900字范文,内容丰富有趣,生活中的好帮手!
900字范文 > html中鼠标经过遮罩消失 CSS遮罩层:hover状态丢失及解决方案

html中鼠标经过遮罩消失 CSS遮罩层:hover状态丢失及解决方案

时间:2023-05-31 15:14:43

相关推荐

html中鼠标经过遮罩消失 CSS遮罩层:hover状态丢失及解决方案

CSS遮罩层,顾名思义就是在div上,再“铺”一层半透明的div。在hover时,亦可进一步改变该遮罩层的色彩和透明度。我们可以通过css定位和背景色实现。

CSS遮罩层实现及hover状态丢失问题

CSS代码:

.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代码:

在Mouse hover时,如果快速点击鼠标,可能会丢失mouse hover的效果。这在windows上的浏览器经常出现,造成'闪烁'。虽然在macbook上出现的时候很少。

解决方案:点击鼠标时,添加isActive 样式,强制显示'hover'里的样式。等mouse out时,去掉isActive class。

普通状态下的效果:

鼠标Hover时的效果图:

问题是,在鼠标hover的时候多次快速点击鼠标,会导致hover状态失效。这个问题在windows的浏览器(包括windows版本的Chrome, FireFox)时常发生,尽管在macOs的各种浏览器挺少发生。

Hover状态丢失的简单解决方案

基本思路是,点击鼠标时给.block添加isActive class,强制它显示Hover里的样式。在鼠标不断点击以致于丢失hover时,也会因为添加了isActive class而照样显示hover里的样式。

/*.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);

Hover状态丢失的通用解决方案

若.block里有多个定位元素,鼠标在子元素内部向上移动时,虽然鼠标可能依旧在.block内部,但是evt.offsetY可能是负数。依照上述简单方案判断结果是,鼠标在.block外部,就不对了。为此我们需要一种通用的方案。

以下图效果举例。我们在.block里添加一个红色⭕️和对勾

摘出HTML代码:可以看到添加了block__circle.

click to view

在鼠标从红色圆圈向上移动到圆圈外部 但仍在.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 状态。具体代码可查看 /JackieGe/a...

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。