带有渐变效果的Javascript/CSS选项卡



我正在努力实现标签,当我们从一个标签更改为另一个标签时,它们会在两个标签之间褪色。我使用的这段代码很有效,但有一个问题。当我从下一个选项卡转到上一个选项卡时,出现了一个小故障,我可以在消失前看到最后一个选项卡的更改状态。

HTML:

function openSvc(evt, svc) {
var i, x, tablinks, opacitys;
x = document.getElementsByClassName("svc");
for (i = 0; i < x.length; i++) {
x[i].classList.remove('display-yes');
}
tablinks = document.getElementsByClassName("tablink");
for (i = 0; i < x.length; i++) {
tablinks[i].className = tablinks[i].className.replace(" active", "");
}
document.getElementById(svc).classList.add('display-yes');
evt.currentTarget.className += " active";
}
.svc {
opacity: 0;
position: absolute;
transition: .3s;
}
.display-yes {
opacity: 1;
position: relative;
}
<div class="tab">
<button class="tablink" onclick="openSvc(event,'dev')"> Desenvolvimento de software </button>
<button class="tablink active" onclick="openSvc(event,'it')"> Infraestruturas IT </button>
<button class="tablink" onclick="openSvc(event,'design')"> UX / UI Design </button>
<button class="tablink" onclick="openSvc(event,'consult')"> Consultoria </button>
</div>
<div id="dev" class="svc display-yes">
<p>lorem ipsum1
</div>
<div id="it" class="svc">
<p>lorem ipsum2
</div>
<div id="design" class="svc">
<p>lorem ipsum3
</div>
<div id="consult" class="svc">
<p>lorem ipsum4
</div>

示例:https://jsfiddle.net/4fz01c2o/

提前感谢您的帮助!

我不确定你在这里到底想要什么效果。G-Cyrillu的解决方案有效,但似乎你失去了一点褪色效果。

因此,为了保持这种效果,您需要删除应用于.display-yesposition: relative规则。

它扰乱了div的位置。为此,您需要添加一个position: relative;容器来保持.svcdiv的位置。

function openSvc(evt, svc) {
var i, x, tablinks, opacitys;
x = document.getElementsByClassName("svc");
for (i = 0; i < x.length; i++) {
x[i].classList.remove('display-yes');
}
tablinks = document.getElementsByClassName("tablink");
for (i = 0; i < x.length; i++) {
tablinks[i].className = tablinks[i].className.replace(" active", "");
}
document.getElementById(svc).classList.add('display-yes');
evt.currentTarget.className += " active";
}
.svc-container {
position: relative;
width: 500px;
height: 200px;
margin-top: 1rem;
background-color: lightblue;
}
.svc {
opacity: 0;
position: absolute;
top: 0;
left: 0;
transition: .3s;
}
.svc p {
margin: 0; /* To be consistent with the next block*/
}
.display-yes {
opacity: 1;
}
.tablink {
background-color: blue;
}
.active {
background-color: red;
}
<div class="tab">
<button class="tablink active" onclick="openSvc(event,'dev')"> Desenvolvimento de software </button>
<button class="tablink" onclick="openSvc(event,'it')"> Infraestruturas IT </button>
<button class="tablink" onclick="openSvc(event,'design')"> UX / UI Design </button>
<button class="tablink" onclick="openSvc(event,'consult')"> Consultoria </button>
</div>
<div class="svc-container">
<div id="dev" class="svc display-yes">
<p>lorem ipsum1</p>
</div>
<div id="it" class="svc">
<p>lorem ipsum2</p>
</div>
<div id="design" class="svc">
<p>lorem ipsum3</p>
</div>
<div id="consult" class="svc">
<p>lorem ipsum4</p>
</div>
</div>
<div style="width:500px; height:200px; background-color:#c2c2c2;">
<p>
lorem ipsum lorem ipsum
</p>
</div>

您有不同的问题:对隐藏元素使用绝对位置总是会导致显示问题我建议使用一个全局大小(和颜色(的父div,里面的每个选项卡都在同一个绝对位置上。

你的问题不清楚,我想你会在开始下一个选项卡的淡入之前等待淡出结束
因此您需要使用transitionend事件来检测淡出完成

我还建议在数据信息属性的帮助下,对所有选项卡按钮使用事件委派,这使html代码更可靠,减少JS代码

所以这个代码:(转换=一秒钟用于测试(

const tabButtons = document.querySelector('div.tab')
,   buttonTabs = document.querySelectorAll('div.tab > button.tablink')
,   tabData    = [...document.querySelectorAll('div.svc')].reduce((res,eTab)=>
{
res.push( { id:eTab.id, disp:eTab.classList.contains('display-yes'), elm: eTab} )
return res
},[])
tabButtons.onclick =e=>
{
if (!e.target.matches('button.tablink'))   return // ignore others clicks outsides 
let currentTab = tabData.find(tb=>tb.disp)
, newTab     = tabData.find(tb=>tb.id===e.target.dataset.tabId)   
if (newTab.id != currentTab.id )
{
currentTab.elm.addEventListener('transitionend',setNewTab)
currentTab.elm.classList.remove('display-yes')
currentTab.disp = false
buttonTabs.forEach(bt=>bt.classList.remove('active'))
e.target.classList.add('active')
}
function setNewTab()
{
currentTab.elm.removeEventListener('transitionend',setNewTab)
newTab.elm.classList.add('display-yes')
newTab.disp = true
}
}
#all-svc {
position:relative;
width:500px; 
height:200px;
background-color:#00488ab5;
margin-top: 1em;
}
.svc{
opacity:0;
transition: opacity 1s;
position:absolute;
top: 0;
left:0;
padding: 0 0.5em;
}
.display-yes{
opacity:1;
}
.tablink{
background-color:#0000ffb5;
}
.active{
background-color:#ff0000b5;  
}
<div class="tab">
<button class="tablink active" data-tab-id="dev"> Desenvolvimento de software </button> 
<button class="tablink" data-tab-id="it"> Infraestruturas IT </button> 
<button class="tablink" data-tab-id="design"> UX / UI Design </button> 
<button class="tablink" data-tab-id="consult"> Consultoria </button> 
</div>
<div id="all-svc">
<div id="dev" class="svc display-yes">
<p>lorem ipsum 1</p>
</div>
<div id="it" class="svc">
<p>lorem ipsum 2 lorem ipsum 2</p>
</div>
<div id="design" class="svc">
<p>lorem ipsum 3 ipsum 3 lorem 3</p>
</div>
<div id="consult" class="svc">
<p>lorem ipsum 4 lorem ipsum ipsum ipsum 4</p>
</div>
</div>
<div style="width:500px; height:200px; background-color:#c2c2c2;">
<p> 
lorem ipsum lorem ipsum
</p>
</div>

最新更新