当我单击li element时,我希望将单击事件添加到页面中的所有li element中,li element的内容将显示在input element中,最后,我希望解除对单击事件的绑定。我已经写了两种方法来解决这个问题,但是其中一种方法不能解除点击事件,所以我想知道为什么点击事件不能解除绑定。
<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 element和button element中解除click事件的绑定。
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 element和button element.So中解除单击事件--我想知道这两种方法之间的区别,并且我想知道为什么我不能在我的第一种方法中解除对单击事件的绑定。
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();
发布于 2016-08-14 06:51:31
bind()方法创建一个新函数--MDN
函数和绑定函数是不同的对象;每次调用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)...
}演示: (也是小提琴)
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;
})();<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时,执行绑定:
var obj = { ... };
obj.toggleUl = obj.toggleUl.bind(obj);
obj.selectLi = obj.selectLi.bind(obj);
obj.init();
...在这种方法中,您应该再次避免将您的函数绑定到addEventListener中,这将给您留下一个无法在removeEventListener中重用的未捕获的引用。
但是最简单的方法就是你找到的方法:不要为这项工作使用对象-字面语法!
https://stackoverflow.com/questions/38939569
复制相似问题