美文网首页
暗色模式脚本注入方案

暗色模式脚本注入方案

作者: jluemmmm | 来源:发表于2021-02-18 11:45 被阅读0次
  • 进入暗色模式时,给当前页面的body添加nightmode__bodyclass,如果有需要自定义的页面样式,可以自己在页面中写样式,如页面中有一个节点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])
      }
    }
  }
}
  • ifame发消息通知应用暗色模式
/**
 * 给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之后应用一次样式
/**
 * 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
}

相关文章

  • 暗色模式脚本注入方案

    进入暗色模式时,给当前页面的body添加nightmode__body的class,如果有需要自定义的页面样式,可...

  • 系统测试利器之挡板实战(四)

    responses常用设置 响应这块主要分三部分:代理模式、脚本注入以及利用shell脚本的动态行为。 代理 代理...

  • php审计之命令注入(敏感函数法)

    PHP脚本中,我们可以对输入进行注入攻击。 注入的种类有很多:命令注入Eval注入客户端脚本攻击跨网站脚本攻击SQ...

  • iOS 实现网页爬虫

    实现方案 利用WKWebView打开一个待爬取的网页 在webView渲染完成之后注入一段爬虫脚本 在脚本回调里面...

  • Android Q暗色模式适配踩坑—状态栏

    暗色模式已经不是什么新鲜玩意了,大家最近看到关于暗色模式最多的内容可能就是iOS版本微信未适配暗色模式面临被App...

  • 希望暗色模式早日一统天下

    今天上线发现stackoverflow添加了暗色模式, 好激动呀. 希望所有网站和应用都早日支持暗色模式. 现列举...

  • TestCafe

    简介三大模式基本使用浏览器支持截图&视频脚本注入报表进阶部分 简介 前端集成测试框架 支持Typescript 报...

  • XSS和CSRF

    XSS篇: XSS,(cross site scripting),跨站脚本注入,指攻击者利用一些技巧向页面注入脚本...

  • H5 暗色模式的适配方案

    网页语言:vue代码示例:vue+iOSWKwebview H5的暗色模式都是基于CSS样式的修改来适配web内容...

  • IOS 非越狱代码注入(dylib)

    前言 由于dylib注入方式和framework注入方式很像,所以下面直接演示使用脚本来注入 首先代码注入思路: ...

网友评论

      本文标题:暗色模式脚本注入方案

      本文链接:https://www.haomeiwen.com/subject/qqbgxltx.html