Traversing DOM with jQuery questions

Question #1

Do not understand why these functions supposedly point to the same object, but they return different results:
(1) with getSubMenu(..)
(2) with itemInSubMenu(..)

(1) traverses down hill with .find(..)
(2) traverses up hill with .parent()

Same target, but different results?

Before I present the 2 functions:

HTML snippet

<li class="daddy">
	text233
	<ul class="aMenu">   <!-- sub-menu  -->
		<li>
			<a href="ABOUT.html">
			text2331
			</a>
		</li>
		<li class="daddy">
			text2332
			<ul class="aMenu">   <!-- sub-sub-menu  -->
				<li>text23321</li>
				<li>text23322</li>
			</ul>
		</li>   <!-- daddy text2332 -->
		<li>
			<a href="ABOUT.html">
			text2333
			</a>
		</li>
	</ul>
</li>   <!-- daddy text233 -->

Now, the culprits …

function getSubMenu($currItem) {
	
	var $theSubMenu = null;
	
	if ( $currItem.hasClass("daddy") ) {
	//	$theSubMenu = $currItem.next(".aMenu");
		$theSubMenu = $currItem.find(".aMenu").first();
	}
	
	return $theSubMenu;

}   // getSubMenu

function itsParentIsSubMenu($theItem) {
	
	// .daddy <-- .aMenu <-- $theItem
	return $theItem.parent(".aMenu").parent("").hasClass("daddy");

}   // itsParentIsSubMenu


function itemInSubMenu($theItem) {

	var $theSubMenu = null;
	
	if (itsParentIsSubMenu($theItem)) {
		$theSubMenu = $theItem.parent();   // parent = ".aMenu"
	}
	
	return $theSubMenu;

}   // itemInSubMenu

Question #2

Inside getSubMenu(..), I have:

// $theSubMenu = $currItem.next(".aMenu");

$theSubMenu = $currItem.find(".aMenu").first();

What is wrong with the .next(..) statement? .find(..) works, but not .next(..)

PS:

FWIW, elsewhere I am TABbing from <li> to <li>.

When I encounter a <li.daddy> I call getSubMenu to show the sub-menu. After it shows, I continue tabbing, e.g.:

from:

<li>text23321</li>
<li>text23322</li>

I call getSubMenu on the 1st <li> and then itemInSubMenu on the 2nd <li> … and they generate un-equal sub-menu objects (“.aMenu”) … but they are in fact the same?

Does it help to know that next searches siblings, whereas find searches children?

BINGO

Will use this knowledge gem to see if it solves my .find vs .parent challenge. .find goes downhill and .parent goes uphill so I don’t know yet.

Thanks to Paul Wilkins, problem #2 solved, but problem #1 still giving nightmares:

Let me present an even shorter HTML snippet:

<li class="daddy">
	text2332
	<ul class="aMenu">   <!-- sub-menu  -->
		<li>text23321</li>
		<li>text23322</li>
	</ul>
</li>   <!-- daddy text2332 -->

When TABbing encounters "li.daddy", getSubMenu is called and selects the very 1st (top) item in the sub-menu = text23321. getSubMenu returns the sub-menu object and stores it in a var.

TABbing continues to the 2nd item = text23322 in the same sub-menu and calls itemInSubMenu which returns a sub-menu object. Since we’re by definition in the same sub-menu, the object returned by getSubMenu and itemInSubMenu should be equal, but they are not?

As already mentioned, getSubMenu traverses down the DOM tree with .find and itemInSubMenu goes up with .parent.

Whether going down or up, shouldn’t the returned object be the same?

I will quote the 2 functions here, with corrections:

functions getSubMenu($currItem) {
	
	var $theSubMenu = null;
	
	if ( $currItem.hasClass("daddy") ) {
		$theSubMenu = $currItem.find(".aMenu").first();
	}
	
	return $theSubMenu;

}   // getSubMenu

function itsParentIsSubMenu($theItem) {
	
	// .daddy <-- .aMenu <-- $theItem
	return $theItem.parent().parent().hasClass("daddy");

}   // itsParentIsSubMenu

function itemInSubMenu($theItem) {

	var $theSubMenu = null;
	
	if (itsParentIsSubMenu($theItem)) {
		$theSubMenu = $theItem.parent();   // parent = ".aMenu"
	}
	
	return $theSubMenu;

}   // itemInSubMenu

It’s time for more “magic”, Paul Wilkins.

Absolutely no thanks to me, I found that i needed to add [0] to compare the contents of the 2 jQuery objects. AND that every time a jQuery object is created, it’s a brand new one so testing for equality of 2 jQuery objects always renders false (or, testing for in-equality always renders true).

1 Like

If you need a more detailed comparison of jQuery objects then that’s where filter can be used.

var divs = $("div");
var divs2 = $("div");

if (divs.length == divs2.length && divs.length == divs.filter(divs2).length) {         
  // They are equal
}

Source: https://css-tricks.com/snippets/jquery/compare-jquery-objects/

Paul,

Buried within your cite, I found this:

if ( $obj1.is($obj2) )

Doesn’t create a new object
Quietly compares contents
And the English verbalization sounds right

“A birch is a tree”

Sort of.

It’s less “a birch is a tree” and more… “Something in this set is also in this other set”. More of a Venn Diagram assertion that the union is not empty;

cars.is("things that are blue") would return true - not all cars are blue, and not all things that are blue are cars, but at least one thing in the two sets is both.

Often used with single-element sets - element.is("li") - the thing you have selected (element) is a member of the set of elements returned by the selector “li”

This topic was automatically closed 91 days after the last reply. New replies are no longer allowed.