JavaScript绑定事件

时间:2016-08-14 05:53:12

标签: javascript

当我点击li element时,我想将点击事件添加到我页面中的所有li elementli element的内容将显示在input element中,最后,我想取消绑定click事件。我写了两个方法来解决这个问题,但是其中一个方法无法取消绑定click事件,所以我想知道为什么click事件无法解除绑定。



<div class="wraper">
    <div>
      <input type="text" id="name" /><button> < </button>
    </div>
    <ul>
      <li>Napoleon</li>
      <li>覃小夫</li>
      <li>毛泽东</li>
      <li>戴高乐</li>
      <li>戴高乐</li>
      <li>戴高乐</li>

    </ul>
 </div>
&#13;
&#13;
&#13;

这是我解决问题的第一种方法,但最后我无法解除li elementbutton element点击事件的绑定。

&#13;
&#13;
var select = (function() {
  var obj = {
    Ulshow : false,
    init : function() {
      this.cacheDOM();
      this.bindEvent();
    },
    cacheDOM : function() {
      var doc = document;
      this.ul =doc.querySelector( '.wraper ul' );
      this.button = doc.querySelector( '.wraper button');
      this.input = doc.querySelector( '.wraper input');
    },
    bindEvent : function() {
      this.button.addEventListener( 'click', this.toggleUl.bind( this ), false );
      this.ul.addEventListener( 'click', this.selectLi.bind( this ), false );
    },
    toggleUl : function() {
      var display = this.Ulshow ? 'none' : 'block';
      this.ul.style.display = display;
      this.Ulshow = !this.Ulshow;
    },
    selectLi : function( e ) {
      if ( e.target.tagName.toLowerCase() !== 'li' )
        return;
      this.input.value = e.target.innerHTML;
      //hide the ul element
      this.toggleUl();
    },
    unbindEvent : function() {
      this.button.removeEventListener( 'click', this.toggleUl, false );
      this.ul.removeEventListener( 'click', this.selectLi, false );
    }
  };

  obj.init();

  //invoke the unbindEvent function to unbind click event
  //But I found I can not unbind the click event, that's my problem.
  obj.unbindEvent();
  return obj;

})();
&#13;
&#13;
&#13;

这是第二种方法,我用它来解决我的问题(问题是我无法取消绑定点击事件),它可以工作,我可以解除li element和{{1}中的点击事件那么我想知道这两种方法之间的区别,我想知道为什么我不能在第一种方法中取消绑定click事件。

&#13;
&#13;
button element
&#13;
&#13;
&#13;

1 个答案:

答案 0 :(得分:-1)

  

bind()方法创建一个新函数    - MDN

函数和绑定函数是不同的对象;每次调用<form method="post" action="process.php"> 时都会返回一个新函数和引用:

bind

因此,this.toggleUl !== this.toggleUl.bind(this) this.toggleUl.bind(this) !== this.toggleUl.bind(this)

obj.unbindEvent

引用的this.button.removeEventListener( 'click', this.toggleUl, false ); EventListener中添加的obj.bindEvent不同:

this.button.addEventListener( 'click', this.toggleUl.bind( this ), false );

解决这个问题的方法是:

var obj = {
  init : function(){
    this.bindCallbacks();
    this.cacheDOM();
    this.bindEvent();
  },
  ...
  bindCallbacks : function(){
    this.toggleUlBound = this.toggleUl.bind(this);
    this.selectLiBound = this.selectLi.bind(this);
  },
  ...
  bindEvent : function(){
    this.button.addEventListener( 'click', this.toggleUlBound, false );
    ...
  }
  unbindEvent : function(){
    this.button.removeEventListener( 'click', this.toggleUlBound, false );
    ...
  }
  ...(etc)...
}

演示:also as a fiddle

&#13;
&#13;
var select = (function() {
  var obj = {
    Ulshow : false,
    init : function() {
      this.bindCallbacks();
      this.cacheDOM();
      this.bindEvent();
    },
    bindCallbacks : function(){
      this.toggleUlBound = this.toggleUl.bind(this);
      this.selectLiBound = this.selectLi.bind(this);
    },    
    cacheDOM : function() {
      var doc = document;
      this.ul =doc.querySelector( '.wraper ul' );
      this.button = doc.querySelector( '.wraper button');
      this.input = doc.querySelector( '.wraper input');
    },
    bindEvent : function() {
      this.button.addEventListener( 'click', this.toggleUlBound, false );
      this.ul.addEventListener( 'click', this.selectLiBound, false );
    },
    toggleUl : function() {
      var display = this.Ulshow ? 'none' : 'block';
      this.ul.style.display = display;
      this.Ulshow = !this.Ulshow;
    },
    selectLi : function( e ) {
      if ( e.target.tagName.toLowerCase() !== 'li' )
        return;
      this.input.value = e.target.innerHTML;
      //hide the ul element
      this.toggleUl();
    },
    unbindEvent : function() {
      this.button.removeEventListener( 'click', this.toggleUlBound, false );
      this.ul.removeEventListener( 'click', this.selectLiBound, false );
    }
  };
 
  obj.init();
  obj.unbindEvent();
  return obj;

})();
&#13;
<div class="wraper">
    <div>
      <input type="text" id="name" /><button> < </button>
    </div>
    <ul>
      <li>Napoleon</li>
      <li>覃小夫</li>
      <li>毛泽东</li>
      <li>戴高乐</li>
      <li>戴高乐</li>
      <li>戴高乐</li>

    </ul>
 </div>
&#13;
&#13;
&#13;

更简单的方法是在声明 obj之后,在调用obj.init之前进行绑定,直接引用obj:< / p>

var obj = { ... };
obj.toggleUl = obj.toggleUl.bind(obj);
obj.selectLi = obj.selectLi.bind(obj);
obj.init();
...

在这种方法中,你应该再次避免在addEventListener中绑定你的函数,这会留下你无法在removeEventListener中重复使用的未捕获的引用。

但最简单的方法是你找到的方法:不要使用对象 - 文字语法来完成这项工作!