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

油猴脚本使用shadowDom添加界面并引入样式

[复制链接]

该用户从未签到

2

主题

4

回帖

13

积分

助理工程师

积分
13

新人报道

发表于 2024-5-4 18:17:03 | 显示全部楼层 | 阅读模式

ShadowDom是个好东西,可以隔离组件防止自己的组件被网站商店css,js啥的污染,所以编写油猴脚本添加自己的div时就可以放心的写样式,不用担心样式问题了

然而通常import './app.css' , css module, css in js ,tailwind等所生成的样式都是全局的,无法应用到shadowDom里面,这该怎么办呢?(我也很想知道,我想用tailwind啊)

其实style-components和emotioncss都有自己的api,可以把样式注入到任何位置,这样就不用担心样式在全局导致shadowDom样式不生效了,示例代码如下

main.tsx

import { App } from "./App";
import { createRoot } from "react-dom/client";
import { StyleProvider } from "@ant-design/cssinjs";
import { StyleSheetManager } from "styled-components";

(function () {
  const container = document.createElement("div");
  container.id = "shadowContainer";

  //创建shadowdom
  const shadowDom = container.attachShadow({ mode: "open" });
  const root = document.createElement("div");
  shadowDom.appendChild(root);

  //把dom附加到body去
  document.body.appendChild(container);
  const app = createRoot(root);
  // mount react app
  app.render(
    <StyleSheetManager target={shadowDom}>
      <StyleProvider container={shadowDom}>
        <App />
      </StyleProvider>
    </StyleSheetManager>
  );
})();

其中target就是style-component指定把style注入到dom的哪个位置,直接注入shadowoDom也是可以的

App.tsx


import { Button } from "antd";

import styled,{ css } from "styled-components";

const head=css`
  position:fixed;
  top: 0;
  left: 0;
`
const Container = styled.div`
  background-color: red;
  color: white;
  width: 200px;
  border: 1px solid red;
  height:200px;

  &:hover {
    border-color: blue;
  }
`;
export function App( ){

  return (

      <div className={head}>
        hello
        <Button >aaa</Button>
        <Container></Container>
      </div>

  );
}

效果如图,样式进入了shadowdom
shad.png

各位大佬有什么好的办法在油猴脚本中使用shadowdom并添加css呢?

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

    [LV.7]常住居民III

    648

    主题

    5269

    回帖

    6156

    积分

    管理员

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

    积分
    6156

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

    发表于 2024-5-5 08:07:04 | 显示全部楼层
    直接先下下来CSS然后创建shaodw通过原生网里写也可以吧
    混的人。
    ------------------------------------------
    進撃!永遠の帝国の破壊虎---李恒道

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

    使用道具 举报

    该用户从未签到

    2

    主题

    4

    回帖

    13

    积分

    助理工程师

    积分
    13

    新人报道

    发表于 2024-5-6 15:16:25 | 显示全部楼层

    李恒道 发表于 2024-5-5 08:07

    直接先下下来CSS然后创建shaodw通过原生网里写也可以吧

    想的是直接使用cssmodule, tailwind, cssinjs,或者直接import './app.scss'之类的用法;
    shadowdom得手动创建style元素,然后把css文本扔进去,或者使用
    <link href="http://localhost:8080/a.css" rel="stylesheet">这种,就很麻烦,开发的时候不爽

    回复

    使用道具 举报

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

    [LV.7]常住居民III

    648

    主题

    5269

    回帖

    6156

    积分

    管理员

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

    积分
    6156

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

    发表于 2024-5-6 15:26:32 | 显示全部楼层
    yzqdev 发表于 2024-5-6 15:16
    [md]> [李恒道 发表于 2024-5-5 08:07](forum.php?mod=redirect&goto=findpost&pid=81516&ptid=6981)
    > >  ...

    这种应该需要自己写shadow的css解析问题了

    感觉可以试一下https://stackoverflow.com/questi ... ow-root-via-webpack


    有一种方法可以用于style-loader此目的
    这一切都取决于执行顺序。你的index.tsx被执行后style-loader::insert。但影子根之前必须存在。

    最简单的方法是修改index.html.

    这是一个完整的示例:

    ./src/index.html

    ...
    <body>
        <div id="root"></div>
        <script>
            <!-- This gets executed before any other script. -->
            document.querySelector("#root").attachShadow({ mode: 'open' })
        </script>
    </body>
    ...
    ./webpack.config.js

    var HtmlWebpackPlugin = require('html-webpack-plugin');

    const cssRegex = /\.css$/i

    const customStyleLoader = {
      loader: 'style-loader',
      options: {
        insert: function (linkTag) {
          const parent = document.querySelector('#root').shadowRoot
          parent.appendChild(linkTag)
        },
      },
    }

    module.exports = {
      module: {
        rules: [
          {
            test: cssRegex,
            use: [
              customStyleLoader,
              'css-loader'
            ],
          },
        ],
      },

      plugins: [
        new HtmlWebpackPlugin({
          template: './src/index.html'
        })
      ],
    };
    混的人。
    ------------------------------------------
    進撃!永遠の帝国の破壊虎---李恒道

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

    使用道具 举报

    该用户从未签到

    2

    主题

    4

    回帖

    13

    积分

    助理工程师

    积分
    13

    新人报道

    发表于 2024-5-6 15:42:34 | 显示全部楼层

    本帖最后由 yzqdev 于 2024-5-6 15:44 编辑

    李恒道 发表于 2024-5-6 15:26

    这种应该需要自己写shadow的css解析问题了

    感觉可以试一下https://stackoverflow.com/questions/6065947 ...

    各种方法我都搜过了,就cssinjs设置注入到shadowdom这个体验跟正常一样,比如大佬这个方法,油猴脚本都是动态添加的,没法用style-loader的这个insert-into;
    网上另外一种方法就是通过xxx-loader把引入的css变成字符串,手动创建style元素,然后把css文本扔进去

    import styleText from './style.scss';
    
    const style = document.createElement('style');
    style.appendChild(document.createTextNode(styleText));
    shadow.appendChild(style)

    我再搜搜看有没有tailwindcss和cssmodule用在shaowdom上的解决方案

    回复

    使用道具 举报

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

    [LV.7]常住居民III

    648

    主题

    5269

    回帖

    6156

    积分

    管理员

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

    积分
    6156

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

    发表于 2024-5-6 15:47:12 | 显示全部楼层
    yzqdev 发表于 2024-5-6 15:42
    [md]> [李恒道 发表于 2024-5-6 15:26](forum.php?mod=redirect&goto=findpost&pid=81606&ptid=6981)
    > >  ...

    打包webpack会走loader,哥哥的意思是在油猴的头上声明然后自动引入?
    混的人。
    ------------------------------------------
    進撃!永遠の帝国の破壊虎---李恒道

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

    使用道具 举报

    该用户从未签到

    2

    主题

    4

    回帖

    13

    积分

    助理工程师

    积分
    13

    新人报道

    发表于 2024-5-6 16:10:03 | 显示全部楼层

    李恒道 发表于 2024-5-6 15:47

    打包webpack会走loader,哥哥的意思是在油猴的头上声明然后自动引入?

    我这里使用webpack打包都是把css打包进xxx.user.js的不引入外部css

    听了哥哥的说法,我想到了另一种方法:

    把自己的脚本js和css分离开,然后把css传到云端,比如使用cdn,接下来shadowDom里面就可以引用了

    
    // @resource     customCSS https://xxx.com/a.css
    // @grant        GM_addStyle
    // @grant        GM_getResourceText
    // ==/UserScript==
    
    //第一种
    
    const styleEl = document.createElement('link')
    styleEl.setAttribute('rel', 'stylesheet')
    styleEl.setAttribute('href', 'https://xx.com/a.css' )
    shadowDOM.appendChild(styleEl)
    
    //第二种
    const newCSS = GM_getResourceText ("customCSS");
    const style = document.createElement('style');
    style.appendChild(document.createTextNode(newCSS));
    shadow.appendChild(style)
    
    回复

    使用道具 举报

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

    [LV.7]常住居民III

    648

    主题

    5269

    回帖

    6156

    积分

    管理员

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

    积分
    6156

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

    发表于 2024-5-6 16:12:38 | 显示全部楼层
    yzqdev 发表于 2024-5-6 16:10
    [md]我这里使用webpack打包都是把css打包进xxx.user.js的不引入外部css

    确实也是方法
    我在想能不能提供一个header的parser工具
    来方便大家在头上做文章
    混的人。
    ------------------------------------------
    進撃!永遠の帝国の破壊虎---李恒道

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

    使用道具 举报

    该用户从未签到

    2

    主题

    4

    回帖

    13

    积分

    助理工程师

    积分
    13

    新人报道

    发表于 2024-5-6 16:21:23 | 显示全部楼层

    李恒道 发表于 2024-5-6 16:12

    确实也是方法
    我在想能不能提供一个header的parser工具
    来方便大家在头上做文章 ...

    类似这种吗
    scriptcat-webpack-plugin
    webpack-userscript
    userscript-metadata-webpack-plugin

    我感觉vite-plugin-monkey已经完全够用了,开发体验最爽

    回复

    使用道具 举报

    发表回复

    本版积分规则

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