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

推荐订阅源

MongoDB | Blog
MongoDB | Blog
B
Blog RSS Feed
MyScale Blog
MyScale Blog
M
MIT News - Artificial intelligence
H
Hackread – Cybersecurity News, Data Breaches, AI and More
J
Java Code Geeks
U
Unit 42
Blog — PlanetScale
Blog — PlanetScale
L
LangChain Blog
C
Check Point Blog
WordPress大学
WordPress大学
Last Week in AI
Last Week in AI
人人都是产品经理
人人都是产品经理
T
Tailwind CSS Blog
Vercel News
Vercel News
腾讯CDC
GbyAI
GbyAI
有赞技术团队
有赞技术团队
S
SegmentFault 最新的问题
H
Help Net Security
博客园 - 三生石上(FineUI控件)
D
DataBreaches.Net
Microsoft Security Blog
Microsoft Security 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各浏览器支持情况一览表 « 张鑫旭-鑫空间-鑫生活
Safari不支持build-in自定义元素的兼容处理 « 张鑫旭-鑫空间...
张鑫旭,zhangxinxu · 2021-04-26 · via 张鑫旭-鑫空间-鑫生活

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

占位封面图 颈椎帮助

一、Safari又拖后腿了

Safari浏览器不支持build-in自定义元素,只支持匿名自定义元素。

兼容性如下图所示:

Safari不支持内置自定义元素

也就是Safari默认仅支持下面这种HTML格式的UI组件:

<ui-tips></ui-tips>
<ui-drop></ui-drop>
<ui-tab></ui-tab>
<ui-lighttip></ui-lighttip>

不支持下面这种通过is属性在原生HTML元素上扩展的web components组件。

<input is="ui-color">
<select is="ui-select"></select>
<form is="ui-form"></form>
<table is="ui-table"></table>

这就麻烦了,本来很帅气的UI组件,如果只能使用匿名自定义元素实现,就很啰嗦与乏味。

或者,狠狠心,无视Safari浏览器用户群体,可以的,等着被解雇就行。

所以,最好的解决方法就是让Safari浏览器也支持内置自定义元素组件的开发。

怎么办呢?

二、Polyfill build-in custom element

解决方法比较简单,有专门polyfill,只要引入就可以了。

项目地址:

https://github.com/WebReflection/custom-elements-builtin

适用于支持自定义元素,但是不支持内置自定义元素的场景,主要就是针对Safari浏览器。

其中的index.js是非压缩版,es.js是压缩版。

使用的时候可以直接这么使用:

<!-- HTML文档的顶部 -->
<script>
if (!(self.chrome || self.navigator))
  document.write('<script src="//unpkg.com/@webreflection/custom-elements-builtin"><\x2fscript>');
</script>

不过if判断外加document.write并不是一个好用法,但是,我们直接引用 //unpkg.com/@webreflection/custom-elements-builtin 这个地址也是不行的。

因为这个Polyfill中并没有对浏览器进行区分,按照作者的话,就是浏览器的特性是一直变化的,做浏览器类型判断是不靠谱的。

上面这句话没错,但是,我们可以不进行浏览器区分,直接基于API特性区分就好了。

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

于是,我对原始的JS代码做了内置的判断处理。

判断逻辑如下代码所示:

class AnyClass extends HTMLBRElement {
  constructor () {
    super();

    this.someMethod = true;
  }
}

if (!customElements.get('any-class')) {
  customElements.define('any-class', AnyClass, {
    extends: 'br'
  });
}


const isSupportBuildIn = document.createElement('br', {
  is: 'any-class'
}).someMethod;

基于特性判断是很安全的,如果浏览器支持内置自定义元素,则 isSupportBuildIn 的返回值就是 true,如果浏览器不支持,则会是 undefined。

优化后的JS代码我已经开源了,放在了gitee上,详见:https://gitee.com/zhangxinxu/build-in-custom-element-polyfill

项目目标源码截图

欢迎大家关注我的这个gitee账号。

三、完美运行下的问题

这段Polyfill真的挺神奇的,原来的Web Components代码无需任何修改,组件功能在Safari浏览器下完美支持,所有组件都运行良好。

然后,真正到业务代码中,进行组件传参处理的时候,发现问题了。

例如,引用代码如下:

<script src="safari-polyfill.js"></script>
<script type="module" src="my-components.js"></script>
<script type="module">
myComponent.someMethod();
</script>

在原生支持内置自定义元素的浏览器下,myComponent.someMethod() 方法是可以正常执行的。

但是在Safari浏览器下,就会报错,undefined不能作为function函数执行。

原因在于,safari-polyfill.js 由于实现机制的限制,会让自定义元素初始化的时机比原生浏览器更靠后。

也就是在Safari浏览器下,myComponent.someMethod() 方法执行的时候,myComponent这个元素还没有变成内置自定义元素。

因此,执行会出错。

我的解决方法是这样的,在 connectedCallback 生命周期函数中触发一个自定义的 'connected' 事件,这样,就可以通过绑定 'connected' 事件的方式保证业务代码执行的时候,元素已经完成了组件化。

代码示意,组件中的代码部分:

connectedCallback () {
  this.dispatchEvent(new CustomEvent('connected'), {
    detail: {
      type: 'my-components'
    }
  });
}

然后,业务代码改造成这样就可以了:

<script src="safari-polyfill.js"></script>
<script type="module" src="my-components.js"></script>
<script> 
myComponent.addEventListener('connected', function () {
    this.someMethod();
});
</script>

这样就可以保证 someMethod() 方法执行的时候,组件一定已经完成了初始化。

四、想不到该说什么的小结

想不到该说些什么。

祝大家五一快乐!

什么,五一还有一周。

那就提前祝大家五一快乐,今天五一出游人会很多,大家记得注意安全哦。

比心!

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

(本篇完)