当前位置: 首页 > Web前端 > CSS

CSS遮罩层:hover状态丢失及解决方法

时间:2023-03-30 19:27:41 CSS

CSS遮罩层,顾名思义,就是在div上“铺”一层半透明的div。悬停时,您可以进一步更改遮罩层的颜色和透明度。我们可以通过css定位和背景色来实现。CSS遮罩层实现及悬停状态丢失问题CSS代码:.block{position:relative;顶部:100px;左:100px;显示:内联块;宽度:300px;边界半径:4px;边框:1px实心;}.block__overlay{位置:绝对;顶部:0;左:0;宽度:100%;高度:100%;背景色:rgba(0,0,0,.3);}.block:hover.block__overlay{背景颜色:rgba(100,200,0,.5);}html代码:

鼠标悬停时,如果快速点击鼠标,可能会失去鼠标悬停的效果。Windows上的浏览??器经常发生这种情况,导致“闪烁”。虽然在macbook上很少出现。

解决方法:鼠标点击时,添加isActive样式,强制显示'hover'中的样式。当鼠标离开时,移除isActive类。

中的效果正常状态:鼠标悬停时的效果图:问题是鼠标悬停时快速多次点击鼠标会导致悬停状态失效。这个问题在windows浏览器中经常出现(包括windows版的Chrome,FireFox),虽然在macOs的各种浏览器中很少出现。一个简单的解决Hover状态丢失的基本思路是在鼠标点击时在.block中添加isActive类,强制显示Hover中的样式。当鼠标一直点击导致hover消失时,由于添加了isActive类,hover中的样式依然会显示。/*.isActive与:hover*/具有相同的样式.block:hover.block__overlay,.block.isActive.block__overlay{background-color:rgba(100,200,0,.5);}JS文件:varblock=document.getElementsByClassName("block")[0];block.addEventListener('mouseout',function(evt){//当鼠标悬停时,连续快速点击鼠标可能会触发mouseout事件,虽然它并没有真正将鼠标移出向上。//这里用offsetX和offsetY来判断鼠标的位置是否还在.block内if(evt.offsetX<=0||evt.offsetY<=0||evt.offsetX>=block.offsetWidth||evt.offsetY>=block.offsetHeight){console.log('真的搬出去了');如果(this.classList.contains('isActive')){this.classList.remove('isActive');}}},错误的);block.addEventListener('click',function(evt){if(!this.classList.contains('isActive')){this.classList.add('isActive');}},false);Hoverstatelost一般解决方案如果.block中有多个定位元素,当鼠标在子元素内部向上移动时,虽然鼠标可能还在.block内部,但是evt.offsetY可能为负数。按照上面简单的解决方法,结果是鼠标在.block之外,这是错误的。为此,我们需要一个通用的解决方案。下图显示了一个效果示例。我们在.block中添加一个红色??并勾选CSS代码,请参考:https://github.com/JackieGe/a...提取HTML代码:可以看到block__circle.
点击查看当鼠标从红圈向上移到外面时circle但是还在.block里面的时候,offsetY小于0。如果还是套用简单方案中的js,会错误的断定鼠标在.block外面。为此,我们使用toElement属性,它指示鼠标移动到哪个元素。如果该元素是.block的后代,我们认为鼠标仍在.block内。FireFox的事件没有toElement属性,我们使用getToElement函数来解决。函数getToElement(evt){var节点;如果(evt.type=='mouseout'){node=evt.relatedTarget;}elseif(evt.type=='mouseover'){node=evt.target;}if(!node){返回;}while(node.nodeType!=1){node=node.parentNode;}返回节点;}varfindElement=(function(){varfound=false;functiondoFindElement(target,scope){if(!found&&scope&&scope.childElementCount>0){for(vari=0;i0){doFindElement(target,child,found)}}}}返回函数(目标,范围){found=false;doFindElement(目标,范围);返回找到;};})();varblock=document.getElementsByClassName("block")[0];block.addEventListener('mouseout',function(evt){vartoElement=evt.toElement||getToElement(evt)||evt.srcElement;if(toElement==this||findElement(toElement,this)){console.log('没有真的搬出去');}else{console.log('真的搬出去');if(this.classList.contains('isActive')){this.classList.remove('isActive');}}/****下面的代码:旧方法不能正常工作,因为offsetX,offsetY依赖于fromElement。*当鼠标向上移出'circle'时,OffsetY可能为负,但鼠标*仍在里面最外面的.block.*//*if(evt.offsetX<=0||evt.offsetY<=0||evt.offsetX>=block.offsetWidth||evt.offsetY>=block.offsetHeight){console.log('老办法:真的搬出去了');如果(this.classList.contains('isActive')){this.classList.remove('isActive');}}else{console.log('老方法:不搬出去');}*/},错误的);block.addEventListener('click',function(evt){if(!this.classList.contains('isActive')){this.classList.add('isActive');}},false);consoleviewmouseclick.blockdiv类后:鼠标移开后.blockdiv的类:总结本文介绍CSS遮罩的简单实现,以及鼠标点击时如何保持遮罩层悬停状态在.block。具体代码可以参考https://github.com/JackieGe/a...