Javascript 在输入聚焦时向主体添加单击事件,然后在模糊时将其删除
我有一个文本输入,当它有焦点时,我想在Javascript 在输入聚焦时向主体添加单击事件,然后在模糊时将其删除,javascript,jquery,Javascript,Jquery,我有一个文本输入,当它有焦点时,我想在正文的任何地方注册一个点击事件。但当焦点从中移除时,单击事件将从正文中移除。可悲的是,我似乎无法理解它 $(document).ready(function () { $("html").on("focus", "#asdf", function () { $("body").on("click", "*:not(#asdf)", wasItClicked); }); $("html").on("blur", "#
正文
的任何地方注册一个点击事件。但当焦点从中移除时,单击事件将从正文中移除。可悲的是,我似乎无法理解它
$(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");
}
感谢您的帮助。在添加和删除事件时,您可以使用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>
例子
$(文档).ready(函数(){
$(“html”)。关于(“焦点”,“asdf”,函数(){
log(“添加点击处理程序”);
$(“body”)。在(“click.fromasf”上,“*:not(#asdf)”,wasItClicked);
});
$(“html”)。关于(“模糊”,“asdf”,函数(){
setTimeout(函数(){
日志(“删除单击”);
$(“body”).off(“click.fromasf”);
}, 500);
});
});
函数wasItClicked(){
console.log(“耶”);
}
当“asdf”被聚焦,并单击其他元素时,事件按鼠标向下、模糊、鼠标上、单击的顺序触发。因此,在单击激发之前,处理程序已被移除
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");
}
好的,我看到了几个问题
您正在将焦点事件委托给上的事件的HTML元素
单一元素。。。这有点过分了,所以我会把
直接在输入上聚焦和模糊事件
当您关闭时,需要在第二个参数中传递完全相同的选择器
您的单击事件被委托给主体,并在任何被单击且与选择器匹配的子元素上触发-这不包括主体本身。。。不确定您是否希望这样做,但我将其上移到html
元素,以包含主体
一旦输入
失去焦点,事件将被删除,因此点击将不会注册(您可以按照@HMR在回答中的建议使用超时)
我对仍然返回输入的html
元素的委托有一些问题(尽管有:not(#asdf)
选择器),所以我只是将过滤器放入函数中
以下是修订后的代码(测试版本):
但我正在尝试注册点击事件。mousedown如何提供帮助?mousedown可以帮助您确定何时删除单击处理程序,因此在由于单击而失去焦点时,您实际上调用wasItClicked。(见编辑)
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);
}
}