Search code examples
javascriptjqueryjquery-selectorsdom-traversaljquery-traversing

How come selectors in $.fn.find() cannot reference the tree beyond the current $ scope?


In jQuery

$('html head').length                             // 1

And

$('html').find('head').length                     // 1

And

$('html').find('head').filter('html head').length // 1

BUT

$('html').find('html head').length                // 0

Why?


Solution

  • Your first selector $('html head') works just like find - gets any <head> descendants of HTML

    HTML──┐  start here and find head
        HEAD
    

    Your second selector $('html').find('head') gets html element - then finds all descendant <head> elements

    HTML──┐ start here and find head
        HEAD
    

    Your third selector $('html').find('head').filter('html head') gets html element - then finds all descendant <head> elements - the filter is really pointless because the returned head elements are guaranteed to be descendants of html because of this $('html').find('head')

    HTML──┐  start here and find head
        HEAD

    Your lastone that isn't working $('html').find('html head') is searching for structure below

    HTML──┐  start here and find "html head" 
        HTML──┐    
             HEAD
    but really your structure is like this
    HTML──┐  
        HEAD
    

    which html doesn't have a descendant html element so that results in 0 elements returned

    If you want to keep the HTML element in the collection you can use .addBack()

    $('html') // get html element
      .find('html head') // find head element
      .addBack() // add back the html element
      // if jQuery 1.7 and lower use .andSelf()
      .length  // this will result in 1 element - the HTML element