媒介
前一阵子忙着找工作,口试过程当中,遇到一个觉得比较有意思的题目,只管多的枚举出新手指导动画的完成体式格局, 昨天轻微总结了一下, 完成了4种.源码在末了,假如想直接看效果的,能够拉到末了去看.
这里假定一切的弹出层都是基于页面上原有的元素
完成一 复制目的内容
具体步骤:
- 用
getBoundingClientRect
猎取目的内容的显现位置 - 复制一个目的内容,而且设置相对定位, 定位的数据在上一步有猎取到,还要把 z-index 轻微设置高一点
- 在复制内容下面,加一层半通明的遮罩层.
中心代码:
let target = document.querySelector('.mid-center')
let pos = target.getBoundingClientRect()
let clone = target.cloneNode(true)
clone.style.position = 'fixed'
clone.style.left = pos.left
clone.style.top = pos.top
clone.style.width = pos.width
clone.style.height = pos.height
clone.style.zIndex = 100
document.body.appendChild(clone)
优瑕玷
比较寻常的完成体式格局,普普通通的,没啥特征.
完成二 应用box-shadow
具体步骤:
- 设置目的对象的 box-shadow 为一个比较大的,半通明的值
- 设置目的对象的 position 为 relative
中心代码:
let target = document.querySelector('.mid-center')
target.style.boxShadow = '0 0 0 4000px rgba(0, 0, 0, 0.85)'
target.style.position = 'relative'
这里设置 position:relative 是为了让 box-shadow 暗影不被父容器所盖住. 假如没有设置, box-shadow 会显现不全
优瑕玷
长处: 完成体式格局简朴易懂
瑕玷: box-shadow 是个比较耗机能的属性, 而且依托 position:relative 不知道会不会涌现没法掩盖的题目
完成三 应用 html2canvas 将目的内容绘制的一个底色半通明的 canvas 内里
具体步骤:
- 用
getBoundingClientRect
猎取目的内容的显现位置 - 用
html2canvas
将目的内容绘制到上一步猎取的指定位置和大小
中心代码:
let target = document.querySelector('.mid-center')
let pos = target.getBoundingClientRect()
let w = ~~pos.width
let h = ~~pos.height
let canvas = document.querySelector('#canvas')
canvas.width = document.documentElement.clientWidth
canvas.height = document.documentElement.clientHeight
let ctx = canvas.getContext("2d");
canvas.style.display = 'block'
html2canvas(target, {
width: w,
height: h,
}).then( (cvs) => {
ctx.drawImage(cvs, pos.left, pos.top)
})
须要注重的是 这里 canvas.width 和 canvas.height 要手动设置,不然默许是 300 * 150,如许假如在款式里设置宽高的话,会致使画布被拉伸.
优瑕玷
长处: 机能应当相对会比较好一点(假如html2canvas机能内有太差的话), 用 canvas 完成, 也比较不容易遇到种种层级遮挡或显现不全的题目.
瑕玷: 完成体式格局相对烦琐一点,而且须要借助外部东西
完成四 把其他元素都设成半通明的.然后给 body 加一个黑色的底色
具体步骤:
- 给全部文档最外层的元素,设置一个黑色的底色
- 遍历全部文档,把非目的内容,和非目的内容的父容器,都设成半通明的
中心代码:
function showGuidance() {
let main = document.querySelector('.main')
main.className += ' darkBackGround'
setOpticity(main)
}
function setOpticity (element) {
let doms = Array.from(element.children) || []
let hasMatched = false
for (let el of doms) {
if (!el.className.match(/mid-center/i) && el.children.length) {
hasMatched = setOpticity(el)
if (!hasMatched) el.className += ' halfTransparent'
} else if(el.className.match(/mid-center/i)) {
hasMatched = true
} else {
el.className += ' halfTransparent'
}
}
return hasMatched
}
假如不小心把目的元素的父元素也设置成半通明的,那末就算目的元素没有设置半通明,也会变通明,由于父元素内里的一切内容,都邑通明
优瑕玷
长处: 觉得没有长处哈
瑕玷: 批量操纵 dom, dom 元素多的情况下,机能极差
末了
以上一切完成体式格局,均按最简朴的完成体式格局来,未斟酌一些特殊情况(如:resize, 有动画等)
附上 源码