检测元素已被删除时的单击

时间:2017-07-16 03:03:06

标签: javascript jquery jquery-ui jquery-ui-datepicker

我试图检测是否在DatePicker控件上发生了点击,但我无法准确地确定事件目标元素是否是DatePicker的一部分。

经过大量调试后,我发现主要问题是DatePicker的各个部分与文档分离,因此它们根本不是任何元素的子元素。

感谢this other question我了解到原因是在切换月份时正在删除并替换了一大块DatePicker,因此我从event.target获取的元素是分离的(它是删除的块。)

那么,我该怎么做才能确定这次点击发生在我的控制范围内?虽然DatePickers的具体修复方法没问题,但我试图用这种方式写出这种内容正在使用中。

到目前为止,我所做的是检查我的元素是否包含DatePicker,以及事件目标是否已分离。如果是这样,我认为点击发生在DatePicker上。这并不完美,因为页面上可能有另一个DatePicker。此外,分离的事件目标并不一定必须与DatePicker相关。

以下是我目前所拥有的一个例子:

$(document).on("click", function (event) {
   const stuff = $("something");

   if (stuff.is($(event.target)))          
      return; // click was on stuff

   if ($(event.target).closest(stuff).length)
      return; // click was on descendents of stuff

   if (stuff.is(":active, :focus"))
      return; // stuff is active or focused

   if (stuff.find(":active, :focus").length)
      return; // a descendent of stuff is active or focused

   if (stuff.is(".hasDatepicker") || stuff.find(".hasDatepicker").length) {
      // stuff is or has a date picker
      if (!$(event.target).closest($(document)).length) {
         // event target is detached, and there's a date picker in stuff
         // so have to assume click was on stuff's date picker
         return;
      }
   }

   // click was not within stuff's elements
}

2 个答案:

答案 0 :(得分:1)

您正在寻找的可能是$(".selector").datepicker("widget")

Per the docs:

  

返回包含datepicker的jQuery对象。   此方法不接受任何参数。

     

代码示例:   调用widget方法:

     

var widget = $(" .selector")。datepicker(" widget");

现在您可以从原始元素中获取实际的日期选择器UI,您可以使用您喜欢的方式,即检查点击是否在其上。

以下是使用上述内容解决此问题的方法:



$(function() {

  $('#thedate').datepicker({
    dateFormat: 'dd-mm-yy',
    altField: '#thealtdate',
    altFormat: 'yy-mm-dd' 
  });

  $(document).on('mousedown',function(event) {
    // only evaluate if the click was NOT on the element or any of its descendants 
    if (!$(event.target).closest('#some-container').length && !$(event.target).is('#some-container')) {
      // now lets check for any elements in our container that have datepickers 
      var $contanier = $('#some-container');
      var $elementsWithDatePickers = $contanier.find('.hasDatepicker');
      var clickedChildDatePicker = false;
      $elementsWithDatePickers.each(function() {
        // for each datepicker found, check that the click was also not on it or any of its descendants
        var $widget = $(this).datepicker("widget");
        if ($(event.target).is($widget) || $(event.target).closest($widget[0]).length > 0) {
          clickedChildDatePicker = true;
          return false;
        }
      });
      if (!clickedChildDatePicker) {
        $contanier.hide();
      }
    }
  }) 
});

#other{
  background-color:#ccc; 
  padding: 45px;
}
#some-container{
  background-color:#fff;
  padding: 45px;
  
}

<link href="https://code.jquery.com/ui/1.8.21/themes/base/jquery-ui.css" rel="stylesheet"/>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://code.jquery.com/ui/1.11.3/jquery-ui.min.js"></script>


<div id="other"> 

<div id="some-container">
  Date :
  <div id="thedate">
  </div>
  <br /> 
</div>

  click here to hide container 
</div>
&#13;
&#13;
&#13;

答案 1 :(得分:-1)

我不明白你的意思:
«DatePicker的各个部分与文档分离,因此它们根本不是任何元素的子元素。»

那是错的。您可以在页面中看到的所有元素都在DOM中(因此“附加”到文档中) 但有时候,不是很长一段时间,这就是这种情况。

Datepicker元素在打开时创建并附加到{\"event_header\":{\"version\":\"1.0\"...} 当它关闭时,它的元素都被删除了。

以下代码会检索点击的元素,bodytagNameclass及其id
我甚至在文件中重新创建了它们...... ;)

它使用delegation,因为@Roamer在评论中正确提及。

innerHTML

可悲的是,我的示例的CSS在SO片段中效果不佳。 所以它在CodePen上。

我使用$(document).on("mouseup",".ui-datepicker",function(e){ var target = e.target; var tag = target.tagName.toLowerCase(); var classes = target.className; var ID = target.id; var resultString = "<"+tag+" id='"+ID+"' class='"+classes+"'>"+target.innerHTML+"</"+tag+"><br>"; console.log(resultString); var result = $(resultString); $("#result").append(result); }); 事件,因为mouseup不起作用...
可能是由于Datepicker中的某个click