油猴脚本使用shadowDom添加界面并引入样式
ShadowDom是个好东西,可以隔离组件防止自己的组件被网站商店css,js啥的污染,所以编写油猴脚本添加自己的div时就可以放心的写样式,不用担心样式问题了> 然而通常`import './app.css'` , css module, css in js ,tailwind等所生成的样式都是全局的,无法应用到shadowDom里面,这该怎么办呢?(我也很想知道,我想用tailwind啊)
其实style-components和emotioncss都有自己的api,可以把样式注入到任何位置,这样就不用担心样式在全局导致shadowDom样式不生效了,示例代码如下
main.tsx
```js
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
```js
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
!(data/attachment/forum/202405/04/180911r66jrgcptos9voj6.png)
各位大佬有什么好的办法在油猴脚本中使用shadowdom并添加css呢? 直接先下下来CSS然后创建shaodw通过原生网里写也可以吧 > [李恒道 发表于 2024-5-5 08:07](forum.php?mod=redirect&goto=findpost&pid=81516&ptid=6981)
> > 直接先下下来CSS然后创建shaodw通过原生网里写也可以吧
想的是直接使用cssmodule, tailwind, cssinjs,或者直接`import './app.scss'`之类的用法;
shadowdom得手动创建style元素,然后把css文本扔进去,或者使用
`<link href="http://localhost:8080/a.css" rel="stylesheet">`这种,就很麻烦,开发的时候不爽 yzqdev 发表于 2024-5-6 15:16
> [李恒道 发表于 2024-5-5 08:07](forum.php?mod=redirect&goto=findpost&pid=81516&ptid=6981)
> >...
这种应该需要自己写shadow的css解析问题了
感觉可以试一下https://stackoverflow.com/questions/60659473/inject-css-styles-to-shadow-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'
})
],
}; 本帖最后由 yzqdev 于 2024-5-6 15:44 编辑
> [李恒道 发表于 2024-5-6 15:26](forum.php?mod=redirect&goto=findpost&pid=81606&ptid=6981)
> > 这种应该需要自己写shadow的css解析问题了
感觉可以试一下https://stackoverflow.com/questions/6065947 ...
各种方法我都搜过了,就cssinjs设置注入到shadowdom这个体验跟正常一样,比如大佬这个方法,油猴脚本都是动态添加的,没法用style-loader的这个insert-into;
网上另外一种方法就是通过xxx-loader把引入的css变成字符串,手动创建style元素,然后把css文本扔进去
```js
import styleText from './style.scss';
const style = document.createElement('style');
style.appendChild(document.createTextNode(styleText));
shadow.appendChild(style)
```
我再搜搜看有没有tailwindcss和cssmodule用在shaowdom上的解决方案 yzqdev 发表于 2024-5-6 15:42
> [李恒道 发表于 2024-5-6 15:26](forum.php?mod=redirect&goto=findpost&pid=81606&ptid=6981)
> >...
打包webpack会走loader,哥哥的意思是在油猴的头上声明然后自动引入? 李恒道 发表于 2024-5-6 15:47
打包webpack会走loader,哥哥的意思是在油猴的头上声明然后自动引入?
我这里使用webpack打包都是把css打包进xxx.user.js的不引入外部css
听了哥哥的说法,我想到了另一种方法:
把自己的脚本js和css分离开,然后把css传到云端,比如使用cdn,接下来shadowDom里面就可以引用了
```js
// @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)
``` yzqdev 发表于 2024-5-6 16:10
我这里使用webpack打包都是把css打包进xxx.user.js的不引入外部css
确实也是方法
我在想能不能提供一个header的parser工具
来方便大家在头上做文章 > [李恒道 发表于 2024-5-6 16:12](forum.php?mod=redirect&goto=findpost&pid=81616&ptid=6981)
> > 确实也是方法
我在想能不能提供一个header的parser工具
来方便大家在头上做文章 ...
类似这种吗
(https://github.com/scriptscat/scriptcat-webpack-plugin)
(https://github.com/momocow/webpack-userscript)
(https://github.com/trim21/userscript-metadata-webpack-plugin)
我感觉(https://github.com/lisonge/vite-plugin-monkey)已经完全够用了,开发体验最爽
页:
[1]