样式文件的动态引用
背景
要实现一个主题切换功能,通常的解决方案是替换css
文件,由此就引出了样式文件的动态引用。样式文件的动态引用普遍有两种方式。
动态创建Link标签
1 2 3 4 5 6 7 8 9
| export const includeLinkStyle = async (sourceThemeName) => { let cssPath = ``; var link = document.createElement('link'); link.rel = 'stylesheet'; link.type = 'text/css'; link.href = cssPath; document.getElementsByTagName('head')[0].appendChild(link); };
|
动态创建Style标签
1 2 3 4 5 6 7 8
| export const includeLinkStyle = async (sourceThemeName) => { let cssPath = ``; const cssText = await axios.get(cssPath); var style = document.createElement('style'); style.innerHTML = cssText.data; document.getElementsByTagName('head')[0].appendChild(style); };
|
两种方式并无本质区别,都是动态创建了一个元素,写入元素属性,将元素压入文档流。不过由于浏览器的资源请求机制,在实际应用上加载远程样式时仍有一些区别。
资源请求机制
假设在example.com
域下有资源style.css
1 2 3 4
| body{ background: red; background-image: url('./2.png'); }
|
以动态创建Link标签为例。浏览器中可以查看到2.png
的请求,请求头为:
1 2 3 4 5 6 7 8
| Accept: image/webp,image/apng,image*;q=0.8 Accept-Encoding: gzip, deflate Accept-Language: zh-CN,zh;q=0.9,en;q=0.8,en-GB;q=0.7,en-US;q=0.6 Cookie: connect.sid=s%3AxFoVr0cFWtheWipka_J25nHMCikvPAJp.Irxj4n60P43ve%2BR1OL6VethJP5FDe3QNt5GZk0QplTM; thinkjs=a3139926-434d-4dbc-a9a9-8a5f279727bf; thinkjs.sig=5dzO8-ZdaKKGRWImhC1DTl4GemI Host: example.com Proxy-Connection: keep-alive Referer: http: User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/83.0.4103.61 Safari/537.36 Edg/83.0.478.37
|
以动态创建Style标签的方式。浏览器中可以查看到2.png
的请求,请求头为:
1 2 3 4 5 6 7 8 9 10 11 12
| Accept: image/webp,image/apng,image*;q=0.8 Accept-Encoding: gzip, deflate, br Accept-Language: zh-CN,zh;q=0.9,en;q=0.8,en-GB;q=0.7,en-US;q=0.6 Connection: keep-alive Cookie: thinkjs=3cc3a7a5-5435-413d-86b0-86fd9c807403; thinkjs.sig=9k3bn5ttg8Z5iGHIqiP2jpBOn5E Host: localhost:8080 If-None-Match: W/"910-osEmo5hhdX1FHE/d8oogcny8bhI" Referer: http: Sec-Fetch-Dest: image Sec-Fetch-Mode: no-cors Sec-Fetch-Site: same-origin User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/83.0.4103.61 Safari/537.36 Edg/83.0.478.37
|
可以这么理解,以link
方式请求了css
文件,css
内部的相对路径,都是相对于css
文件的。如果拿到了css
文件的text值并写入html
的style
标签,请求是相对于html
的。
如此,其实以动态创建Style标签的方式是拿不到背景图片的。
总结
资源的相对路径引用,多多少少会存在一些问题。如果可以的话,主题样式文件,应该尽量以文件名作为区分例如theme1.style.min.css
,theme1-1.png
而不是以路径作为区分\theme1\style.min.css
,\theme1\1.png
参考 & 引用
https://segmentfault.com/a/1190000007491687