CSS遮罩层,顾名思义就是在div上,再“铺”一层半透明的div。在hover时,亦可进一步改变该遮罩层的色彩和透明度。咱们能够经过css定位和背景色实现。css
CSS代码:html
.block { position: relative; top: 100px; left: 100px; display: inline-block; width: 300px; border-radius: 4px; border:1px solid ; } .block__overlay { position: absolute; top:0; left:0; width: 100%; height: 100%; background-color: rgba(0, 0, 0, .3); } .block:hover .block__overlay { background-color: rgba(100, 200, 0, .5); }
Html代码:node
<div class="block"> <p> 在Mouse hover时,若是快速点击鼠标,可能会丢失mouse hover的效果。这在windows上的浏览器常常出现,形成'闪烁'。虽然在macbook上出现的时候不多。 </p> <p> 解决方案:点击鼠标时,添加isActive 样式,强制显示'hover'里的样式。等mouse out时,去掉isActive class。 </p> <img src="test.png" width="300px"> <!-- 遮罩住了文本段落和图片 --> <div class="block__overlay"> </div> </div>
普通状态下的效果:git
鼠标Hover时的效果图:github
问题是,在鼠标hover的时候屡次快速点击鼠标,会致使hover状态失效。这个问题在windows的浏览器(包括windows版本的Chrome, FireFox)时常发生,尽管在macOs的各类浏览器挺少发生。web
基本思路是,点击鼠标时给.block添加isActive class,强制它显示Hover里的样式。在鼠标不断点击以至于丢失hover时,也会由于添加了isActive class而照样显示hover里的样式。windows
/*.isActive 拥有:hover相同的样式*/ .block:hover .block__overlay, .block.isActive .block__overlay { background-color: rgba(100, 200, 0, .5); }
JS文件:浏览器
var block = document.getElementsByClassName("block")[0]; block.addEventListener('mouseout', function (evt) { // mouse hover时,不断地快速点击鼠标,可能会触发mouseout事件,尽管并非真正将鼠标move out了。 // 这里经过offsetX,offsetY来判断鼠标的位置,是否真正还在.block内 if (evt.offsetX <= 0 || evt.offsetY <= 0 || evt.offsetX >= block.offsetWidth || evt.offsetY >= block.offsetHeight) { console.log('Really moved out'); if (this.classList.contains('isActive')) { this.classList.remove('isActive'); } } }, false); block.addEventListener('click', function (evt) { if (!this.classList.contains('isActive')) { this.classList.add('isActive'); } }, false);
若.block里有多个定位元素,鼠标在子元素内部向上移动时,虽然鼠标可能依旧在.block内部,可是evt.offsetY多是负数。依照上述简单方案判断结果是,鼠标在.block外部,就不对了。为此咱们须要一种通用的方案。ide
如下图效果举例。咱们在.block里添加一个红色⭕️和对勾函数
CSS代码较多,请参考:https://github.com/JackieGe/a...
摘出HTML代码:能够看到添加了block__circle.
<div class="block"> <img src="tianyuan1.jpg" style="width: 300px;"> <div class="block__overlay"> </div> <div class="block__circle"> <input id="chk1" type="checkbox"> <label for="chk1"></label> </div> <button class="block__viewer"> click to view </button> </div>
在鼠标从红色圆圈向上移动到圆圈外部 但仍在.block内时, offsetY是小于0的。 若是依旧应用简单方案里的js,就会错误地得出鼠标在.block外的结论。
为此咱们使用toElement属性,它表示mouse移动到哪一个元素。若是该元素是.block的子孙元素,咱们就认为鼠标还在.block内。FireFox的event没有toElement属性,咱们用getToElement函数解决。
function getToElement(evt) { var node; if (evt.type == 'mouseout') { node = evt.relatedTarget; } else if (evt.type == 'mouseover') { node = evt.target; } if (!node) { return; } while (node.nodeType != 1) { node = node.parentNode; } return node; } var findElement = (function(){ var found = false; function doFindElement(target, scope) { if (!found && scope && scope.childElementCount > 0) { for (var i=0; i< scope.childElementCount; i++) { var child = scope.children[i]; if (target == child) { found = true; return; } else if (child.childElementCount > 0) { doFindElement(target, child, found) } } } } return function (target, scope) { found = false; doFindElement(target, scope); return found; }; })(); var block = document.getElementsByClassName("block")[0]; block.addEventListener('mouseout', function (evt) { var toElement = evt.toElement || getToElement(evt) || evt.srcElement; if (toElement == this || findElement(toElement, this)) { console.log('Does NOT really move out'); } else { console.log('Really moved out'); if (this.classList.contains('isActive')) { this.classList.remove('isActive'); } } /*** * The below code: the old way no long works correctly, because offsetX, offsetY rely on fromElement. * When mouse move up direction out of 'circle', the OffsetY could be negative, but mouse * is still inside the outermost .block. */ /* if (evt.offsetX <= 0 || evt.offsetY <= 0 || evt.offsetX >= block.offsetWidth || evt.offsetY >= block.offsetHeight) { console.log('OLD way: Really moved out'); if (this.classList.contains('isActive')) { this.classList.remove('isActive'); } } else { console.log('OLD way: Doest NOT move out'); }*/ }, false); block.addEventListener('click', function (evt) { if (!this.classList.contains('isActive')) { this.classList.add('isActive'); } }, false);
控制台查看鼠标点击.block div后的class:
鼠标移走以后,.block div的class:
本文介绍了CSS遮罩的简单实现,以及在鼠标点击.block时如何保持遮罩层的hover 状态。具体代码可查看 https://github.com/JackieGe/a...