聚合物:检测自定义元素之外的点击

Polymer: Detect click outside of custom element

我有一个自定义元素,想检测它之外的点击。例如

<dom-module id="simple-element">



<style>
  </style>

  <template>
    <content></content>
  </template>

</dom-module>

<script>
  (function() {
    Polymer({
      is: 'simple-element',
      listeners: {
        'tap': 'regularTap'
      },
      regularTap: function() {
        console.log("i was tapped");
      }
    });
  })();
</script>

是否有我可以收听的事件,它会在用户单击元素外部时告诉我?谢谢

按照这些思路应该可以满足您的要求:

window.addEventListener('click', (e) => {
  var target = event.target;

  while(target != this && target != document.body) {
    target = Polymer.dom(target).node.domHost.parentNode;
    // might need some additional steps to get the parent from inside custom elements
    // don't know by heart
  }
  if(target == this) {
    // inside element
  } else {
    // outside element
  }
});

修改了代码,使其真正起作用:

var that = this;

window.addEventListener("click", function(e){
    var target = e.target;

    while (target != that && target != document.body) {
        target = Polymer.dom(target).node.parentElement;
    }

    if (target == that) {
         console.log("inside element");
    } else {
         console.log("outside element");
    }
});

您可以使用这样的行为:

    <script>
      /** @polymerBehavior Polymer.HarleyClickOutsideBehavior */
      Polymer.HarleyClickOutsideBehavior = {

        ready: function () {
          // bind listener method
          this.clickOutsideListenerBinded = this._clickOutsideListener.bind(this)
        },

        detached: function () {
          this._clickOutsideUnlisten()
        },

        clickOutsideListen: function () {
          // run this method to start listening
          this._clickOutsideUnlisten()
          window.addEventListener('click', this.clickOutsideListenerBinded, false)
        },

        _clickOutsideUnlisten: function () {
          window.removeEventListener('click', this.clickOutsideListenerBinded, false)
        },

        _clickOutsideListener: function (ev) {
          // check if the user has clicked on my component or on my children
          var isOutside = !ev.path.find(function (path) {
            return path === this
          }.bind(this))
          if (isOutside) {
            this.onClickOutside()
            this._clickOutsideUnlisten()
          }
        },

        onClickOutside: function () {
          // overwrite this method to be notified
        }

      }
    </script>

我发现一个更简单的解决方案尚未在所有浏览器上进行测试,但很有意义。因此,我向 window 添加了一个全局侦听器,并为自定义元素添加了一个侦听器。这样点击里面会调用两者,点击外面只会调用全局..

listenToClickOutside() {
            this.addEventListener("click", thisClick, false);
            window.addEventListener("click", windowClick, false);

            var clicksInside = 0;
            var thisRef = this;

            function thisClick() {
                clicksInside++
            }

            function windowClick(event) {
                clicksInside--;
                if (clicksInside < 0) {
                    thisRef.removeEventListener("click", thisClick, false);
                    window.removeEventListener("click", windowClick, false);
                    // CLICKED outside
                }
            }
        }