当前位置: 首页 > Web前端 > vue.js

实现对焦效果

时间:2023-03-31 19:00:37 vue.js

这是之前有朋友问我的一个功能:他觉得有时候看网页注意力会被转移,希望能有个mask帮助他反手对焦,所以我把带box-shadow的函数写出来了。(function(){letlastEl=null;letstyleEl=null;document.body.addEventListener('mouseover',(e)=>{e.stopPropagation();if(!styleEl){styleEl=document.createElement('样式');document.body.appendChild(styleEl);styleEl.innerHTML=`.lilnong-focus{box-shadow:000px9999pxrgba(0,0,0,.8);z-index:99999;位置:relative;}`}constel=e.target;lastEl?.classList?.remove('lilnong-focus');lastEl=el;el.classList.add('lilnong-focus');})})()因为z-index不能超过non-staticlevel导致的bug,我在测试中发现了一些比较暗的效果,所以需要做一点小改动。直接给父ZIndex所有提升。(function(){letlastEl=null;letstyleEl=null;letZIndex=1;document.body.addEventListener('mouseover',(e)=>{e.stopPropagation();if(!styleEl){styleEl=document.createElement('style');document.body.appendChild(styleEl);styleEl.innerHTML=`.lilnong-focus{box-shadow:000px9999pxrgba(0,0,0,.8);z-index:99999;position:relative;}`}constel=e.target;lastEl?.classList?.remove('lilnong-focus');lastEl=el;el.classList.add('lilnong-focus');letparent=el;ZIndex++;while(parent){console.log(parent?.style)if(parent.style)parent.style.zIndex=10000+ZIndex;parent=parent.parentNode;}})})()因为溢出,样式不能超出框。好吧,让我们恢复溢出(function(){letlastEl=null;letstyleEl=null;letZIndex=1;document.body.addEventListener('mouseover',(e)=>{e.stopPropagation();if(!styleEl){styleEl=document.createElement('style');document.body.appendChild(styleEl);styleEl.innerHTML=`.lilnong-focus{box-shadow:000px9999pxrgba(0,0,0,.8);z-index:99999;position:relative;}.lilnong`}constel=e.target;lastEl?.classList?.remove('lilnong-focus');lastEl=el;el.classList.add('lilnong-focus');letparent=el;ZIndex++;while(parent){//console.log(parent?.style)if(parent.style){//parent.style.zIndex=10000+ZIndex;//溢出:可见!重要;//parent.style.overflow='visible!important'parent.setAttribute('style',`${parent.getAttribute('style')};z-index:${10000+ZIndex};overflow:visible!important;`)}parent=parent.parentNode;}})})()最好的实现?经过我们的一般操作,终于可以实现功能了,但是这样的功能真的是我们想要的吗?我们只想实现焦点功能,不希望页面布局被破坏。那我们该怎么办呢?从上面的例子可以看出,box-shadow是最好的实现方式。它可以给我们一个视口来覆盖视口之外的所有内容,所以我们只需要控制视口的大小即可。这样我们也可以在视口上做一些特殊的样式。当然,你会说,如果在上面放一层,元素就不能被选中了。这里我们可以使用pointer-events:none;以防止元素接收事件。(这个经常出现在头像widget中,一般来说点击头像会弹出数据卡片,我们只需要在widget中阻止接收到该事件即可。)(function(){letmaskEl=document.querySelector('.lilnong-mask')||document.createElement('div');maskEl.className="lilnong-mask"document.body.appendChild(maskEl);让styleEl=document.createElement('style');document.body.appendChild(styleEl);styleEl.innerHTML=`.lilnong-mask{box-shadow:000px9999pxrgba(0,0,0,.8);z-index:99999;position:fixed;top:0;left:0;width:40px;height:40px;pointer-events:none;}`document.body.addEventListener('mousemove',(e)=>{e.stopPropagation();constel=e.target;const{x,y,width,height,top,left}=el.getBoundingClientRect();maskEl.style.left=left+'px'maskEl.style.top=top+'px'maskEl.style.width=width+'px'maskEl.style.height=height+'px'})})()甚至说我们可以修改聚焦视口的样式(function(){letmaskEl=document.querySelector('.lilnong-mask')||document.createElement('div');maskEl.className="lilnong-mask"document.body.appendChild(maskEl);让styleEl=document.createElement('style');document.body.appendChild(styleEl);styleEl.innerHTML=`.lilnong-mask{box-shadow:000px9999pxrgba(0,0,0,.8);z-index:99999;position:fixed;top:0;left:0;宽度:40像素;高度:40像素;指针事件:无;填充:10像素;框大小:内容框;转换:翻译(-10像素,-10像素);之前{c内容:'';位置:绝对;上:-6px;右:-6px;下:-6px;左:-6px;边框:1px虚线#eee;border-radius:10px}`document.body.addEventListener('mousemove',(e)=>{e.stopPropagation();constel=e.target;const{x,y,width,height,top,left}=el.getBoundingClientRect();maskEl.style.left=left+'px'maskEl.style.top=top+'px'maskEl.style.width=width+'px'maskEl.style.height=height+'px'})})()因为是left,top,width,height变化,所以我们也可以transition:.2sall;这样动画就会有过渡效果