- 进入暗色模式时,给当前页面的
body
添加nightmode__body
的class
,如果有需要自定义的页面样式,可以自己在页面中写样式,如页面中有一个节点div.title
在暗色模式下呈现#ddd
的颜色, 则在样式表中添加.nightmode__body div.title {color: #dddd}
- 生成暗色模式下背景颜色, 图片, 移除背景图片, 反色的样式
- 像
dom
树中插入style
标签
let insertStyle = function(styleStr) {
if(!document.querySelector('.dark')) {
let node = document.createElement('style')
node.type = 'text/css'
node.rel = 'stylesheet'
node.className = 'dark'
node.appendChild(document.createTextNode(styleStr))
(function() {
let container = document.documentElement || document.body || document.head
if (container) {
container.appendChild(node)
} else {
setTimeout(arguments.callee, 0)
}
})()
}
}
- 监听
dom
的变化,对根节点元素进行深度优先遍历,如果有dom
的变化就调用一次样式,防止有内容是接口请求的延时返回
/**
* 向dom树中插入style标签
*/
let insertStyle = function(styleStr) {
if(!document.querySelector('.dark')) {
let node = document.createElement('style')
node.type = 'text/css'
node.rel = 'stylesheet'
node.className = 'dark'
node.appendChild(document.createTextNode(styleStr))
(function() {
let container = document.documentElement || document.body || document.head
if (container) {
container.appendChild(node)
} else {
setTimeout(arguments.callee, 0)
}
})()
}
}
//监听dom变化
function observedom() {
let target = document.querySelector('body')
let observer =
MutationObserver &&
new MutationObserver(function(mutations) {
if(mutations && mutations.length) {
applyStyleSingle(document.body)
}
})
observer.observe(target, { childList: true, subtree: true})
}
//深度遍历根元素里面的所有元素, 把需要的样式加上
function applyStyleSingle(rootDom) {
if (!rootDom) return
let nodeStack = [rootDom]
while( nodeStack.length > 0) {
let n = nodeStack.pop()
if(!n.classList.contains('nightmode__ignore')) {
//改变元素背景色为黑色
//去掉元素背景图
//对元素进行反色
//处理单个元素的渐变背景色
//改变元素背景色
}
let children = n.childList
if (!n.classList.contains('nightmode__ignore--children')) {
for (let i = children.length - 1; i >= 0; i--) {
nodeStack.push(children[i])
}
}
}
}
/**
* 给iframe发消息通知应用暗色模式
*/
function applyIframeNight() {
let iframes = document.querySelectorAll('iframe')
iframes.forEach( item => { //contentWindow 属性返回当前 HTMLFrameElement的 window 对象,可以使用这个window对象去访问这个iframe的文档和它内部的DOM
item.contentWindow.postMessage(JSON.stringify({
type: '事件名',
action: 'applyNightMode'
}))
})
}
/**
* dom ready之后应用一次样式
*/
let ready = function(callback) {
if( /complete|loaded|interactive/.test(document.readyState)) {
callback()
} else {
document.addEventListener('DOMContentLoaded', function(){
callback()
// 应用一次深度优先遍历, 将class添加
}, false)
}
}
/**
* 应用自定义事件触发,通知页面其他js库暗色和亮色模式切换 1 暗色 0 亮色
*/
function customerEvent(status) {
let nightmodeEvent = new CustomEvent('switchNightMode', {
detail: { status: status }
})
if (window.dispatchEvent) {
window.dispatchEvent(nightmodeEvent)
}
}
/**
* 去除暗色模式
*/
function removeNightMode() {
if (document.body.classList.contains('nightmode__body')) {
document.body.classList.remove('nightmode__body')
}
let styleEle = [].slice.call(document.querySelectorAll('.dark'))
if (styleEle && styleEle.length) {
styleEle.forEach( item => {
item.parentNode.removeChild(item)
})
}
CustomEvent(0)
let iframes = document.querySelectorAll('iframe')
iframes.forEach( item => {
item.contentWindow.postMessage(JSON.stringify({
type: 'dark',
action: 'removeNightMode'
}))
})
}
/**
* 初始化事件
*/
function init() {
window.addEventListener('message', function(event) {
let data = JSON.parse(event.data)
if (data.action === 'applyNightMode') {
applyNightMode({ //应用暗色模式
isIframe: true
})
} else if (data.action === 'removeNightMode') {//移除暗色模式
removeNightMode()
}
})
window.applyNightMode = applyNightMode
window.removeNightMode = removeNightMode
}
网友评论