共计 2223 个字符,预计需要花费 6 分钟才能阅读完成。
昨天敌人说要实现一个成果,获取鼠标所在区域的容器,区域外都遮罩半透明 ,起名为 专一模式。咱们明天来实现一下。
需要剖析
-
获取鼠标地位,鼠标属于的容器。
mouseover
,mouseout
,mousedown
,mouseup
,mouseenter
,mouseleave
,mousemove
这么多事件太容易了。- 然而因为 DOM 构造太多了,其实要的元素有可能是 父级 、 先人级,这里须要实现一个相似于 jquery 的 parants。
-
区域外遮罩半透明。这个感觉相似于老手疏导的那种成果。
- 计划:克隆节点,fixed 定位
- 计划:
box-shadow
- 计划:
outline
- 计划:
border
,这个就不举荐应用了,下面两个不会影响地位。
性能实现
获取鼠标地位的 DOM 元素
几乎不要太简略。通过事件对象间接拿 e.target
window.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
正文完
发表至: javascript
2020-10-09