说说 web components

Web Components 的现状

到目前为止,w3c定义的web components已经包含了

  • Templates, 提供一个包含html,css,js的代码片段,类似于一般模板引擎里的视图
  • Custom Elements, 提供一个自定义html元素的接口,支持对现有html元素的扩展
  • Imports, 提供对模板或者自定义元素这些资源的加载支持
  • Shadow DOM, 提供一个对外隐藏的web片段,而且支持独立的样式,不会破坏文档内的样式

web 组件的技术规范的制定就是为了保证前端组件的规范化,独立性,可重用性.先来说说Templates功能


Templates

Templates提供了类似于模板引擎里的视图功能,默认浏览器是不会渲染此标签的内容的,只有当你真正用的时候才会去render,下面给一个简单的使用Templates的例子

<template id="foo">
    <h2>Hello, world!</h2>
</template>

跟普通的html标签一样,定义一个id来标识这段代码,下面我们来使用这个模板

var template = document.querySelector('#foo');
document.querySelector('body').appendChild(template.content.cloneNode(true));

上面的代码就是往body里插入模板里的内容,这里要注意下,想要获取模板内的内容,得使用模板元素的content属性,内容的类型是documentFragment,一般在同时插入多个html内容的时候,用documentFragment是最有效率的, 这里还要注意下,假如直接把content的内容插入到目标元素内之后,模板的内容就会丢失,所以为了保证别的目标元素也想插入这个模板的话,可以使用NodecloneNode方法,这是所有html节点都有的方法,参数传递true的话会深度clone.

Custom Elements

自定义元素api接口提供了一个可以自定义html元素的方法,支持新增方法以及对现有的元素进行扩展

w3c提供了document.registerElement方法来创建一个新元素,先来一个简单的实例,然后再分析它的实现

var p = Object.create(HTMLElement.prototype);
p.hello = function () {
    this.appendChild("<h1>hello feenan</h1>");
}
var HelloFeenan = document.registerElement('hello-feenan', {prototype: p});

上面的代码创建一个名叫hello-feenan的元素,自定义的元素必须以-来连接,Object.create传递一个原型,将会创建继承这个原型的对象,然后对这个原型进行方法扩展,这里加了一个hello方法,定义完这个元素之后,怎么使用呢,其实它跟系统自带的元素一样,可以直接在html页里使用也可以动态的添加,这里使用document.createElement方法来添加,然后动态的添加body元素中

var el = document.createElement('hello-feenan');

document.querySelector('body').appendChild(el);

// 调用hello方法来添加子元素
document.querySelector('hello-feenan').hello();

上面的代码就是应用自定义元素的好例子,其实这里的hello方法的内容可以在自定义元素的初始化事件回调里执行,说到这里,就得提提customer element 的支持的事件了

  • createdCallback 自定义元素创建实例的时候触发
  • attachedCallback 当元素实例被添加到document文档流中时触发
  • detachedCallback 当从document文档流中删除自定义的元素实例时触发
  • attributeChangedCallback 当元素实例的属性修改的时候触发

这四个事件的回调函数必须定义在自定义元素的原型对象上面,比如上面的p,可以通过createdCallback事件来实现上面的hello方法的内容

p.createdCallback = function(){
    this.appendChild("<h1>hello feenan</h1>");
}

下面是一个完整的带自定义元素实现的例子

<html>
    <head>
        <title>customer elements</title>
        <meta charset="utf-8">
    </head>
    <body>
        <script>

            var helloFeenan = Object.create(HTMLElement.prototype);

            helloFeenan.hello = function(){
                this.appendChild("<h1>hello feenan</h1>");
            }

            // 当元素被创建的时候触发此回调函数
            helloFeenan.createdCallback = function(){
                this.appendChild("<h1>hello feenan</h1>");
            }
            document.registerElement('hello-feenan', { prototype: helloFeenan});

            var el = document.createElement('hello-feenan');

            document.querySelector('body').appendChild(el);

        </script>
    </body>
</html>

Imports

imports特性提供了以link方式来导入一段html文本的功能,相当于是template的进化版,方便做成模板文件

w3c规定linkrel属性传入import值,然后设置src为一个html文件,像下面这样的

<link rel="import" href="import.html">

那么在引入页面的dom里怎么获取导入的文件内容呢,w3crel=import的元素提供了import属性来获取文件内容,本质上是#document类型,可以像下面这样来获取内容

var link = $('link[rel=import]')[0];

var link_doc = link.import;

Shadow DOM

shadow dom根据字面意思就知道这是隐藏在dom节点里的元素,提供了对css,js,html的封装从而形成一个独立组件的功能,这是一个非常不错的特性,结合import可以实现一个可重用的Web组件功能替代现在的一些ui组件.

下面我们来看看怎么使用shadow dom

w3c提供了createShadowRoot方法,这属于element的方法,在元素上面调用这个方法将在它下面创建shadow dom子元素,可以像下面这样来使用

var shadowroot = $('.content')[0].createShadowRoot();
var elm = document.createElement('h1');
elm.textConent = 'hello feenan';
shadowroot.appendChild(elm);

一个完整的例子

目前chrome 36 已对template, import, shadow dom提供了完整的支持,所以下面提供一个结合三者的例子

  • link元素需要引入的import.html文件

<style>
    .content{
        margin: 20px;padding: 15px;
        width: 200px;height: 200px;
        border: 1px solid #ccc;border-radius: 5px;
        box-shadow: 0 0 10px red;
        overflow: auto;
    }
</style>
<div class="content">
    <h2>this is a test for ShadowRoot</h2>
</div>

上面的文件,chrome在用link引入之后,样式文件会放在link.importdocument里的head元素内,普通html元素会放入body中,知道了内容的位置,方便下面用的时候查找

  • index.html 运行例子的主html文件

<!doctype html>
<html>
<head>
    <title>web components</title>
    <meta charset='utf8'>
    <link rel="import" href="import.html">
    <style>
        .content{
            margin: 20px;padding: 15px;
            width: 300px;height: 400px;
            border: 1px solid #ccc;border-radius: 5px;
            box-shadow: 0 0 10px #009933 inset;
            overflow: auto;
        }
        .btn{
            width: 120px;line-height: 30px;
            font-size: 16px;
            text-align: center;
            padding: 10px 15px;
            border-radius: 5px;
            border: 1px solid #ccc;
            box-shadow: 0 0 5px #ddd;
        }
        .btn:focus{
            outline: none;
            box-shadow: 0 0 10px green;
        }
    </style>
</head>
<body>
    <div class="content">
    </div>
    <p class="tmpl"></p>
    <p>
        <button class="btn add">添加</button>
    </p>
    <template id="tmpl1">
        <h1>hello feenan!</h1>
    </template>
    <script src="/lib/jquery/dist/jquery.min.js"></script>
    <script>
        $('.add').click(function(){

            var link = $('link[rel=import]')[0];

            // 获取引入文件的模板内容,返回的其实是#document类型
            var link_doc = link.import;

            // 创建shadow dom 元素,本质是一个documetn片段元素
            var shadowroot = $('.content')[0].createShadowRoot();

            // 创建样式
            var style = function(){
                var css = document.createElement('style');
                // 通过styleSheets获取模板内的样式内容
                css.textContent = link_doc.styleSheets[0].rules[0].cssText;
                return css;
            }

            // 创建内容
            var body = function(){
                return $(link_doc.body.innerHTML)[0];
            }

            shadowroot.appendChild(style());
            shadowroot.appendChild(body());
            $('.content').append($(link_doc).find('body').html());

            // 使用template来获取模板文件
            $('.content').append($('#tmpl1')[0].content.cloneNode(true));

        });
    </script>
</body>
</html>
  • 以上的例子建议在chrome 36里运行

总结

非常高兴chrome已对template,import,customer element,shadow dom提供了完整的支持,更多关于各个浏览器对web components支持请点击这里

关于web components相关的网站,可以参考下面的地址,大部分都要翻墙浏览,因为基本上都是google维护的

webcomponents 官网

Polymer 框架, google出品的开发web组件的框架,兼容大部分浏览器

w3c web 组件规范

时间: 2024-10-08 11:02:56

说说 web components的相关文章

Programming Microsoft Office 2000 Web Components第一

第一章第二节 Office Web Components是什么? Office Web Components是一组的COM控件,设计的目的是为众多的控件容器提供交互的电子表格建模,数据报表和数据可视化功能.OWC库包含四个主要的组件:电子表格组件,图表组件,透视表组件和数据源组件.我们将在这一节中简要论述每个控件,然后在后续各章中讨论更多细节. 注释: COM也被称作ActiveX.当微软发明了术语"ActiveX"来描述COM技术时,我正在Visual Basic小组,这个术语使得我

Programming MS Office 2000 Web Components第二章第二节

web 第二章第二节 电子表格组件的高级功能 我们已经讨论了电子表格组件的大部分基本功能,现在让我们转向一些高级功能.大部分的这些高级功能Excel2000都不包含,因为这些是组件专门需要的特殊功能.而那些Excel2000中存在的功能,在电子表格组件中也被增强,使得可以提供一些新的功能. 属性绑定和实时数据 "属性绑定"是电子表格组件中最新奇的新功能之一,它是指控件能够将同一个web页面上其它对象的属性和方法用作单元值或公式参数的能力.电子表格控件使用标准的COM机制来实现绑定到属性

Programming Microsoft Office 2000 Web Components第一章

web 译者说明:<Programming Microsoft Office 2000 Web Components>是我从网上下载的一本讲述OWC技术的英文电子书,之所以要翻译这本书,是基于以下几个想法:1.阅读英文资料时常常会不求甚解,忽略很多细节和不容易阅读的句子,如果强迫自己逐句的翻译出来,则会对原来的英文资料有更加全面.详细和深刻的了解.2.可以锻炼自己在英语方面的能力.3.能够给其他需要这方面的资料的朋友提供一定的帮助. 这是本人初次进行这方面的工作,本人的技术和英文能力都很一般,

Programming Microsoft Office 2000 Web Components第一章第一节

web 第一章第二节 Office Web Components是什么? Office Web Components是一组的COM控件,设计的目的是为众多的控件容器提供交互的电子表格建模,数据报表和数据可视化功能.OWC库包含四个主要的组件:电子表格组件,图表组件,透视表组件和数据源组件.我们将在这一节中简要论述每个控件,然后在后续各章中讨论更多细节. 注释: COM也被称作ActiveX.当微软发明了术语"ActiveX"来描述COM技术时,我正在Visual Basic小组,这个术

Programming MS Office 2000 Web Components第一章第三节

web 哪里可以使用这些组件? 既然Office Web Components都是COM控件,您会很自然的希望它们能够在任何自称是COM控件容器的环境中工作.然而,理论和现实不总是一致的,尤其在软件世界里.微软公司创造了许多能够包含控件的环境(我们小组脱口就能说出了16个),而别的公司创造了许多其它的环境. 为了避免Office的测试小组发狂,我们针对不同的容器,进行不同的级别的Office Web Components测试.首先,我们挑选出那些我们认为人们使用的最多的容器,进行了充分的测试.然

Web Components是个什么样的东西

前端组件化这个主题相关的内容已经火了很久很久,angular 刚出来时的 Directive 到 angular2 的 components,还有 React 的components 等等,无一不是前端组件化的一种实现和探索,但是提上议程的 Web Components 标准是个怎样的东西,相关的一些框架或者类库,如 React,Angular2,甚至是 x-tag,polymer 现在实现的组件化的东西和 Web Components 标准差别在哪里?我花时间努力地把现有的 W3C Web C

一、Angular 2.0的变革之路-组件化 Web Components

Angular 2.0的变革之路 Angular 1.x从2009年到现在已经过了6个年头,虽然中间Angular1.x顺应前端思想加入了很多新的特性,例如在1.3版本加入的bindToController,在1.5版本加入的用于取代directive部分功能的component.然而从整体的设计思想来说,Web Components已经成为大势所趋,Angular的变革也就势在必行. Angular 2.0 放弃了对1.x版本的兼容,这也就意味着2.0版本没有了1.x版本的历史包袱.Googl

Web Services: Building Reusable Web Components wit

Web Services: Building Reusable Web Components with SOAP and ASP.NET David S. Platt This article assumes you're familiar with XML and Visual Basic Level of Difficulty 1 2 3 Download the code for this article: WebComp.exe(93KB) Browse the code for thi

Web Components是不是Web的未来

今天 ,Web 组件已经从本质上改变了HTML.初次接触时,它看起来像一个全新的技术.Web组件最初的目的是使开发人员拥有扩展浏览器标签的能力,可以自由的进行定制组件.面对新的技术,你可能会觉得无从下手.那这篇文章将为你揭开Web组件神秘的面纱.如果你已经熟知HTML标签和DOM编程,已经拥有了大量可用的Web组件,那么你已经是Web组件专家了. Web组件的现状 随着各式各样的用户需求,浏览器的原生组件已经无法满足需求.Web组件也就变得越来越重要. 我们将以自定义一个传统三方插件为例来介绍W