0

I am creating a drop box when clicking into search field. I also have a document click function that reports length of drop box when clicking anywhere on the page. Why when the first click is into that search field my test says length = 1? I don't know how better to explain than showing code.

$(document).click(function(){
if($('#suggestionBox').length == 1){
    console.log("YODER " + $('#suggestionBox').length);
    console.log("YODER CLICKY");
    }   
});

$(document).ready(function(){
    $('input.search-header-box').click(
        function(){
        if($('#suggestionBox').length == 0){
            $('#navMainSearch').append('<div id="suggestionBox"class="shadow"><ul><li><a>Ideas</a></li><li><a>More Ideas</a></li></ul></div>');
        //console.log("YODER");
        }   
    });
});
  • because both `input.click` and `document.click` fire when your click on the search field, and `input.click` is called before `document.click` – Igor Dec 12 '14 at 02:51

1 Answers1

0

It is because of event bubbling.

When you click on the input element, first the $('input.search-header-box').click() handler is called which adds the target element to the dom, then the click event gets bubbled to the ancestor elements reaching at the end reaching the $(document).click(function(){}) handler where when you query the dom for the element it is already present thus it is showing 1.

$(document).click(function() {
  if ($('#suggestionBox').length == 1) {
    log("YODER " + $('#suggestionBox').length);
    log("YODER CLICKY");
  }
});

$(document).ready(function() {
  $('input.search-header-box').click(function() {
      if ($('#suggestionBox').length == 0) {
        log('Inside input click')
        $('#navMainSearch').append('<div id="suggestionBox"class="shadow"><ul><li><a>Ideas</a></li><li><a>More Ideas</a></li></ul></div>');
        //console.log("YODER");
      }
    });
});



var log = (function () {
    var $log = $('#log');
    return function (msg) {
        $('<p/>', {text: msg}).appendTo($log)
    }
})();
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<input class="search-header-box" type="button" value="Click" />
<div id="navMainSearch"></div>
<div id="log"></div>

If you don't want this behavior then you can prevent the bubbling by calling event.stopPropagation()

$(document).click(function() {
  if ($('#suggestionBox').length == 1) {
    log("YODER " + $('#suggestionBox').length);
    log("YODER CLICKY");
  }
});

$(document).ready(function() {
  //we want to add the element only once, so use .one() to register the handler
  $('input.search-header-box').one('click', function(e) {
    e.stopPropagation();
    if ($('#suggestionBox').length == 0) {
      log('Inside input click')
      $('#navMainSearch').append('<div id="suggestionBox"class="shadow"><ul><li><a>Ideas</a></li><li><a>More Ideas</a></li></ul></div>');
      //console.log("YODER");
    }
  });
});



var log = (function() {
  var $log = $('#log');
  return function(msg) {
    $('<p/>', {
      text: msg
    }).appendTo($log)
  }
})();
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<input class="search-header-box" type="button" value="Click" />
<div id="navMainSearch"></div>
<div id="log"></div>
Community
  • 1
  • 1
Arun P Johny
  • 384,651
  • 66
  • 527
  • 531