上一主题 下一主题
ScriptCat,新一代的脚本管理器脚本站,与全世界分享你的用户脚本油猴脚本开发指南教程目录
返回列表 发新帖

[油猴脚本开发指南]shadowroot基础介绍

[复制链接]
  • TA的每日心情
    开心
    2023-2-28 23:59
  • 签到天数: 191 天

    [LV.7]常住居民III

    620

    主题

    5084

    回帖

    5958

    积分

    管理员

    非物质文化遗产社会摇传承人

    积分
    5958

    荣誉开发者管理员油中2周年生态建设者喜迎中秋

    发表于 2022-6-1 16:05:32 | 显示全部楼层 | 阅读模式

    ShadowRoot

    我们可以参考MDN
    https://developer.mozilla.org/zh-CN/docs/Web/API/ShadowRoot
    Shadow DOM API 的 ShadowRoot 接口是一个 DOM 子树的根节点, 它与文档的主 DOM 树分开渲染。
    说白了
    ShadowRoot技术就是在一个dom树下创建一个隔离的封闭的空间
    用来隔绝网页的一些污染,让html实现一些模块化的思想
    创建类似html元素标签的封闭html块
    其目的个人推测
    是因为浏览器随着时代逐渐发展
    会不断的拓展一些新功能
    这时候普通用户可以使用ShadowRoot技术以及以前其他浏览器技术
    用来创建一些基础的html标签等等
    其一是方便用户开发和隔离污染
    其二是一旦某种ShadowRoot元素在全世界受到广泛的欢迎
    浏览器可以无缝过度实现该功能
    并且即使浏览器没有实现
    也可以利用ShadowRoot来实现进行发布和测试
    其想法来源于

    Shadow DOM removes the brittleness of building web apps. The brittleness comes from the global nature of HTML, CSS, and JS. Over the years we've invented an exorbitant number of tools to circumvent the issues. For example, when you use a new HTML id/class, there's no telling if it will conflict with an existing name used by the page. Subtle bugs creep up, CSS specificity becomes a huge issue (!important all the things!), style selectors grow out of control, and performance can suffer. The list goes on.
    
    Shadow DOM fixes CSS and DOM. It introduces scoped styles to the web platform. Without tools or naming conventions, you can bundle CSS with markup, hide implementation details, and author self-contained components in vanilla JavaScript.

    实践

    ShadowRoot使用Element.attachShadow()函数进行创建
    创建后的一些数据
    我们通常对元素的Element.shadowRoot属性进行读取
    那么我们实践一下
    首先创建一个没有shadow的一个页面,大家应该都非常了解了
    图片.png
    图片.png
    然后我们将其改造成ShadowRoot模式
    我们查看一下attachShadow函数
    var shadowroot = element.attachShadow(shadowRootInit);
    通过attachShadow创建后,返回一个shadowroot对象或null
    而attachShadow传入一个shadowRootInit对象
    shadowRootInit对象有两个参数
    mode 模式 字符串
    有两个参数,一个是open,一个是closed
    如果是为open,则从可以外部获得字符串
    如果是为close,则从外部无法获得字符串,只能从返回的引用中获取
    delegatesFocus 焦点委托
    这个据说是提高焦点性能问题,以及点击不可点击的可以转移到第一个可以点击的焦点参数
    该参数拓展了元素的焦点行为,除了点击不可点击的可以转移到第一个可以点击的焦点外,当shadow dom中的节点获取焦点时,除了焦点元素有focus外,附加shadowdom的宿主(host)元素将也会被应用上focus。
    资料来源https://web.dev/shadowdom-v1/#focus
    因为delegatesFocus在平时并不常用,所以这里就不尝试了(由于没有尝试,所以上述资料请自行辨别真假)
    我们可以实践一下代码

    <body>
        <div class="wrap">
        </div>
    
    </body>
    <script>
        let shadow= document.querySelector('.wrap').attachShadow({mode: 'open'})
        shadow.innerHTML=` <span>我是ShadowRoot</span>`
    </script>

    图片.png
    这里可以看到显示了shadow-root
    图片.png
    我们也可以根据shadow的宿主元素找到shadowRoot然后innerHTML读取
    图片.png
    但是如果将其改为closed
    图片.png
    那么在页面中根本拿不到了shadowRoot属性,而且控制器里也显示closed
    图片.png
    如果我们将attach的函数返回的sahdow对象放置到windows上
    图片.png
    可以发现这时候是可以拿到的
    图片.png
    那么我们总结一下
    1.如果是open状态可以直接根据宿主元素拿到shadowroot对象然后拿innerhtml等
    2.如果是closed对象,只能拿到创建时返回的应用才可以进一步操作shadow内对象
    如果我们想要解决页面的shadowroot的问题,有两种方式
    1.直接针对attachShadow函数进行劫持,将所有的创建的shadow都改成open模式

    let old=Element.prototype.attachShadow
    Element.prototype.attachShadow=function(...args){
        args[0].mode='open'
        return old.call(this,...args)
    }

    1.1更优秀的解决办法,来自cxxjackie
    我们可以调用old后拿到了shadowRoot引用对象
    然后赋值到元素的_shadowRoot属性上
    这样就可以在不破坏原有的参数
    以及closed的mode模式的情况下
    拿到引用!

    let old=Element.prototype.attachShadow
    Element.prototype.attachShadow=function(...args){
        const shadowRoot = old.call(this, ...args);
        this._shadowRoot = shadowRoot;
        return shadowRoot;
    }

    2.分析页面拿到attachShadow函数返回的对象
    这个具体情况具体分析
    暂且不表
    那么我们这节课就算完成了

    结语

    撒花~

    混的人。
    ------------------------------------------
    進撃!永遠の帝国の破壊虎---李恒道

    入驻了爱发电https://afdian.net/a/lihengdao666
    个人宣言:この世界で私に胜てる人とコードはまだ生まれていません。死ぬのが怖くなければ来てください。
  • TA的每日心情
    开心
    2024-3-13 10:14
  • 签到天数: 211 天

    [LV.7]常住居民III

    284

    主题

    3810

    回帖

    3739

    积分

    管理员

    积分
    3739

    管理员荣誉开发者油中2周年生态建设者喜迎中秋油中3周年挑战者 lv2

    发表于 2022-6-1 17:11:18 | 显示全部楼层
    油猴 king!
    上不慕古,下不肖俗。为疏为懒,不敢为狂。为拙为愚,不敢为恶。/ 微信公众号:一之哥哥
    回复

    使用道具 举报

  • TA的每日心情
    开心
    2023-2-28 23:59
  • 签到天数: 191 天

    [LV.7]常住居民III

    620

    主题

    5084

    回帖

    5958

    积分

    管理员

    非物质文化遗产社会摇传承人

    积分
    5958

    荣誉开发者管理员油中2周年生态建设者喜迎中秋

    发表于 2022-6-1 17:28:36 | 显示全部楼层

    我是要成为豆油美猴王的男人!
    混的人。
    ------------------------------------------
    進撃!永遠の帝国の破壊虎---李恒道

    入驻了爱发电https://afdian.net/a/lihengdao666
    个人宣言:この世界で私に胜てる人とコードはまだ生まれていません。死ぬのが怖くなければ来てください。
    回复

    使用道具 举报

  • TA的每日心情

    2023-12-8 22:55
  • 签到天数: 37 天

    [LV.5]常住居民I

    15

    主题

    145

    回帖

    153

    积分

    荣誉开发者

    积分
    153

    荣誉开发者

    发表于 2022-6-1 20:26:23 | 显示全部楼层
    gg学到了!
    摸鱼中
    回复

    使用道具 举报

  • TA的每日心情
    慵懒
    2022-3-8 11:41
  • 签到天数: 2 天

    [LV.1]初来乍到

    22

    主题

    857

    回帖

    1356

    积分

    荣誉开发者

    积分
    1356

    荣誉开发者卓越贡献油中2周年生态建设者油中3周年挑战者 lv2

    发表于 2022-6-1 20:35:33 | 显示全部楼层
    劫持这样感觉好一点,尽量不破坏原有的设计:
    1. const shadowRoot = old.call(this, ...args);
    2. this._shadowRoot = shadowRoot;
    3. return shadowRoot;
    复制代码
    回复

    使用道具 举报

  • TA的每日心情
    开心
    2023-2-28 23:59
  • 签到天数: 191 天

    [LV.7]常住居民III

    620

    主题

    5084

    回帖

    5958

    积分

    管理员

    非物质文化遗产社会摇传承人

    积分
    5958

    荣誉开发者管理员油中2周年生态建设者喜迎中秋

    发表于 2022-6-1 20:43:43 | 显示全部楼层
    cxxjackie 发表于 2022-6-1 20:35
    劫持这样感觉好一点,尽量不破坏原有的设计:

    品到了!明天改一下!
    这个确实是好思路
    混的人。
    ------------------------------------------
    進撃!永遠の帝国の破壊虎---李恒道

    入驻了爱发电https://afdian.net/a/lihengdao666
    个人宣言:この世界で私に胜てる人とコードはまだ生まれていません。死ぬのが怖くなければ来てください。
    回复

    使用道具 举报

  • TA的每日心情
    开心
    2023-2-28 23:59
  • 签到天数: 191 天

    [LV.7]常住居民III

    620

    主题

    5084

    回帖

    5958

    积分

    管理员

    非物质文化遗产社会摇传承人

    积分
    5958

    荣誉开发者管理员油中2周年生态建设者喜迎中秋

    发表于 2022-6-1 20:47:55 | 显示全部楼层
    cxxjackie 发表于 2022-6-1 20:35
    劫持这样感觉好一点,尽量不破坏原有的设计:

    现在加上了!
    大佬牛逼!
    我写的时候其实就感觉脏
    但是没想到这个好办法
    混的人。
    ------------------------------------------
    進撃!永遠の帝国の破壊虎---李恒道

    入驻了爱发电https://afdian.net/a/lihengdao666
    个人宣言:この世界で私に胜てる人とコードはまだ生まれていません。死ぬのが怖くなければ来てください。
    回复

    使用道具 举报

  • TA的每日心情
    慵懒
    2022-3-8 11:41
  • 签到天数: 2 天

    [LV.1]初来乍到

    22

    主题

    857

    回帖

    1356

    积分

    荣誉开发者

    积分
    1356

    荣誉开发者卓越贡献油中2周年生态建设者油中3周年挑战者 lv2

    发表于 2022-6-2 11:05:10 | 显示全部楼层
    李恒道 发表于 2022-6-1 20:47
    现在加上了!
    大佬牛逼!
    我写的时候其实就感觉脏

    只是一点微小的改动,不要尬吹不要尬吹。
    回复

    使用道具 举报

  • TA的每日心情
    开心
    2023-2-28 23:59
  • 签到天数: 191 天

    [LV.7]常住居民III

    620

    主题

    5084

    回帖

    5958

    积分

    管理员

    非物质文化遗产社会摇传承人

    积分
    5958

    荣誉开发者管理员油中2周年生态建设者喜迎中秋

    发表于 2022-6-2 14:05:38 | 显示全部楼层
    cxxjackie 发表于 2022-6-2 11:05
    只是一点微小的改动,不要尬吹不要尬吹。

    话说大佬对Ts学的好吗
    我对基础ts是理解的
    但是碰到很好的精品项目或者框架的ts
    直接升天
    感觉有一些鸿沟
    但是不知道怎么补
    大佬有经验吗
    混的人。
    ------------------------------------------
    進撃!永遠の帝国の破壊虎---李恒道

    入驻了爱发电https://afdian.net/a/lihengdao666
    个人宣言:この世界で私に胜てる人とコードはまだ生まれていません。死ぬのが怖くなければ来てください。
    回复

    使用道具 举报

  • TA的每日心情
    慵懒
    2022-3-8 11:41
  • 签到天数: 2 天

    [LV.1]初来乍到

    22

    主题

    857

    回帖

    1356

    积分

    荣誉开发者

    积分
    1356

    荣誉开发者卓越贡献油中2周年生态建设者油中3周年挑战者 lv2

    发表于 2022-6-2 20:35:16 | 显示全部楼层
    李恒道 发表于 2022-6-2 14:05
    话说大佬对Ts学的好吗
    我对基础ts是理解的
    但是碰到很好的精品项目或者框架的ts

    ts的问题还是问一之大佬吧,我更习惯用js写。
    回复

    使用道具 举报

    发表回复

    本版积分规则

    快速回复 返回顶部 返回列表