我想要一个文本输入,当它有焦点时,在body
的任何地方注册一个点击事件。但是当焦点从中删除时,该点击事件将从body
中删除。可悲的是,我似乎无法理解它。
$(document).ready(function () {
$("html").on("focus", "#asdf", function () {
$("body").on("click", "*:not(#asdf)", wasItClicked);
});
$("html").on("blur", "#asdf", function () {
$("body").off("click", "*", wasItClicked);
});
});
function wasItClicked() {
alert("yeah");
}
感谢您的帮助。
答案 0 :(得分:1)
当#asdf被聚焦,并且点击了一些其他元素时,事件将按照mousedown,blur,mouseup,click进行触发。因此,在点击火灾之前已经删除了处理程序。
mousedown事件在模糊之前触发。如果您对mousedown而不是单击没问题,可以使用:
$(document).ready(function () {
$("#asdf").on("focus", function () {
$("body").on("mousedown", wasItClicked);
});
$("#asdf").on("blur", function () {
$("body").off("mousedown", wasItClicked);
});
});
编辑:
您可以使用mousedown事件来帮助确定您是否因为点击而失去焦点,并在失去焦点时删除点击处理程序中的处理程序。
$(document).ready(function () {
$("#asdf").on("focus",function() {
$("body").on("mousedown", setDown);
$("body").on("click", wasItClicked);
});
$("#asdf").on("blur", function() {
if ($(this).attr("mouse") != "down") {
$("body").off("mousedown", setDown);
$("body").off("click", wasItClicked);
}
});
});
function setDown() {
$("#asdf").attr("mouse","down");
}
function wasItClicked() {
if ($("#asdf") != $(document.activeElement)) {
$("body").off("mousedown", setDown);
$("body").off("click", wasItClicked);
}
$("#asdf").attr("mouse","up");
alert("yeah");
}
答案 1 :(得分:0)
您可以使用setTimeout在添加和删除事件时删除单击并使用名称空间,因为您可能会意外删除另一个单击处理程序,但最简单的方法是删除处理程序中的单击事件:
...
$("body").on("click.fromasf", "*:not(#asdf)", wasItClicked);
...
function wasItClicked() {
$("body").off("click.fromasf");
console.log("yeah");
}
以下是使用超时的示例:
<!DOCTYPE html>
<html>
<head>
<script src="jquery-1.9.0.js"></script>
<style>
</style>
<meta content="text/html; charset=UTF-8" http-equiv="content-type">
<title>Example</title>
</head>
<body>
<input type="text" id="asdf" />
<input type="text" id="Text1" />
<script>
$(document).ready(function () {
$("html").on("focus", "#asdf", function () {
console.log("adding click handler");
$("body").on("click.fromasf", "*:not(#asdf)", wasItClicked);
});
$("html").on("blur", "#asdf", function () {
setTimeout(function () {
console.log("remove click");
$("body").off("click.fromasf");
}, 500);
});
});
function wasItClicked() {
console.log("yeah");
}
</script>
</body>
</html>
答案 2 :(得分:0)
好的,我看到了几个问题......
focus
blur
和input
个事件
off
时,您需要在第二个参数body
本身...不确定您是否想要这样,但是我将其移至html
元素,以包含body
input
失去焦点,该事件将被删除,因此点击不会注册(您可以使用超时作为答案中建议的@HMR)我在仍然返回输入的html
元素上的委托有一些问题(尽管有:not(#asdf)
选择器)所以我只是将过滤器放入函数中。
以下是修订后的代码(测试版):
var click_selector = ":not(#asdf)";
var click_target = 'html';
$(document).ready(function () {
$("#asdf").on("focus", function () {
$(click_target).on("click", click_selector, wasItClicked);
});
$("#asdf").on("blur", function () {
// Use timeout to be able to register the click before function is removed
// NOTE that since 'click' fires when the mouse is released, if they
// hold the mouse down for a while, the event will be gone and won't
// register. Maybe better to use 'mousedown' instead of 'click'
// in which case the timeout could probably be reduced to 10ms or something
// Also, using timeouts creates the possibility of multiple click handlers
// present at the same time (new one added before the previous is removed)
setTimeout( function(){
$(click_target).off("click", click_selector, wasItClicked);
}, 100);
});
});
function wasItClicked(e) {
e.stopPropagation();
e.preventDefault();
if( e.target.id !== 'asdf' ){
console.log('yeah', click_target, click_selector);
}
}