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

JS效果《获取鼠标所在区域的容器,区域外都遮罩半透明》

时间:2023-04-02 20:48:36 HTML

朋友昨天说要实现一个效果,获取鼠标所在区域的容器,遮住区域外的半透明,称之为焦点模式。让我们今天做。需求分析得到鼠标的位置和鼠标所属的容器。mouseover,mouseout,mousedown,mouseup,mouseenter,mouseleave,mousemove这么多事件太容易了。但是因为DOM结构太多,你想要的元素实际上可能是父类和祖先类。这里需要实现一个类似jquery的parants。elementsFromPoint获取坐标下的DOM元素e.path获取路径区域外的半透明遮罩。这种感觉和新手引导的效果差不多。解决方案:克隆节点,固定定位解决方案:box-shadow解决方案:outline解决方案:border,这个不推荐,上面两种不会影响位置。实现获取鼠标位置DOM元素的功能也不是太简单。直接通过event对象取e.targetwindow.addEventListener('mousemove',function(e){console.log(e.target)})递归查找符合条件的DOM元素parentNode得到父节点,因为只有一个父节点,比找子节点少遍历一次。实现了一个简单的选择器,它只处理一个类、id和标签。如果想深入,可以看jquery的实现。函数findParentAttribute(node,key=''){key=key.trim();如果(!节点)返回空;if(!key)返回节点;if(node==document)returnnull;switch(key.slice(0,1)){case'.':if(node.classList.contains(key.slice(1))){returnnode}case'#':if(node.id==key.slice(1)){returnnode}默认:if(node.tagName.toLowerCase()==key){returnnode}}if(node.parentNode){returnfindParentAttribute(node.parentNode,key)}returnnull;}通过elementsFromPoint获取鼠标位置DOM节点评论区小伙伴的Reminder,可以使用document.elementsFromPoint(e.clientX,e.clientY)全部获取,不需要递归。通过e.path获取鼠标位置DOM节点。突然想到可以不用递归直接使用e.path获取触发路径。遮罩半透明实现轮廓实现box-shadowJS克隆DOM由于原始DOM不能直接修改为fixed,会引起布局变化,所以我们直接clone一个,然后定位克隆的fixed。类似于模拟拖动效果的代码。懒得写这个了,大家有什么意见可以在评论区留言吗?完整代码shadowClass=['.stream-list__item','div','#app'];shadowEl=null;shadowStyleTimeout=0;shadowStyle=`.lilnong-shadow{outline:9999pxsolidrgba(0,0,0,.5);z-index:9999999999;transform:translate3d(0px,0px,1px);position:relative;}`;if(!window.styleEl){varstyleEl=document.createElement('style');styleEl.id=styleEl;}styleEl.innerHTML=shadowStyle;if(!styleEl.parentNode){document.head.appendChild(styleEl)}window.addEventListener('mouseover',function(e){varel=e.target;varnewEl=null;for(leti=0,l=shadowClass.length;i{if(newEl){newEl.classList.add('lilnong-shadow')shadowEl=newEl;}},50)})functionfindParentAttribute(节点,键=''){//console.log(node,key)key=key.trim()||'';如果(!节点)返回空;if(!key)返回节点;if(node==document)returnnull;switch(key.slice(0,1)){case'.':if(node.classList.contains(key.slice(1))){returnnode}case'#':if(node.id==key.slice(1)){returnnode}default:if(node.tagName.toLowerCase()==key){returnnode}}if(node.parentNode){returnfindParentAttribute(node.parentNode,key)}returnnull;}基于elementsFromPoint获取dom评论区,有小伙伴提醒还有elementsFromPoint和elementFromPoint实现DOM元素shadowClass=['.stream-list__item','div','#app'];shadowEl=null;shadowStyleTimeout=0;shadowStyle=`.lilnong-shadow{outline:9999pxsolidrgba(0,0,0,.5);z-index:9999999999;transform:translate3d(0px,0px,1px);position:相对的;}`;if(!window.styleEl){varstyleEl=document.createElement('style');styleEl.id=styleEl;}styleEl.innerHTML=shadowStyle;if(!styleEl.parentNode){document.head.appendChild(styleEl)}window.addEventListener('mouseover',function(e){if(shadowEl)shadowEl.classList.remove('lilnong-shadow')varels=document.elementsFromPoint(e.clientX,e.clientY);shadowClass.every(selectorKey=>{varel=els.find(el=>{keySlice=[selectorKey.slice(0,1),selectorKey.slice(1)]switch(keySlice[0]){case'.':if(el.classList.contains(keySlice[1])){returnel}case'#':if(el.id==keySlice[1]){returnel}默认值:if(el.tagName.toLowerCase()==selectorKey){returnel}}returnfalse;})if(el){el.classList.add('lilnong-shadow')shadowEl=el;returnfalse}returntrue})})微信公众号:前端linong