0

我有一个文本输入,当它具有焦点时,我想在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");
}

垃圾桶

谢谢你的帮助。

4

3 回答 3

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

新垃圾箱

于 2013-06-21T02:40:52.857 回答
0

好吧,我看到几个问题...

  1. 您正在将焦点事件委托给 HTML 元素,以获取单个元素上的事件......这有点矫枉过正,所以我会将 focusandblur事件直接放在input
  2. 当您调用时off,您需要在第二个参数中将完全相同的选择器传递给它
  3. 您的点击事件被委托给主体,并在任何被点击并与选择器匹配的子元素上触发 - 这不包括body本身......不确定您是否想要那样,但我将它移到html元素上,包括body
  4. 一旦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);
  }
}
于 2013-06-21T13:26:04.530 回答
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>
于 2013-06-21T02:32:36.613 回答