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...