Home Start Get started Build an element 1. Get set up 2. Add local DOM 3. Data binding & properties 4. React to input 5. Theming with custom properties Build an app 1. Get set up 2. Create a new page 3. Add some elements 4. Deploy Polymer Feature overview Quick tour Define elements Register an element Declare properties Instance methods Behaviors Local DOM & styling Local DOM Styling Events Handle and fire events Gesture events Data system Data system concepts Work with object and array data Observers and computed properties Data binding Helper elements Tools Tools overview Polymer CLI Document your elements Test your elements Optimize for production Publish an element Advanced tools Services What's new Release notes 1.0 Migration guide About Polymer 1.0 Resources Community Browser compatibility API Reference Polymer.Base array-selector custom-style dom-bind dom-if dom-repeat dom-template Polymer.Templatizer Global settings 2.0 Preview About Polymer 2.0 Upgrade guide App Toolbox What's in the box? Using the Toolbox App templates Responsive app layout Routing Localization App storage Service worker Serve your app Case study Shop Elements News Feature overview Quick tour
Define elements
Register an element Declare properties Instance methods Behaviors
Local DOM & styling
Local DOM Styling
Events
Handle and fire events Gesture events
Data system
Data system concepts Work with object and array data Observers and computed properties Data binding Helper elements
Tools
Tools overview Polymer CLI Document your elements Test your elements Optimize for production Publish an element Advanced tools Services
What's new
Release notes 1.0 Migration guide About Polymer 1.0
Resources
Community Browser compatibility
API Reference
Polymer.Base array-selector custom-style dom-bind dom-if dom-repeat dom-template Polymer.Templatizer Global settings

Polymer supports extending custom element prototypes with shared code modules called behaviors.

A behavior is an object that looks similar to a typical Polymer prototype. A behavior can define lifecycle callbacks, declared properties, default attributes, observers, and event listeners.

To add a behavior to a Polymer element definition, include it in a behaviors array on the prototype.

Polymer({
  is: 'super-element',
  behaviors: [SuperBehavior]
});

For lifecycle events, the lifecycle callback is called for each behavior in the order given in the behaviors array, followed by the callback on the prototype.

Any non-lifecycle functions on the behavior object are mixed into the base prototype, unless the prototype already defines a function of the same name. If multiple behaviors define the same function, the last behavior in the behaviors array takes precedence over other behaviors.

To define a behavior, create a JavaScript object that you can reference from your element definition. The following example simply adds HighlightBehavior to the global scope:

highlight-behavior.html:

<script>
    HighlightBehavior = {

      properties: {
        isHighlighted: {
          type: Boolean,
          value: false,
          notify: true,
          observer: '_highlightChanged'
        }
      },

      listeners: {
        click: '_toggleHighlight'
      },

      created: function() {
        console.log('Highlighting for ', this, 'enabled!');
      },

      _toggleHighlight: function() {
        this.isHighlighted = !this.isHighlighted;
      },

      _highlightChanged: function(value) {
        this.toggleClass('highlighted', value);
      }

    };
</script>

my-element.html:

<link rel="import" href="highlight-behavior.html">

<script>
  Polymer({
    is: 'my-element',
    behaviors: [HighlightBehavior]
  });
</script>

Polymer doesn't specify any particular method for referencing your behaviors. Behaviors created by the Polymer team are added to the Polymer object. When creating your own behaviors, you should use some other namespace to avoid collisions with future Polymer behaviors. For example:

window.MyBehaviors = window.MyBehaviors || {};
MyBehaviors.HighlightBehavior = { ... }

Here the MyBehaviors namespace is explicitly added to the global window object, so the behavior can be referenced from your elements as MyBehaviors.HighlightBehavior.

To extend a behavior, or create a behavior that includes an existing behavior, you can define a behavior as an array of behaviors:

<!-- import an existing behavior -->
<link rel="import" href="oldbehavior.html">

<script>
  // Implement the extended behavior
  NewBehaviorImpl = {
    // new stuff here
  }

  // Define the behavior
  NewBehavior = [ OldBehavior, NewBehaviorImpl ]
</script>

As with the element's behaviors array, the rightmost behavior takes precedence over behaviors earlier in the array. In this case, anything defined in NewBehaviorImpl takes precedence over anything defined in OldBehavior.

Naming each element in the behavior array is a good practice, since it allows behaviors to explicitly reference methods on the behaviors they extend (for example, NewBehaviorImpl can call to methods on OldBehavior).

In some cases, a behavior may need to perform one-time work when an element is registered. For example, to allocate a shared object accessed by all element instances, or to modify the element prototype.

For example, iron-a11y-keys-behavior allows elements and other behaviors to add bindings by specifying a keyBindings object on the prototype. A single element could potentially have multiple keyBindings objects, one from its own prototype and several inherited from behaviors. The iron-a11y-keys-behavior uses the registered callback to collate these keyBindings objects into a single object on the element's prototype.

The following simplified example demonstrates how iron-a11y-keys-behavior collates objects from multiple behaviors.

registered: function() {
  // collate keyBindings objects from behaviors & element prototype
  var keyBindings = this.behaviors.map(function(behavior) {
    return behavior.keyBindings;
  });
  if (keyBindings.indexOf(this.keyBindings) === -1) {
    keyBindings.push(this.keyBindings);
  }
  // process key bindings in order
  keyBindings.forEach(function() {
    ...
  });
}