Polymer API開發指南 (一)(翻譯)

翻譯的很差,輕拍css

Polymer是google的一款前端開發框架,其基於Shadow DOM、Custom Elements、MDV等最新瀏覽器特性構建,表明了下一代Web框架的方向:一切皆組件、儘可能減小代碼量、儘可能減小框架限制。html

名詞解釋

  • Attribute: 元素聲明或者建立時須要的屬性。
  • Property: 屬性、元素或者類向外提供的數據區域,例如js對象的屬性。
  • Polyfill: 指的是經過第三方腳本對老舊瀏覽器進行的修補,經過這些修補使之可以支持新瀏覽器的特性。

Web components標準主要由如下3個部分組成:前端

  • Custom Elements
  • Shadow DOM
  • HTML Imports

元素聲明

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>

Attrubtes

Polymer在polymer-element標籤上預留了一些特殊的attribute數組

Attribute 必要 描述
name Polymer元素名,名稱中須要包含"-"
attributes 指定元素的Published properties
extends 指定元素繼承其它元素
noscript 不須要調用Polymer()的簡單元素
constuctor 放置在全局對象(如window)中的元素構造器名,容許用戶經過new來新建此元素.(如: var tagName = new TagName()

默認 Attribute

你在polymer-elemnet上設置的其餘 attribute 將會自動添加到元素實例上。例如:瀏覽器

<polymer-element name="tag-name" class="active" mycustomattr>
  <template>...</template>
  <script>Polymer('tag-name');</script>
</polymer-element>

當一個tag-name實例被建立的時候,它就會自帶兩個默認 attributeclass="active"mycustomattr閉包

<tag-name class="active" mycustomattr></tag-name>

Attribute大小寫

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和方法

若是你想要定義一些方法或者 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: {}
});

添加私有或者靜態property

若是須要私有對象的話,將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-ready 事件

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>
相關文章
相關標籤/搜索