如何在 Polymer 1.0 中使用突变观察器

how to use mutation observers in polymer 1.0

我找不到关于如何使用属于 webcomponents.js polyfill 的突变观察器的文档。能举个例子吗

我想观察快照中指向的元素的变化。

MutationObserver 在 polyfill (webcomponents.js) 下的工作方式与原生相同或非常接近。 You can learn more about MutationObserver here.

您可以在自定义元素 (data-tree) 的 ready 函数中设置 MutationObserver。如果您想观察调用 ready 函数后添加的元素的变化,您应该在添加元素后 setup/re-setup MutationObserver


ready 函数中的 MutationObserver 示例:

ready: function () {                    
    var mutationHandler = function (mutation) {
        var newValue = mutation.target.getAttribute("filters");
        var oldValue = mutation.oldValue;

        // filterList is a method on the element's (data-tree) prototype.
        this.filterList(mutation.target, newValue, oldValue);
    }.bind(this);

    var observerCallback = function (mutations) {
        mutations.forEach(mutationHandler);
    };

    var mutationObserver = new MutationObserver(observerCallback);

    // You can change the querySelectorAll to select other elements or narrow the results.
    // For example, Polymer.dom(this.root).querySelector("#all > li:nth-child(1)");
    var targetNodes = Polymer.dom(this.root).querySelectorAll("li");    
    targetNodes.forEach(function (targetNode) {
        mutationObserver.observe(targetNode, {
            attributes: true,
            attributeOldValue: true,
            attributeFilter: ["filters"]
        });
    });
}


下面是一个使用问题图像中的一些代码的工作示例。

<script src="http://www.polymer-project.org/1.0/samples/components/webcomponentsjs/webcomponents.min.js"></script>
<link rel="import" href="http://www.polymer-project.org/1.0/samples/components/polymer/polymer.html">
<link rel="import" href="bower_components/iron-icons/iron-icons.html" />
<link rel="import" href="bower_components/paper-fab/paper-fab.html" />
<dom-module id="data-tree">
  <style>
    :host {
      font-family: "Segoe UI Semilight", "Segoe UI", "Segoe", Tahoma, Helvetica, Arial, sans-serif;
      font-size: 15px;
    }
    paper-fab {
      border-radius: 5px;
      height: 2px;
      transform: scale(0.5);
      width: 1px;
    }
    ul {
      list-style-type: none;
    }
    li {
      margin: 20px;
    }
    li span {
      padding: 20px 10px;
    }
    .toggler {
      background: #9b9b9b;
    }
    .hidden ul {
      display: none;
    }
    /deep/ paper-material[elevation="1"].paper-material-0 {
      box-shadow: none;
    }
    /deep/ paper-material[elevation="1"].paper-material-0:hover {
      box-shadow: 0px 2px 2px 0px rgba(0, 0, 0, 0.14), 0px 1px 5px 0px rgba(0, 0, 0, 0.12), 0px 3px 1px -2px rgba(0, 0, 0, 0.2);
    }
  </style>
  <template>
    <div id="tree-container">
      <ul id="all">
        <li>
          <paper-fab icon="remove" class="toggler"></paper-fab>All
          <ul id="plants">
            <li>
              <paper-fab icon="remove" class="toggler"></paper-fab>Plants
              <ul id="plant-types"></ul>
            </li>
          </ul>
        </li>
      </ul>
    </div>
    <div id="mutation-record">
      <div>
        Current <em>filters</em> attribute: <strong id="new-value"></strong>
      </div>
      <div>
        Old <em>filters</em> attribute: <strong id="old-value"></strong>
      </div>
    </div>
  </template>
  <script>
    Polymer({
      is: "data-tree",
      ready: function() {
        var mutationHandler = function(mutation) {
          var newValue = mutation.target.getAttribute("filters");
          var oldValue = mutation.oldValue;

          this.filterList(mutation.target, newValue, oldValue);
        }.bind(this);

        var observerCallback = function(mutations) {
          mutations.forEach(mutationHandler);
        };

        var mutationObserver = new MutationObserver(observerCallback);

        // You can change the querySelectorAll to select other elements or narrow the results.
        // For example, Polymer.dom(this.root).querySelector("#all > li:nth-child(1)");
        var targetNodes = Polymer.dom(this.root).querySelectorAll("li");
        targetNodes.forEach(function(targetNode) {
          mutationObserver.observe(targetNode, {
            attributes: true,
            attributeOldValue: true,
            attributeFilter: ["filters"]
          });
        });
      },
      filterList: function(target, newValue, oldValue) {
        console.log(target);
        this.$["new-value"].textContent = newValue;
        this.$["old-value"].textContent = oldValue;
      }
    });
  </script>
</dom-module>
<data-tree></data-tree>
<input type="text" />
<button>Set Attribute</button>
<script>
  document.querySelector("button").addEventListener("click", function() {
    var dataTree = Polymer.dom(document.querySelector("data-tree").root);
    var li = dataTree.querySelector("#all > li:nth-child(1)");
    li.setAttribute("filters", document.querySelector("input").value);
  });
</script>