惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

Y
Y Combinator Blog
GbyAI
GbyAI
U
Unit 42
WordPress大学
WordPress大学
Last Week in AI
Last Week in AI
P
Proofpoint News Feed
D
DataBreaches.Net
N
Netflix TechBlog - Medium
H
Hackread – Cybersecurity News, Data Breaches, AI and More
freeCodeCamp Programming Tutorials: Python, JavaScript, Git & More
C
Check Point Blog
Martin Fowler
Martin Fowler
月光博客
月光博客
MongoDB | Blog
MongoDB | Blog
MyScale Blog
MyScale Blog
The Cloudflare Blog
Apple Machine Learning Research
Apple Machine Learning Research
让小产品的独立变现更简单 - ezindie.com
让小产品的独立变现更简单 - ezindie.com
M
MIT News - Artificial intelligence
云风的 BLOG
云风的 BLOG
罗磊的独立博客
B
Blog RSS Feed
J
Java Code Geeks
The GitHub Blog
The GitHub Blog

张鑫旭-鑫空间-鑫生活

1分钟速度了解text-align match-parent声明 « 张鑫旭-鑫空间-鑫生活 光标的形状也能设置了,就是CSS caret-shape属性 « 张鑫旭-鑫空间-鑫生活 pretext与文字四面环绕效果的实现 « 张鑫旭-鑫空间-鑫生活 JSON.rawJSON方法的作用是什么? « 张鑫旭-鑫空间-鑫生活 如何使用CSS判断鼠标从哪个方向进入元素? « 张鑫旭-鑫空间-鑫生活 借助mediabunny纯JS实现视频水印、剪裁、合成等功能 « 张鑫旭-鑫空间-鑫生活 务必谨慎使用JS WeakRef弱引用 « 张鑫旭-鑫空间-鑫生活 CSS六边形头像的实现与蜂巢布局 « 张鑫旭-鑫空间-鑫生活 CSS corner-shape与背景底纹技术 « 张鑫旭-鑫空间-鑫生活 浅学WebTransport API:下一代Web双向通信技术 « 张鑫旭-鑫空间-鑫生活 HTML dialog元素新支持了closedBy属性 « 张鑫旭-鑫空间-鑫生活 HTML interestfor属性与悬停popover交互效果 « 张鑫旭-鑫空间-鑫生活 CSS3模拟window7炫酷界面效果展示 « 张鑫旭-鑫空间-鑫生活 图片旋转+剪裁js插件(兼容各浏览器) « 张鑫旭-鑫空间-鑫生活 纯js无图片无外链CSS图片幻灯片播放插件 « 张鑫旭-鑫空间-鑫生活 CSS border三角、圆角图形生成技术简介 « 张鑫旭-鑫空间-鑫生活 CSS “渐进增强”在web制作中常见应用举例 « 张鑫旭-鑫空间-鑫生活 让IE6/IE7/IE8浏览器支持CSS3属性 « 张鑫旭-鑫空间-鑫生活 jQuery – 高亮动态显示页面HTML代码插件 « 张鑫旭-鑫空间-鑫生活 翻译 – 逐渐消失的Flash网站 « 张鑫旭-鑫空间-鑫生活 CSS reset的重新审视 – 避免样式重置 « 张鑫旭-鑫空间-鑫生活 新浪微博插入话题后部分文字选中的js实现 « 张鑫旭-鑫空间-鑫生活 JavaScript实现http地址自动检测并添加URL链接 « 张鑫旭-鑫空间-鑫生活 CSS实现兼容性的渐变背景(gradient)效果 « 张鑫旭-鑫空间-鑫生活 CSS content内容生成技术以及应用 « 张鑫旭-鑫空间-鑫生活 CSS gradient渐变之webkit核心浏览器下的使用 « 张鑫旭-鑫空间-鑫生活 CSS渐变之CSS3 gradient在Firefox3.6下的使用 « 张鑫旭-鑫空间-鑫生活 区分IE8/IE7/IE6及其他浏览器-CSS “\9″hack « 张鑫旭-鑫空间-鑫生活 CSS实现跨浏览器兼容性的盒阴影效果 « 张鑫旭-鑫空间-鑫生活 CSS3&HTML5各浏览器支持情况一览表 « 张鑫旭-鑫空间-鑫生活
Web Components中引入外部CSS的3种方法 « 张鑫旭-鑫空间-鑫生活
张鑫旭,zhangxinxu · 2021-02-13 · via 张鑫旭-鑫空间-鑫生活

by zhangxinxu from https://www.zhangxinxu.com/wordpress/?p=9816
本文欢迎分享与聚合,全文转载就不必了,尊重版权,圈子就这么大,若急用可以联系授权。

爱心纹理

为了重复利用,本文的Web Components组件就使用前两天写的“巧用两个type=range input实现区域范围选择”这篇文章中的Range组件示意。

原Range组件的CSS都是直接内联在Shadow DOM中的,如下图所示:

style样式内联

实际开发时候,往往会碰到需要引入外部CSS到Shadow DOM中的情况,此时该如何处理才合适呢?

本文介绍3种处理方法。

假设Range组件需要的CSS都放在了一个名为range.css的文件中。

一、@import方法

代码示意:

class uiRange extends HTMLElement {
    constructor () {
        super();
        // 附加Shadow DOM
        this.attachShadow({
            mode: 'open'
        });
        // 创建样式
        let node = document.createElement('style');
        node.innerHTML = `@import './range.css';`;
        this.shadowRoot.append(node);
    }
    ...
}
if (!customElements.get('ui-range')) {
    customElements.define('ui-range', uiRange);
}

引用的核心就是下面这样CSS语句:

@import './range.css'

实际DOM渲染效果如下截图(截自Firefox):

@import语句使用示意

优缺点

优点是兼容性不错,支持Shadow DOM的元素均支持此语法;以及使用比较方便。

缺点是性能著名的差。根据我看到的某些资料的测试数据,会有半秒左右的阻塞。

总的阻塞时间示意

不过有些站点对于小小的阻塞延时并不在意,反而更在意使用的便捷性,此时使用@import也是可以的,比方说一些demo原型页面,内部的文档页面等。

如果对性能比较在意,可以试试下面的fetch方法。

二、fetch获取

直接以请求的方式去load CSS文件的资源内容,并在Shadow DOM中输出。

代码示意:

class uiRange extends HTMLElement {
    constructor () {
        super();
        // 附加Shadow DOM
        this.attachShadow({
            mode: 'open'
        });
        // 获取样式
        fetch('./range.css').then(response => response.text()).then(data => {
            let node = document.createElement('style');
            node.innerHTML = data;
            this.shadowRoot.appendChild(node);
        });
    }
    ...
}
if (!customElements.get('ui-range')) {
    customElements.define('ui-range', uiRange);
}

由于fetch执行的时候是个异步的过程,因此并不会发生加载阻塞,理论性能会好一点。

优缺点

优点是兼容性不错,支持Shadow DOM的元素均支持此语法;以及性能还OK。

缺点是使用的时候比较啰嗦,也就是语句较多,以及感觉不是很正统。

//zxx: 如果你看到这段文字,说明你现在访问是体验糟糕的垃圾盗版网站,你可以访问原文获得很好的体验:https://www.zhangxinxu.com/wordpress/?p=9816(作者张鑫旭)

如果从正统角度来说的话,下面的方法是最合适,也是理论上应该推崇的外部CSS引入方法。

三、作为CSS module import

此方法使用浏览器原生的import语法,但是import的是CSS文件而不是JS文件。

也就是把CSS文件直接作为模块引入。

相关代码演示如下:

import styles from './range.css';
class uiRange extends HTMLElement {
    constructor () {
        super();

        let shadow = this.attachShadow({
            mode: 'open'
        });
        shadow.adoptedStyleSheets = [styles];
    }
    ...
}
if (!customElements.get('ui-range')) {
    customElements.define('ui-range', uiRange);
}

简单的2步:

  1. import引入;
  2. adoptedStyleSheets采用;

这个方法是本文介绍重点,因此有demo,您可以狠狠地点击这里:Web Components中CSS样式import引用demo

说明:由于CSS文件直接import这个语法目前仅Chrome及其同样内核浏览器支持,因此Firefox和Safari下使用的是fetch方法。

关于adoptedStyleSheets

adoptedStyleSheets这个API方法是随着样式表构造(Constructed StyleSheets)一起出现的。

存在与shadowRoot和document两个对象上,用来设置样式。

例如:

document.adoptedStyleSheets;   // 默认返回 []

adoptedStyleSheets牵扯到的新的知识点很多,这里不具体展开,以后有机会更详细介绍。

优缺点

优点是使用方便快捷且是官方推荐方法,或者是import CSS模块就是为了这个场景才支持的;以及性能OK,import本身就是异步过程。

缺点就是兼容性不行,如下图(数据源自MDN文档),Firefox和Safari还没有支持。

adoptedStyleSheets兼容性

目前使用还不太成熟,不过现在浏览器支持新特性都是很快的。

说不定2年后就可以用起来了。

其实,配合一些打包工具,实际项目中也是可以使用的。

四、3个方法对比总结

最后,把本文介绍的3个方法再一起对比总结下,参见下表:

性能好 使用便捷 兼容性好
@import
fetch
import

可以发现,缺点每个方法各占一项。

其中,import方法未来最有潜力,因为,兼容性可以慢慢变好,而其他两个方法的缺点已经定型没救了。

大家可以根据实际使用场景选择合适的方法。

以上就是正文内容,感谢你的阅读,行为仓促,如有错误,欢迎指正。

如果觉得文章不错,也欢迎分享。

看到上面爱心图标突然想到明天是情人节,哎呀,突然脑壳疼~~

本文为原创文章,欢迎分享,勿全文转载,如果实在喜欢,可收藏,永不过期,且会及时更新知识点及修正错误,阅读体验也更好。
本文地址:https://www.zhangxinxu.com/wordpress/?p=9816

(本篇完)