html5 shadow dom,shadow dom解析

本文作者:IMWeb ouven

未经同意,禁止转载

1.shadowdom解析

1.1 什么是shadow dom

先看个例子:

这样一个标签可以在浏览器产生几个界面你相对较复杂的播放器,怎么做到的?

为了理解问题,可以选择chrome设置里面的show userAgent shawdow,就可以看到shadow dom里的内容。

#shadow root

0:00
0:00

shadow-root里面的内容就是所有视频播放器控制组件的所在之处,css也可以看到,可见video标签内部也是很多个div和input形成的。

另外浏览器之所以将其置灰,是为了表明这部分是在 shadow DOM 里,对于页面的其他部分来说它是 不可用的 。这里的 不可用 意味着你写的 CSS 选择器和 JavaScript代码都不会影响到这部分内容。实际上,就是让video 标签的逻辑和样式都被浏览器封装了。

1.2 小结

小结下,Shadow DOM 是一个 HTML 的规范,其允许开发者封装自己的 HTML 标签、CSS 样式和 JavaScript代码。也使得开发人员可以创建诸如 video这样自定义的一级标签。总的来说,这些新标签和相关的 API 被称为 Web Components。

关于shadow 都没有些概念可以理解下,上面shadow root是shadow dom的根节点;shadow tree为这个show dom包含的节点树,div和input等;shadow host称为shadow dom的容器元素,即video

2.如何创建shadow dom

指定一个元素可以使用createShadowRoot方法创建一个shadow root,shadow root上可以任意通过dom操作添加shadow tree,同时制定样式和处理的逻辑,并将自己的api暴露出去。

完成创建后需要通过registerElement来注册元素。

(不过需要注意的是,目前支持chrome31、android4.4以上版本)

下面看个示例,是实现一个图文组合的组件功能:

图文组合插件

组价模板的代码文件如下

:host {

display:block;

font:16px monospace;

}

.banner-section{

margin:0;

padding:0;

width:100%;

display:block;

position:relative;

}

.banner-section .banner-image{

margin:0;

padding:0;

width:100%;

height:100%;

}

.banner-section .banner-text{

display:block;

position:absolute;

bottom:0;

left:0;

right:0;

padding:10px 5px;

color:#fff;

background:rgba(0,0,0,0.5);

}

.banner-section .banner-text:hover{

cursor: pointer;

}

(function(thisDoc){

"use strict"; // 启用严格模式

// 所有实例元素对象的公共prototype

var XImage = Object.create(HTMLElement.prototype, {

height: {

get: function(){ return this._height; },

set: function(height){

this._height = height;

this._innerBanner.style.height = height + 'px';

this._innerBanner.querySelector('.image').style.height = height +'px';

}

},

width: {

get: function(){ return this._width; },

set: function(width){

this._width = width;

this._innerBanner.style.width = width + 'px';

this._innerBanner.querySelector('.image').style.width = width +'px';

}

},

alt: {

get: function(){ return this._width; },

set: function(alt){

this._alt = alt;

this._innerBanner.querySelector('.banner-text') = alt;

this._innerBanner.querySelector('.image').setAttribute('alt', alt);

}

},

src: {

get: function(){ return this._src; },

set: function(src){

this._src = src;

this._innerBanner.querySelector('.image').setAttribute('src', src);

}

}

});

// 组件被创建时执行,相当于构造函数

XImage.createdCallback = function(){

// 创建Shadow root,自定义模板放入其中

var sr = this.createShadowRoot();

var template = thisDoc.querySelector("template");

var node = document.importNode(template.content, true);

this._innerBanner = node.querySelector(".banner-section");

var height = this._height || Number(this.getAttribute("height")),

width = this._width || Number(this.getAttribute("width")),

alt = this._alt || String(this.getAttribute('alt')),

src = this._src || String(this.getAttribute('src'));

if (!isNaN(height) || !isNaN(width)) {

this.height = height;

this.width = width;

}

if(alt){

this.alt = alt;

}

this.src = src;

sr.appendChild(node);

};

// 注册组件

document.registerElement("x-image", { prototype: XImage });

})(document.currentScript.ownerDocument); // ownerDocument指向被导入的文档对象(本文件)

html中使用html import方式引入外部的shadow dom内容,在支持shadow dom的浏览器上显示如下效果,同时在自定义的组件里可以按照自己的需要向外暴露可配置属性和webApi接口。

6c16dab0f38e0b458877c6c7552183b2.png

参考:

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值