翻譯的很差,輕拍css
Polymer是google的一款前端開發框架,其基於Shadow DOM、Custom Elements、MDV等最新瀏覽器特性構建,表明了下一代Web框架的方向:一切皆組件、儘可能減小代碼量、儘可能減小框架限制。html
Web components標準主要由如下3個部分組成:前端
Polymer的核心是Custom Elements,定義一個Polymer元素和定義一個普通的Custom Elements是差很少的。主要的區別就是Polymer使用polymer-element
標籤進行聲明。node
<polymer-element name="tag-name" constructor="TagName"> <template> <!-- 在這裏放置shadow DOM --> </template> <script>Polymer('tag-name');</script> </polymer-element>
Polymer在polymer-element
標籤上預留了一些特殊的attribute。數組
Attribute | 必要 | 描述 |
name | 是 | Polymer元素名,名稱中須要包含"-" |
attributes | 否 | 指定元素的Published properties |
extends | 否 | 指定元素繼承其它元素 |
noscript | 否 | 不須要調用Polymer()的簡單元素 |
constuctor | 否 | 放置在全局對象(如window )中的元素構造器名,容許用戶經過new 來新建此元素.(如: var tagName = new TagName() ) |
你在polymer-elemnet
上設置的其餘 attribute 將會自動添加到元素實例上。例如:瀏覽器
<polymer-element name="tag-name" class="active" mycustomattr> <template>...</template> <script>Polymer('tag-name');</script> </polymer-element>
當一個tag-name
實例被建立的時候,它就會自帶兩個默認 attribute : class="active"
和mycustomattr
。閉包
<tag-name class="active" mycustomattr></tag-name>
HTML解析器對 attribute 大小寫敏感是沒有必要的,可是Javascript卻對大小寫敏感。app
書寫時你能夠忽略屬性名的大小寫,可是當你運行並查看元素的屬性列表時,屬性名永遠都是小寫的,Polymer會謹慎的將* property* 和 attribute 一一配對。例如:框架
<name-tag nameColor="blue" name="Blue Name"></name-tag>
在DOM中nameColor
是小寫的,而且一般都會被忽略不處理。dom
下面例子也都會正常工做:
<name-tag NaMeCoLoR="blue" name="Blue Name"></name-tag> <name-tag NAMECOLOR="red" name="Red Name"></name-tag> <name-tag NAMEcolor="green" name="Green Name"></name-tag>
考慮到重構的須要,咱們有時候不會將腳本放置在元素標籤裏,而是獨立成一個文件。Polymer元素也能夠經過外部腳本中調用Polymer('tag-name')
來建立。
<!-- 1. 在元素聲明內部添加外部腳本 --> <polymer-element name="tag-name"> <template>...</template> <script src="path/to/tagname.js"></script> </polymer-element> <!-- 2. 在元素聲明以前添加外部腳本 --> <script src="path/to/tagname.js"></script> <polymer-element name="tag-name"> <template>...</template> </polymer-element> <!-- 3. 沒有腳本 --> <polymer-element name="tag-name" constructor="TagName" noscript> <template> <!-- shadow DOM here --> </template> </polymer-element>
元素也能夠只經過JS來註冊:
<script> Polymer('name-tag', {nameColor: 'red'}); var el = document.createElement('div'); el.innerHTML = '\ <polymer-element name="name-tag" attributes="name">\ <template>\ Hello <span style="color:{{nameColor}}">{{name}}</span>\ </template>\ </polymer-element>'; //若是不將這個元素聲明放入DOM內的話,custom elements的polyfill就找不到它。 document.body.appendChild(el); </script> <name-tag name="John"></name-tag>
須要注意的是,要將polymer-element
放入DOM中,這樣custom element
的polyfill才能找到它。
若是你想要定義一些方法或者 property 時(可選),在Polymer()的第二個參數中傳遞包含定義信息的對象便可。
下面這個例子中,定義了一個property: message
, 一個使用到了ES5 getter特性的property: greeting
, 還有一個方法:foo
。
<polymer-element name="tag-name"> <template></template> <script> Polymer('tag-name', { message: "Hello!", get greeting() { return this.message + ' there!'; }, foo: function() {...} }); </script> </polymer-element>
註釋: this是這個Polymer元素在本身內部他自己的引用。例如:this.localName == 'tag-name'.
注意: 當元素的property是一個js對象或者數組時須要注意,因爲prototype
的一些特性,你可能會在同一類元素的不一樣實體中,陷入shared state
問題。若是你想初始化一個property爲對象或者數組的時候,不要在prototype
中賦值,而應該在created
回調中賦值。
// 正確 Polymer('x-foo', { created: function() { this.list = []; // Initialize and hint type to be array. this.person = {}; // Initialize and hint type to an object. } }); // 錯誤 Polymer('x-foo', { list: [], // Don't initialize array or objects on the prototype. person: {} });
若是須要私有對象的話,將Polymer()放置在匿名自調函數裏便可。
<polymer-element name="tag-name"> <template>...</template> <script> (function() { // 只會運行一次 var foo_ = new Foo(); // 每個實例建立時都會運行 Polymer('tag-name', { get foo() { return foo_; } }); })(); </script> </polymer-element>
有時候你但願定義一個全局變量,而且在不一樣的元素中使用它。好比你會定義一個配置信息,而後在其它部件中引用這個配置。或者一個運動曲線用於處理不一樣的動畫效果,或者一個變量用於保存當前登陸用戶的信息。
你可使用MonoState Pattern來實現這個目標。當定義一個Polymer元素時,定義一個閉包,將須要的變量放入進去,而後在元素的prototype
上設置訪問器,或者在構造器裏把他們賦值到不一樣的實例上。
<polymer-element name="app-globals"> <script> (function() { var firstName = 'John'; var lastName = 'Smith'; Polymer('app-globals', { ready: function() { this.firstName = firstName; this.lastName = lastName; } }); })(); </script> </polymer-element>
而後像使用其餘元素同樣把它放置到另外一個元素聲明裏,將須要的property綁定到實例上,這樣就可使用Polymer的數據綁定技術來訪問它了。
<polymer-element name="my-component"> <template> <app-globals id="globals"></app-globals> <div id="firstname"></div> <div id="lastname"></div> </template> <script> Polymer('my-component', { ready: function() { this.globals = this.$.globals; } }); </script> </polymer-element>
只要作一些輕微的調整,就能夠在外部配置全局變量的值了。
<polymer-element name="app-globals"> <script> (function() { var values = {}; Polymer('app-globals', { ready: function() { for (var i = 0; i < this.attributes.length; ++i) { var attr = this.attributes[i]; values[attr.nodeName] = attr.nodeValue; } } }); })(); </script> </polymer-element>
在主頁中,專遞 attribute 就能夠配置全局變量了。
<app-globals firstName="Addy" lastName="Osmani"></app-globals>
Polymer對於元素聲明週期回調有着一流的支持,爲了方便,回調函數都用了簡短的名稱。
全部這些回調都是可選的:
Polymer('tag-name', { created: function() { ... }, ready: function() { ... }, attached: function () { ... }, domReady: function() { ... }, detached: function() { ... }, attributeChanged: function(attrName, oldVal, newVal) { //var newVal = this.getAttribute(attrName); console.log(attrName, 'old: ' + oldVal, 'new:', newVal); }, });
下面是custom elements和Polymer元素的生命週期方法的對照表:
Custom Elements | Polymer | 觸發條件 |
createdCallback | created | 一個元素的實例被建立 |
- | ready | polymer-element 已經徹底準備好。(例如:shadow DOM建立完成,事件已綁定等等) |
attachedCallback | attached | 當一個元素的實例被插入到DOM中 |
- | domReady | Called when the element’s initial set of children are guaranteed to exist. This is an appropriate time to poke at the element’s parent or light DOM children. Another use is when you have sibling custom elements (e.g. they’re .innerHTML‘d together, at the same time). Before element A can use B’s API/properties, element B needs to be upgraded. The domReady callback ensures both elements exist. |
detachedCallback | detached | 當實例從DOM中移除 |
attributeChangedCallback | attributeChanged | attribute被添加移除或者改變。注意: 要監聽一個公開的property,應該使用 changed watchers |
Polymer經過異步的方式來處理自定義元素定義和升級。若是你在元素尚未升級的時候,就經過DOM來獲取它,你只會獲得一個HTMLUnknownElement
。Polymer元素有時還會使用外部元素,例如css,若是他們尚未徹底加載完畢,就可能引發FOUC的問題。爲了不FOUC,Polymer只有在css等資源所有加載完畢以後纔會註冊元素。
經過polymer-ready事件就能夠得知元素什麼時候註冊/升級完。
<head> <link rel="import" href="path/to/x-foo.html"> </head> <body> <x-foo></x-foo> <script> window.addEventListener('polymer-ready', function(e) { var xFoo = document.querySelector('x-foo'); xFoo.barProperty = 'baz'; }); </script> </body>