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

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

普通状态下的效果:

鼠标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里添加一个红色⭕️和对勾

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

CSS遮罩层:hover状态丢失及解决方案相关推荐

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

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

  2. css遮罩层从下往上_CSS:图片自带3px下边距的bug修复

    有个朋友有这样一个需求,在一张图片上放置一个半透明的遮罩层,当鼠标悬停其上,减少遮罩的透明度,让图片显示更清晰,效果图如下: 简化HTML如下: Mask Text CSS样式文件如下: .item ...

  3. css一元素hover状态控制另一元素显现

    .delIndex { //目标元素默认不显现display: none; } .historyPanel:hover .delIndex { //对目标元素的父标签添加hover状态,控制目标元素显 ...

  4. 利用display属性写的遮罩层

    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/ ...

  5. css鼠标hover悬停图片遮罩层js特效

    下载地址 css实现的鼠标悬停在图片上的遮罩特效,hover图片遮罩层样式.该鼠标hover动画在鼠标悬停到图片上面的时候,遮罩层以两个不规则图形出现,并显示描述文字和链接图标. dd:

  6. css hover遮罩层效果

    运用css方法达到鼠标移入文字消失,图片占满,遮罩层展示. 用到了transition (过渡). position(定位).opacity(透明度)等 效果图 html <div class= ...

  7. CSS实现鼠标悬浮时背景图片拉近且增加遮罩层效果

    效果预览 点击查看效果   我们在浏览网站时会发现有一些图片在鼠标悬浮在上时会有放大拉近的效果.   想要实现这个效果有两种方法,第一种方法是控制背景图片,第二种方法是控制插入的图片,我们这里介绍第一 ...

  8. css3遮罩层_CSS3鼠标hover图片超酷遮罩层动画特效

    这是一款CSS3鼠标hover图片超酷遮罩层动画特效.该特效中,当鼠标悬停在图片上面的时候,左右两个遮罩层会向中间收缩,最后合成一个完整的遮罩层.效果截图如下:  HTML代码 Williamson ...

  9. Vue + Bootstrap|Element UI——模态框被遮罩层遮盖问题解决方案

    问题描述 问题分析 1)若dialog弹出框,它的遮罩层就会被插入到body标签下(即与组件所在的最外层div同一层级) Element UI中设置了modal-append-to-body='tru ...

最新文章

  1. C#中将结构类型数据存储到二进制文件中方法
  2. Pycharm中tensorflow框架下tqdm的安装
  3. Java方法的反射(对反射的进一步认识)
  4. 拼多多:扶贫项目正连续遭受网络舆情涉黑团伙攻击
  5. php+mysql+like+通配符+变量
  6. hp eva 4400存储配置手记
  7. 圣殿骑士的一篇关于WPF的培训好文,WPF应用与团队开发(转)
  8. 区块链 Solidity中uint转string 数字转字符串
  9. java设计模式-State模式
  10. 服务器上发布的网站应用80端口时内网可以访问,外网不能访问
  11. 一个小白程序员的目标
  12. JAVA实现Tom猫
  13. 乡村的野蛮生长|独秀日记
  14. smart bi 学习
  15. linux at91看门狗驱动设置
  16. 【视频】老外拍的阿里巴巴纪录片,讲述淘宝怎么打败eBay
  17. Activiti Designer申请请假流程
  18. 怎么用计算机制作海报,电脑word怎么做海报_用word做的海报步骤
  19. 常用的PostMethod及getMethod请求
  20. 《勋伯格和声学》读书笔记(一):大调三和弦的排列与结构

热门文章

  1. Android Location API跟踪您当前的位置
  2. python编程示例_Python套接字编程–服务器,客户端示例
  3. 什么是Reactive Streams in Java 译
  4. linux中SUID,SGID和SBIT的奇妙用途
  5. TF目标检测API-Error: Argument must be a dense tensor: range(0, 3) - got shape [3], but wanted []....
  6. 002,jvm启动流程
  7. linux不能上网问题
  8. java基础----集合操作---实例----List集合的初始化
  9. highcharts插件使用总结和开发中遇到的问题及解决办法
  10. [转]php返回json数据中文显示的问题