Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/oop/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 在输入聚焦时向主体添加单击事件,然后在模糊时将其删除_Javascript_Jquery - Fatal编程技术网

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);
      }
    }