我有一个HTML按钮,我使用jQuery的bind()
附加了一个事件,如下所示:
$('#mybutton').bind('click', myFirstHandlerFunction);
在myFirstHandlerFunction
中,我希望这个处理程序用新的处理程序mySecondHandlerFunction
替换自己,如下所示:
function myFirstHandlerFunction(e) {
$(this).unbind('click', myFirstHandlerFunction).bind('click', mySecondHandlerFunction);
}
在第二个单击处理程序mySecondHandlerFunction
中,我想将按钮切换回其原始状态:取消绑定mySecondHandlerFunction
处理程序并重新附加原始处理程序myFirstHandlerFunction
,如这样:
function mySecondHandlerFunction(e) {
$(this).unbind('click', mySecondHandlerFunction).bind('click', myFirstHandlerFunction);
}
这很好用,除了一个小细节:因为click事件还没有传播通过每个按钮的点击处理程序,click事件被传递给按钮的下一个点击处理程序,它恰好是处理程序刚绑定在前一个处理程序中。最终结果是在mySecondHandlerFunction
执行后立即执行myFirstHandlerFunction
。
通过在每个处理程序中调用e.stopPropagation()
可以很容易地解决这个问题,但这会产生消极的副作用,即取消可能已独立附加的任何其他点击处理程序。
有没有办法在两个点击处理程序之间安全且一致地切换,而不必停止点击事件的传播?
答案 0 :(得分:8)
更新:由于此版本的
toggle()
已在jQuery 1.9中删除,因此以下解决方案不再有效。请参阅this question 的替代品。
看起来toggle()会解决您的问题:
$("#mybutton").toggle(myFirstHandlerFunction, mySecondHandlerFunction);
上面的代码会注册myFirstHandlerFunction
和mySecondHandlerFunction
,以便通过备用点击进行调用。
答案 1 :(得分:6)
只需使用布尔值来切换处理程序的功能,就不需要处理哪个处理程序正在侦听:
$('#mybutton').bind('click', myHandlerFunction);
var first = true;
function myHandlerFunction(e) {
if(first){
// Code from the first handler here;
}else{
// Code from the second handler here;
}
first = !first; // Invert `first`
}
答案 2 :(得分:1)
这个解决方案是一个黑客,但它 简短而且很适合你的粗糙工作:
$('#myButton').click(function() {
(this.firstClk = !this.firstClk) ? firstHandler(): secondHandler();
});
这是一个黑客,因为它将一个新属性直接放在this
上,这是点击目标HTML DOM元素,这可能不是最佳实践。但是,它因此避免了创建任何新的全局变量,并且可以在不同的按钮上同时使用它。
请注意,三元操作的第一部分使用=
而不是==
或===
,即它是一项任务,而非比较。另请注意,第一次单击按钮时,this.firstClk
未定义,但会立即取消,这使得三元操作的第一部分第一次评估为true
。
这是一个有效的版本:
$('#a > button').click(function() {(this.firstClk = !this.firstClk) ? a1(): a2();});
$('#b > button').click(function() {(this.firstClk = !this.firstClk) ? b1(): b2();});
function a1() {$('#a > p').text('one');}
function a2() {$('#a > p').text('two');}
function b1() {$('#b > p').text('ONE');}
function b2() {$('#b > p').text('TWO');}
div {display: inline-block;width: 10em;}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="a"><p>not yet clicked</p><button>click</button></div>
<div id="b"><p>NOT YET CLICKED</p><button>CLICK</button></div>
答案 3 :(得分:0)
我今天看着这个,并意识到如果没有列出全局变量,仍然没有办法做到这一点。我想出了以下内容来向ESRI底图添加位置,但它通常也会起作用:
function addLocationClickHandler() {
var addLocationClick = overviewMap.on('click', function (event) {
addLocationClick.remove();
})
$('#locationAddButton').one('click', function (cancelEvent) {
addLocationClick.remove();
$('#locationAddButton').on('click', addLocationClickHandler)
});
}
$('#locationAddButton').on('click', addLocationClickHandler)
这应该允许您在覆盖点击处理程序的部分中添加其他内容,而不需要全局变量。
答案 4 :(得分:-1)
这有助于在按钮上添加数据点击状态属性
$(document).ready(function(){
$('#mybutton').on('click',function(){
if($(this).attr('data-click-state') == 1) {
$(this).attr('data-click-state', 0)
myFirstHandlerFunction();
} else {
$(this).attr('data-click-state', 1)
mySecondHandlerFunction();
}
});
});
答案 5 :(得分:-2)
像这样:
$(this).bind('click', myMasterHandler);
handler = 0;
function myMasterHandler(e) {
if(handler == 0) {
myFirstHandler(e);
handler = 1;
} else {
mySecondHandler(e);
handler = 0;
}
}