Skip to content

Instantly share code, notes, and snippets.

@kaelfeitosa
Created April 9, 2016 22:28
Show Gist options
  • Save kaelfeitosa/124cbc443fd58877ffb763963f1521e6 to your computer and use it in GitHub Desktop.
Save kaelfeitosa/124cbc443fd58877ffb763963f1521e6 to your computer and use it in GitHub Desktop.

WEB Components

DOM

Document Object Model é uma convenção multiplataforma e independente de linguagem para representação e interação com objetos em documentos HTML, XHTML e XML.

<button>Oi, eu sou um botão!</button>
document
document.constructor.name
var button = document.querySelector('button')
a.constructor.name
a.textContent = 'Olá, maravilhosos!'

Elementos tem atributos, propriedades, métodos e eventos

<button disabled="true">Oi, eu sou um botão!</button>

<script>
  var button = document.querySelector(`button`)
  button.addEventListener('click', function() {
    alert('Oxe!')
  })
</script>

Elementos simples e complexos

<video src="http://www.w3schools.com/tags/movie.mp4" controls>
</video>

Interface para mediação

<label>0</label>
<button>eu quero mais!</button>

<script>
  var button = document.querySelector('button');
  var label = document.querySelector('label');
  var count = 0;
  button.addEventListener('click', function() {
    count = count + 1;
    label.textContent = count;
  })
</script>

WEB Components

Permite definir componentes funcionais, isolados e reutilizáveis

  • Shadown DOM
<input value="Me preencha"></input>
<video src="http://www.w3schools.com/tags/movie.mp4" controls>
</video>
  • Custom Elements
var wantMore = document.registerElement('want-more', {
  prototype: {
    count: 0,
    sum: function() {
      //implementation
    }
  }
});
  • Templates
<template id="template">
  <style>
  </style>
  <div id="container">
    <label>Oi,</label>
    <button>Me aperta!</button>
  </div>
</template>
  • HTML Imports
<link rel="import" href="/my/litle/element.html">

Criando um elemento

<template>
  <label>0</label>
  <button>Quero Mais!</button>
</template>

<script>  
  var prototype = Object.create(HTMLElement.prototype);

  prototype.createdCallback = function() {
    var template = document.querySelector('template');
    var clone = document.importNode(template.content, true);

    var root = this.createShadowRoot();
    root.appendChild(clone);
  }

  document.registerElement('want-more', {
    prototype: prototype
  });
</script>

<want-more></want-more>

Adicionado comportamento

<template>
  <label>0</label>
  <button>Quero Mais!</button>
</template>

<script>  
  var prototype = Object.create(HTMLElement.prototype);

  prototype.createdCallback = function() {
    var template = document.querySelector('template');
    var clone = document.importNode(template.content, true);

    var root = this.createShadowRoot();
    root.appendChild(clone);

    //adicionando comportamento
    var button = root.querySelector('button');
    var label = root.querySelector('label');
    var count = 0;
    button.addEventListener('click', function() {
      count = count + 1;
      label.textContent = count;
    });
  }

  document.registerElement('want-more', {
    prototype: prototype
  });
</script>

<want-more></want-more>

Usando HTML Import

<template>
  <label>0</label>
  <button>Quero Mais!</button>
</template>

<script>
  var prototype = Object.create(HTMLElement.prototype);

  prototype.createdCallback = function() {
    // usando dom original
    var innerDocument = document.querySelector('link[rel="import"]').import;
    var template = innerDocument.querySelector('template');

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

    var root = this.createShadowRoot();
    root.appendChild(clone);

    var button = root.querySelector('button');
    var label = root.querySelector('label');
    var count = 0;
    button.addEventListener('click', function() {
      count = count + 1;
      label.textContent = count;
    });
  }

  document.registerElement('want-more', {
    prototype: prototype
  });
</script>
<link rel="import" href="want-more.html">
<want-more></want-more>

Propriedade

<template>
  <label>0</label>
  <button>Quero Mais!</button>
</template>

<script>
  var prototype = Object.create(HTMLElement.prototype);
  var label;

  prototype.createdCallback = function() {
    // usando dom original
    var innerDocument = document.querySelector('link[rel="import"]').import;
    var template = innerDocument.querySelector('template');

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

    var root = this.createShadowRoot();
    root.appendChild(clone);

    var button = root.querySelector('button');
    label = root.querySelector('label');
    button.addEventListener('click', function() {
      this.count = this.count + 1;
      label.textContent = this.count;
    }.bind(this));
  }

  prototype.count = 0;

  Object.defineProperty(prototype, 'count', {
    set: function (x) {
      this.count = x;
      label.textContent = this.count;
    }
  });

  document.registerElement('want-more', {
    prototype: prototype
  });
</script>

Propriedade com setter

<template>
  <label>0</label>
  <button>Quero Mais!</button>
</template>

<script>
  var prototype = Object.create(HTMLElement.prototype);
  var label;
  var count = 0;

  prototype.createdCallback = function() {
    // usando dom original
    var innerDocument = document.querySelector('link[rel="import"]').import;
    var template = innerDocument.querySelector('template');

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

    var root = this.createShadowRoot();
    root.appendChild(clone);

    var button = root.querySelector('button');
    label = root.querySelector('label');
    button.addEventListener('click', function() {
      count = count + 1;
      label.textContent = count;
    }.bind(this));
  }

  Object.defineProperty(prototype, 'count', {
    set: function (x) {
      count = x;
      label.textContent = count;
    }
  });

  document.registerElement('want-more', {
    prototype: prototype
  });
</script>

Polymer

The Polymer library is designed to make it easier and faster for developers to create great, reusable components for the modern web.

  • Sintaxe declarativa para definir elementos
  • Template helpers
  • Data binding
  • Elementos customizados

Elemento com polymer

<link rel="import" href="http://www.polymer-project.org/1.0/components/polymer/polymer.html">

<dom-module id="want-more">
  <template>
    <label>0</label>
    <button>Quero Mais!</button>
  </template>

  <script>
    Polymer({
      is: "want-more"
    });
  </script>
</dom-module>

Adicionando comportamento

<link rel="import" href="http://www.polymer-project.org/1.0/components/polymer/polymer.html">

<dom-module id="want-more">
  <template>
    <label>0</label>
    <button>Quero Mais!</button>
  </template>

  <script>
    Polymer({
      is: "want-more",

      ready: function() {
        var button = this.querySelector('button');
        var label = this.querySelector('label');
        var count = 0;

        button.addEventListener('click', function() {
          count = count + 1;
          label.textContent = count;
        }.bind(this));

        Object.defineProperty(this, 'count', {
          set: function (x) {
            count = x;
            label.textContent = count;
          }
        });
      }
    });
  </script>
</dom-module>

Auto descobrimento

<link rel="import" href="http://www.polymer-project.org/1.0/components/polymer/polymer.html">

<dom-module id="want-more">
  <template>
    <label id="label">0</label>
    <button id="button">Quero Mais!</button>
  </template>

  <script>
    Polymer({
      is: "want-more",

      ready: function() {
        var count = 0;

        this.$.button.addEventListener('click', function() {
          count = count + 1;
          this.$.label.textContent = count;
        }.bind(this));

        Object.defineProperty(this, 'count', {
          set: function (x) {
            count = x;
            this.$.label.textContent = count;
          }
        });
      }
    });
  </script>
</dom-module>

Propriedades

<link rel="import" href="http://www.polymer-project.org/1.0/components/polymer/polymer.html">

<dom-module id="want-more">
  <template>
    <label id="label">0</label>
    <button id="button">Quero Mais!</button>
  </template>

  <script>
    Polymer({
      is: "want-more",

      properties: {
        count: {
          type: Number,
          value: 0,
          observer: '_countChanged'
        }
      },

      ready: function() {
        this.$.button.addEventListener('click', function() {
          this.count = this.count + 1;
          this.$.label.textContent = this.count;
        }.bind(this));
      },

      _countChanged: function(value) {
        this.$.label.textContent = this.count;
      }
    });
  </script>
</dom-module>

Event listeners

<link rel="import" href="http://www.polymer-project.org/1.0/components/polymer/polymer.html">

<dom-module id="want-more">
  <template>
    <label id="label">0</label>
    <button id="button" on-click="_handleClick">Quero Mais!</button>
  </template>

  <script>
    Polymer({
      is: "want-more",

      properties: {
        count: {
          type: Number,
          value: 0,
          observer: '_countChanged'
        }
      },

      ready: function() {
      },

      _countChanged: function(value) {
        this.$.label.textContent = this.count;
      },

      _handleClick: function() {
        this.count = this.count + 1;
        this.$.label.textContent = this.count;
      }
    });
  </script>
</dom-module>

Data binding

<link rel="import" href="http://www.polymer-project.org/1.0/components/polymer/polymer.html">

<dom-module id="want-more">
  <template>
    <label id="label">{{count}}</label>
    <button id="button" on-click="_handleClick">Quero Mais!</button>
  </template>

  <script>
    Polymer({
      is: "want-more",

      properties: {
        count: {
          type: Number,
          value: 0
        }
      },

      ready: function() {
      },

      _handleClick: function() {
        this.count = this.count + 1;
      }
    });
  </script>
</dom-module>
<link rel="import" href="http://www.polymer-project.org/1.0/components/polymer/polymer.html">

<dom-module id="want-more">
  <template>
    <label id="label">[[count]]</label>
    <button id="button" on-click="_handleClick">Quero Mais!</button>

    <input value="{{count::change}}"></input>
  </template>

  <script>
    Polymer({
      is: "want-more",

      properties: {
        count: {
          type: Number,
          value: 0
        }
      },

      ready: function() {
      },

      _handleClick: function() {
        this.count = this.count + 1;
      }
    });
  </script>
</dom-module>

Helpers

1

<link rel="import" href="http://www.polymer-project.org/1.0/components/polymer/polymer.html">

<dom-module id="want-more">
  <template>
    <label id="label">{{count}}</label>
    <button id="button" on-click="_handleClick">Quero Mais!</button>

    <template is="dom-if" if="{{count}}">
      <label>começou</label>
    </template>

    <template is="dom-repeat" items="{{_stars(count)}}">
      <label>🌟</label>
    </template>
  </template>

  <script>
    Polymer({
      is: "want-more",

      properties: {
        count: {
          type: Number,
          value: 0
        }
      },

      ready: function() {
      },

      _handleClick: function() {
        this.count = this.count + 1;
      },

      _stars(count) {
        return new Array(count)
      }
    });
  </script>
</dom-module>

2

<link rel="import" href="want-more.html">

<want-more></want-more>
<input></input>

<script>
  var input = document.querySelector('input');
  input.addEventListener('change', function() {
    document.querySelector('want-more').count = input.value
  })
</script>
<link rel="import" href="http://www.polymer-project.org/1.0/components/polymer/polymer.html">

<dom-module id="want-more">
  <template>
    <label id="label">[[count]]</label>
    <button id="button" on-click="_handleClick">Quero Mais!</button>
  </template>

  <script>
    Polymer({
      is: "want-more",

      properties: {
        count: {
          type: Number,
          value: 0
        }
      },

      ready: function() {
      },

      _handleClick: function() {
        this.count = this.count + 1;
      }
    });
  </script>
</dom-module>

3

<link rel="import" href="http://www.polymer-project.org/1.0/components/polymer/polymer.html">
<link rel="import" href="want-more.html">

<body>
  <template is="dom-bind" id="app">
    <want-more count="[[count]]"></want-more>
    <input value="{{count::change}}"></input>
  </template>
</body>

4

<link rel="import" href="http://www.polymer-project.org/1.0/components/polymer/polymer.html">
<link rel="import" href="want-more.html">

<body>
  <template is="dom-bind" id="app">
    <want-more count="{{count}}"></want-more>
    <input value="{{count::change}}"></input>
  </template>
</body>
<link rel="import" href="http://www.polymer-project.org/1.0/components/polymer/polymer.html">

<dom-module id="want-more">
  <template>
    <label id="label">[[count]]</label>
    <button id="button" on-click="_handleClick">Quero Mais!</button>
  </template>

  <script>
    Polymer({
      is: "want-more",

      properties: {
        count: {
          type: Number,
          value: 0,
          notify: true
        }
      },

      ready: function() {
      },

      _handleClick: function() {
        this.count = this.count + 1;
      }
    });
  </script>
</dom-module>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment