昨天敌人说要实现一个成果,获取鼠标所在区域的容器,区域外都遮罩半透明,起名为专一模式。咱们明天来实现一下。

需要剖析

  1. 获取鼠标地位,鼠标属于的容器。mouseovermouseoutmousedownmouseupmouseentermouseleavemousemove 这么多事件太容易了。

    1. 然而因为 DOM 构造太多了,其实要的元素有可能是父级先人级,这里须要实现一个相似于 jquery 的 parants。
  2. 区域外遮罩半透明。这个感觉相似于老手疏导的那种成果。

    1. 计划:克隆节点,fixed定位
    2. 计划:box-shadow
    3. 计划:outline
    4. 计划: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