首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >JavaScript绑定事件

JavaScript绑定事件
EN

Stack Overflow用户
提问于 2016-08-14 05:53:11
回答 1查看 6.9K关注 0票数 1

当我单击li element时,我希望将单击事件添加到页面中的所有li element中,li element的内容将显示在input element中,最后,我希望解除对单击事件的绑定。我已经写了两种方法来解决这个问题,但是其中一种方法不能解除点击事件,所以我想知道为什么点击事件不能解除绑定。

代码语言:javascript
复制
<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>

这是我解决这个问题的第一个方法,但最后我无法从li elementbutton element中解除click事件的绑定。

代码语言:javascript
复制
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;

})();

这里是第二种方法,我使用它来解决我的问题(问题是我不能解除对单击事件的绑定),它可以工作,我可以从li elementbutton element.So中解除单击事件--我想知道这两种方法之间的区别,并且我想知道为什么我不能在我的第一种方法中解除对单击事件的绑定。

代码语言:javascript
复制
var selected = (function(){
  var doc = document;
  var DOM = {
    Ulshow : false,
    button : doc.querySelector( '.wraper button' ),
    input : doc.querySelector( '.wraper input' ),
    ul : doc.querySelector( '.wraper ul' )
  }

  function toggleUl() {
    var display = DOM.Ulshow ? 'none' : 'block';
    DOM.ul.style.display = display;
    DOM.Ulshow = !DOM.Ulshow;
  }

  function selectLi( e ) {
    if ( e.target.tagName.toLowerCase() !== 'li' )
      return;
    DOM.input.value = e.target.innerHTML;
    toggleUl();
  }

  function bindEvent() {
    DOM.button.addEventListener( 'click', toggleUl, false );
    DOM.ul.addEventListener( 'click', selectLi, false );
  }

  function unbindEvent() {
    DOM.button.removeEventListener( 'click', toggleUl, false );
    DOM.ul.removeEventListener( 'click', selectLi, false );
  }

  function init() {
    bindEvent();
  }

  init();

  return {
    unbindEvent : unbindEvent
  };
})();

//Now I can invoke the selected.unbindEvent function to unbind click event
seleted.unbindEvent();

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2016-08-14 06:51:31

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

函数和绑定函数是不同的对象;每次调用bind都会返回一个新函数和引用。

代码语言:javascript
复制
this.toggleUl !==  this.toggleUl.bind(this)
this.toggleUl.bind(this) !== this.toggleUl.bind(this)

因此,obj.unbindEvent

代码语言:javascript
复制
this.button.removeEventListener( 'click', this.toggleUl, false );

引用的是与在EventListener中添加的不同的obj.bindEvent

代码语言:javascript
复制
this.button.addEventListener( 'click', this.toggleUl.bind( this ), false );

绕过这一切的一种方法是这样的:

代码语言:javascript
复制
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)...
}

演示: (也是小提琴)

代码语言:javascript
复制
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;

})();
代码语言:javascript
复制
<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>

一种更简单的方法是在声明obj之后,在调用obj.init之前,当您可以直接引用obj时,执行绑定:

代码语言:javascript
复制
var obj = { ... };
obj.toggleUl = obj.toggleUl.bind(obj);
obj.selectLi = obj.selectLi.bind(obj);
obj.init();
...

在这种方法中,您应该再次避免将您的函数绑定到addEventListener中,这将给您留下一个无法在removeEventListener中重用的未捕获的引用。

但是最简单的方法就是你找到的方法:不要为这项工作使用对象-字面语法!

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/38939569

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档