欢迎测评:前端工程师
在页面上加些代码,让页面白屏幕,有哪些方式呢?如何防御呢?
本文介绍了 8 种让页面白屏的方法。在防御方法中,包含了一些你可能不知道的冷知识,如:判断元素是否被遮挡。
方法1: 隐藏根节点
html { display:none !important; }
选择器用 body
也能达到一样的效果。
当页面是深色模式时,添加上面的代码页面后,页面是黑色的。需要取消深色模式:删除下面的代码:
<meta name="color-scheme" content="dark" >
方法2: 让根节点不可见
设置可见性的属性:
html { visibility: hidden !important; }
或者,设置透明度为完全透明:
html { opacity: 0 !important; }
方法3: 大小设为0,超出隐藏
body { width: 0 !important; height: 0 !important; overflow: hidden !important; }
选择器用 html
没有效果。
方法4: 偏移出屏幕
用 fixed
定位:
html { position: fixed; left: -99999px; }
或者,用 transform
:
html { transform: translateX(-99999px); }
方法5: 遮挡页面
用全屏的白色元素遮挡页面。
html::before { content: ''; position: fixed; z-index: 999999; left: 0; top: 0; width: 100vw; height: 100vh; background: #fff; }
方法6: 缩小
html { transform: scale(0.0000000000001); }
方法7: 清空页面内容
document.documentElement.innerHTML = ''
方法8: 页面跳转到一个空白页面
location.href = '空白页面URL'
这个方法有点皮~
防御
检测白屏的样式
通过轮训检查根节点上,是否有导致白屏的样式。如果有,则刷新页面。例如:
setInterval(() => { if(hasWhitePageStyle()) { location.reload() } }, 100)
通过这种方式,可以防御方法 1 ~ 6。我们来看具体的检查方法。
根节点是否隐藏检查
const root = document.documentElement const body = document.body if( getComputedStyle(root, null).display === 'none' || getComputedStyle(body, null).display === 'none' ) { return true // 根节点被隐藏 }
根节点是否可见检查
if( getComputedStyle(root, null).visibility === 'hidden' || getComputedStyle(body, null).visibility === 'hidden' ) { return true // 不可见 } if( getComputedStyle(root, null).opacity < 0.1 || getComputedStyle(body, null).opacity < 0.1 || ) { return true // 不可见 }
大小为 0 检查
const {width, height } = body.getBoundingClientRect() if(width === 0 || height === 0) { return true // 大小为 0 }
偏移出屏幕检查
const {left, right, top, bottom } = body.getBoundingClientRect() if( left > window.innerWidth || right < 0 || top > window.innerHeight || bottom < 0 ) { return true // 偏移出屏幕 }
遮挡检查
document.elementFromPoint(x, y)[1] 返回某个坐标点下最上层的元素。如果元素没有被遮挡,则在该 API 中传入元素的上下左右四个坐标点,返回的均为该元素。
假设页面上有个 id 为 tar 的元素,如果该元素未被遮挡,则认为页面被遮挡。
const tarElem = document.getElementById('tar') const {left, right, top, bottom} = tarElem.getBoundingClientRect() if( document.elementFromPoint(left, top) === tar && document.elementFromPoint(left, bottom) === tar && document.elementFromPoint(right, top) === tar && document.elementFromPoint(right, bottom) === tar && ) { return true// 未被遮挡 }
防止修改 DOM
MutationObserver API[2] 可以监控 DOM 的变动。用该 API 可以防御页面内容被清空。代码如下:
// 监控 属性,子节点和后代节点的变动 const config = { attributes: true, childList: true, subtree: true }; const observer = new MutationObserver((mutationsList) => { for(let mutation of mutationsList) {// 页面DOM变动 location.reload() } }) window.addEventListener('DOMContentLoaded', () => { observer.observe(document.documentElement, config); })
防止页面跳转
目前没有找到防御的方法。尝试过以下方法。
重置 window.location
执行:
window = {}
window.location 仍然在。
执行:
const location = ''
和
function location () {}
都会报错。
执行:
window.location = {}
页面直接跳转了。
将 window.location 设置为只读
做了如下尝试,均不行:
Object.freeze(window) // 报错 Object.freeze(window.location) // 无效 // 报错 Object.defineProperty(window, "location", {"writable": false}) // 报错 Object.defineProperty(location, "false", {"writable": false})