昨天朋友说要实现一个效果,获取鼠标所在区域的容器,区域外都遮罩半透明,起名为专注模式。我们今天来实现一下。
需求分析获取鼠标位置,鼠标属于的容器。mouseover,mouseout,mousedown,mouseup,mouseenter,mouseleave,mousemove 这么多事件太容易了。但是因为 DOM 结构太多了,其实要的元素有可能是父级、祖先级,这里需要实现一个类似于 jquery 的 parants。
区域外遮罩半透明。这个感觉类似于新手引导的那种效果。方案:克隆节点,fixed定位
方案:box-shadow
方案:outline
方案:border,这个就不推荐使用了,上面两个不会影响位置。
功能实现
获取鼠标位置的DOM元素
简直不要太简单。通过事件对象直接拿 e.targetwindow.addEventListener('mousemove', function(e){
console.log(e.target)
})
向上递归查找符合条件的DOM元素
parentNode 可以获取到父节点,因为只有一个父节点,比找子节点还少了一个遍历。
实现了一个简单的选择器,只处理了单个的 class、id、tag,想深入的可以看 jquery 的实现。function findParentAttribute(node, key = ''){
key = key.trim();
if(!node) return null;
if(!key) return node;
if(node == document) return null;
switch(key.slice(0,1)){
case '.': if(node.classList.contains(key.slice(1))){return node}
case '#': if(node.id == key.slice(1)){return node}
default: if(node.tagName.toLowerCase() == key){return node}
}
if(node.parentNode){
return findParentAttribute(node.parentNode, key)
}
return null;
}
遮罩半透明实现
outline 实现
box-shadow
JS 克隆 DOM
因为原始的 DOM 不能直接修改为 fixed,会造成布局变化,所以我们直接克隆一个,然后将克隆的 fixed 定位。类似于模拟拖拽效果代码。
这个懒得写了,有没有大佬评论区留言呀。
完整代码shadowClass = ['.stream-list__item','div','#app'];
shadowEl = null;
shadowStyleTimeout = 0;
shadowStyle = `.lilnong-shadow{outline: 9999px solid rgba(0,0,0,.5);z-index: 9999999999;transform: translate3d(0px,0px,1px);position: relative;}`;
if(!window.styleEl){
var styleEl = document.createElement('style');
styleEl.id = styleEl;
}
styleEl.innerHTML = shadowStyle;
if(!styleEl.parentNode){
document.head.appendChild(styleEl)
}
window.addEventListener('mouseover', function(e){
var el = e.target;
var newEl = null;
for(let i = 0,l = shadowClass.length; i < l; i++){
newEl = findParentAttribute(el, shadowClass[i]);
if(newEl) break;
}
if(shadowEl) shadowEl.classList.remove('lilnong-shadow')
clearTimeout(shadowStyleTimeout);
shadowStyleTimeout = setTimeout(v=>{
if(newEl){
newEl.classList.add('lilnong-shadow')
shadowEl = newEl;
}
},50)
})
function findParentAttribute(node, key = ''){
//console.log(node, key)
key = key.trim() || '';
if(!node) return null;
if(!key) return node;
if(node == document) return null;
switch(key.slice(0,1)){
case '.': if(node.classList.contains(key.slice(1))){return node}
case '#': if(node.id == key.slice(1)){return node}
default: if(node.tagName.toLowerCase() == key){return node}
}
if(node.parentNode){
return findParentAttribute(node.parentNode, key)
}
return null;
}
微信公众号:前端linong
关于找一找教程网
本站文章仅代表作者观点,不代表本站立场,所有文章非营利性免费分享。
本站提供了软件编程、网站开发技术、服务器运维、人工智能等等IT技术文章,希望广大程序员努力学习,让我们用科技改变世界。
[JS效果之《获取鼠标所在区域的容器,区域外都遮罩半透明》]http://www.zyiz.net/tech/detail-147819.html