粥里有勺糖

vuePress-theme-reco 粥里有勺糖    2018 - 2023
粥里有勺糖 粥里有勺糖

Choose mode

  • dark
  • auto
  • light
关于我
备战春秋
  • 心得总结
  • 校招考点汇总
  • 面经汇总
  • 复习自查
技术笔记
  • 技术教程
  • 模板工程
  • 源码学习
  • 技术概念
  • 个人作品
  • 学习笔记
计算机基础
  • 算法与数据结构
  • 操作系统
  • 计算机网络
  • 设计模式
  • 剑指offer
大前端
  • javascript
  • vue
  • html
  • css
  • 🌏浏览器专题
  • Web性能优化
  • regexp
  • node
面试
  • 问解
  • javascript
  • css
  • 手撕代码
  • 性能优化
  • 综合问题
  • 面经汇总
  • 小程序
手撕代码
  • 数据结构与算法
  • javascript
  • css
个人站点
  • GitHub (opens new window)
  • 博客园 (opens new window)
  • 掘金 (opens new window)
线上作品
  • 轻取(文件收集) (opens new window)
  • 个人图床 (opens new window)
  • 考勤小程序 (opens new window)
  • 时光恋人 (opens new window)
  • 在线简历生成 (opens new window)
留言板
Github (opens new window)
author-avatar

粥里有勺糖

285

文章

40

标签

关于我
备战春秋
  • 心得总结
  • 校招考点汇总
  • 面经汇总
  • 复习自查
技术笔记
  • 技术教程
  • 模板工程
  • 源码学习
  • 技术概念
  • 个人作品
  • 学习笔记
计算机基础
  • 算法与数据结构
  • 操作系统
  • 计算机网络
  • 设计模式
  • 剑指offer
大前端
  • javascript
  • vue
  • html
  • css
  • 🌏浏览器专题
  • Web性能优化
  • regexp
  • node
面试
  • 问解
  • javascript
  • css
  • 手撕代码
  • 性能优化
  • 综合问题
  • 面经汇总
  • 小程序
手撕代码
  • 数据结构与算法
  • javascript
  • css
个人站点
  • GitHub (opens new window)
  • 博客园 (opens new window)
  • 掘金 (opens new window)
线上作品
  • 轻取(文件收集) (opens new window)
  • 个人图床 (opens new window)
  • 考勤小程序 (opens new window)
  • 时光恋人 (opens new window)
  • 在线简历生成 (opens new window)
留言板
Github (opens new window)
  • devlearn

    • 开发教程
    • 实践:利用ArrayBuffer实现预览指定目录下的所有文件的内容
    • 在linux-deepin上使用deepin-wine5完美运行腾讯会议/QQ/微信等此类应用
    • eslint插件开发教程
    • ServerLess之云函数实践-天气API
    • 移动端阻止弹窗下层页面被滑动
    • 小技巧:for of中获取index
    • Git常用的一些基本操作
    • 向页面注入js实现为图片和文字元素添加透明蒙层
    • 实践:使用jsencrypt配合axios实现非对称加密传输的数据
    • 封装dotenv库实现类似Vite加载环境变量的行为
    • 30行代码实现合并指定目录下的所有文件的内容
    • 马上中秋了,把鼠标指针变为小玉兔
    • Node中require与fs.readFile读取JSON文件的对比
    • 使用免费的七牛云OSS(10G)搭建个人的在线图床
    • 分享封装的一些七牛云OSS操作方法
    • 本地配置SSH免密远程登录服务器
    • 工具方法汇总
    • 腾讯云Serverless实践-Node.js服务部署
    • 腾讯云Serverless实践-静态网站托管
    • 为什么'\x1B'.length === 1?\x与\u知识延伸
    • Vite插件开发纪实:vite-plugin-monitor(上)
    • Vite插件开发纪实:vite-plugin-monitor(中)
    • Vite插件开发纪实:vite-plugin-monitor(下)
    • 解决Vite-React项目中js使用jsx语法报错的问题
    • webpack 项目接入Vite的通用方案介绍
    • webpack 项目接入Vite的通用方案介绍-草稿
    • 优雅的处理挂载window上的函数可能不存在的情况
    • Mac上抓包秒通关羊了个羊

向页面注入js实现为图片和文字元素添加透明蒙层

vuePress-theme-reco 粥里有勺糖    2018 - 2023

向页面注入js实现为图片和文字元素添加透明蒙层

粥里有勺糖 2021-07-29 技术笔记技术教程

# 向页面注入js实现为图片和文字元素添加透明蒙层

# 背景

最近在做一个操作Dom的小工具(做完再接着分享这个工具是什么)

从中拆解出了一个小练习:

  1. 高亮页面中所有的图片元素
  2. 高亮页面中所有的文字元素
  3. 页面触发显示/隐藏时,转换文字/图片高亮的颜色

最终效果如下:

图片

# 注入js

向第三方页面注入js的方法有很多

这里demo使用DevTools的控制台进行注入

简单代码如下

var a=document.createElement('script');
a.src="http://127.0.0.1:8080/index.js";
window.document.head.append(a)
1
2
3

# 图片高亮

常规的图片展示有两种方式:

  1. 使用<img>标签
  2. 设置元素的background或者background-image属性

# 情况一

**思路:**使用<div>标签将其包裹,然后再添加一个<div>作为蒙层

<div>
    <img src="url">
</div>
1
2
3

添加蒙层后结构

<div>
    <div style="position:relative">
        <img src="url">
        <div class="cover"></div>
    </div>
</div>
1
2
3
4
5
6

添加蒙层的代码如下:

    function addImgCover(img, bgc = 'rgba(255,0,0,0.2)') {
        // 如果有蒙层,则直接新的颜色
        if (img.getAttribute('cover')) {
            img.nextElementSibling.style.backgroundColor = bgc
            return
        }

        // 标记已经添加过蒙层
        img.setAttribute('cover', '1')

        const divParent = document.createElement('div')
        divParent.style.position = 'relative'

        const divChild = document.createElement('div')
        divChild.style.position = 'absolute'
        divChild.style.top = '0'
        divChild.style.width = '100%'
        divChild.style.height = '100%'
        divChild.style.backgroundColor = bgc

        divParent.appendChild(img.cloneNode())
        divParent.appendChild(divChild)

        img.replaceWith(divParent)
    }
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25

图片

# 情况二

思路: 由于是背景图片,可直接为其添加一个子元素<div>作为蒙层即可

<div>
    <div style="background-image:url(xxxx)"></div>
</div>
1
2
3

添加蒙层后结构

<div>
    <div style="background-image:url(xxxx)">
        <div class="cover"></div>
    </div>
</div>
1
2
3
4
5

添加蒙层的代码如下:

    function addBgImgCover(bgImg, bgc = 'rgba(255,0,0,0.2)') {
        // 如果有蒙层,则直接新的颜色
        if (bgImg.getAttribute('cover')) {
            bgImg.children[0].style.backgroundColor = bgc
            return
        }

        // 标记已经添加过蒙层
        bgImg.setAttribute('cover', '1')

        const divChild = document.createElement('div')
        divChild.style.width = '100%'
        divChild.style.height = '100%'
        divChild.style.backgroundColor = bgc
        bgImg.appendChild(divChild)
    }
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16

# 文字高亮

文字就比较简单,可以直接设置background-color实现

function addTextCover(textEl, bgc = 'rgba(255,0,0,0.2)') {
    textEl.style.backgroundColor = bgc
}
1
2
3

# 获取所有图片元素

使用querySelectorAll获取img元素

简单的递归方法获取使用background-image属性的元素

实现如下

    function judgeBgImgEl(el) {
        return el && !!el.style.backgroundImage
    }
    function getAllImgEls() {
        // 常规的
        const imgs = document.querySelectorAll('img')

        // 递归获取非常规的
        const getBgIms = (el = document.body) => {
            const res = []
            if (el.childElementCount > 0) {
                Array.from(el.children).forEach(v => {
                    res.push(...getBgIms(v))
                })
            }
            if (judgeBgImgEl(el)) {
                res.push(el)
            }
            return res
        }
        const bgImgs = getBgIms()
        return {
            imgs,
            bgImgs
        }
    }
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26

# 获取所有文本元素

思路跟递归获取图片一致,条件略有区别

  1. 通过textContent可以获取元素的文本内容(包含子孙元素的)
  2. 通过childElementCount可以获取子元素的个数
  3. 当无子元素且内容不为空的元素即为目标元素

实现如下

function getAllTextEls() {
    // 递归获取
    const getTextEls = (el = document.body) => {
        const res = []
        if (el.childElementCount === 0) {
            el.textContent.trim().length !== 0 && res.push(el)
        } else {
            Array.from(el.children).forEach(e => {
                res.push(...getTextEls(e))
            })
        }
        return res
    }
    return getTextEls()
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15

# 监听页面显/隐

这个就比较简单了,直接调用原生监听事件(visibilitychange)即可:

    let theme = 'red'

    // 主题切换
    window.addEventListener('visibilitychange', (e) => {
        if (document.hidden) {
            theme = theme === 'red' ? 'blue' : 'red'
            changeTheme(theme)
        }
    })
1
2
3
4
5
6
7
8
9

# 最后

本文只是简单的抛砖,做了一个简单的demo

上述方式肯定还有考虑不周到的地方,留给感兴趣的同学继续探索

完整源码地址 (opens new window)

Edit this page (opens new window)
Last Updated: 2022/5/15 12:46:34