Javascript/jQuery - Each skip all children - javascript

I'm getting all the elements on the document:
$("*").each(function(){
var el = $(this);
});
What I need is to get all the elements but the children elements. I mean this:
<div> <!--GET IT-->
<div></div> <!--DON'T GET IT-->
</div>
<div> <!--GET IT-->
<div></div> <!--DON'T GET IT-->
<label></label> <!--DON'T GET IT-->
</div>
How can I filter that?

You can target the parent element of outermost div elements and then use immediate child selector to get first level child element.
Let us assume you have above markup in body container. Then you can use
$('body > *').each(function(){
var el = $(this);
});

You can use this
$('body > * ').each();
This targets all elements childrens of body, but don't target the childrens of the elements.

Look this: https://api.jquery.com/child-selector/
$("parent > child").each(function(){
$(this) /* children */
});

Related

How to select leaf node using jQuery :contains selector?

I want to get leaf elements containing specific text, and I used :contains selector. However, this selector selects includes every parent nodes too. Here is my example.
<div id='parent1'>
<p id='target1'>Red balloon</p>
<div id='target2'>Blue balloon</div>
</div>
<div id='parent2'>
<span id='target3'>Brown balloon</span>
</div>
In this case, I just want to get elements containing text balloon. I expected to get 3 elements(target1, target2, target3) by $(":contains('balloon')"), but it returns every nodes including parent nodes of targets. (e.g. html, body, and every parent div)
How can I select only targets?
p.s Above HTML is only example. HTML can be vary, so the answer should be generic.
use indexOf("balloon") > -1 to find id the word balloon is found
var arr = $("div").children().map(function(){
if($(this).text().indexOf("balloon") > -1 )
return $(this).attr("id")
}).get();
console.log(arr)
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id='parent1'>
<p id='target1'>Red balloon</p>
<div id='target2'>Blue balloon</div>
</div>
<div id='parent2'>
<span id='target3'>Brown balloon</span>
</div>
The solution below, look for all elements containing the word and clone these elements, This way we can be sure only to get "correct" amount of elements
Just remove .length and you have access to the elements.
var s = $(":contains('balloon')").not("script").filter(function() {
return (
$(this).clone() //clone the element
.children() //select all the children
.remove() //remove all the children
.end() //again go back to selected element
.filter(":contains('balloon')").length > 0)
}).length;
console.log(s)
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id='parent1'>
<p id='target1'>Red balloon</p>
<div id='target2'>Blue balloon</div>
</div>
<div id='parent2'>
<span id='target3'>Brown balloon</span>
</div>

Can't read the NodeName of a parent element

I want to build a script which recognizes the index of an (unspecified) element within its parent element with an simple mouseclick. It's possible that the clicked element is a span, div, li or any other element.
Problem is that I am not able to retrieve the TagName / NodeName of the parent element because I always get an error Uncaught TypeError: Cannot read property 'nodeName' of undefined
My HTML looks like that:
<body>
<span id="test1">
<div>test</div>
</span>
<div id="test2">
<div>eins</div>
<div>zwei</div>
<div>drei</div>
</div>
</body>
My function looks like that:
$(document).on('click', function(evt){
evt.stopPropagation();
var child = evt.target.tagName;
var parent = $(evt).parent();
console.log(parent[0].nodeName);
});
According to this StackOverflow thread this should be right, but it doesn't work.
I want to build a script which recognizes the index of an (unspecified) element within its parent ...
So you just need to use $.fn.index method with evn.target which points to clicked element:
$(document).on('click', function(evt) {
var index = $(evt.target).index();
alert(index);
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<span id="test1">
<div>test</div>
</span>
<div id="test2">
<div>eins</div>
<div>zwei</div>
<div>drei</div>
</div>
Seems that -
$(evt).parent();
Should be -
$(evt.target).parent();

this parent jQuery

jQuery
$(".drop-down h3").click(function(e) {
e.preventDefault();
$(this).parent(".drop-down").find($("ul")).stop().slideToggle();
$(this).parent(".drop-down").find($(".divider-aside")).stop().toggle("slow");
$(this).parent(".drop-down").find($(".arrow")).stop().toggleClass("rotate1 rotate2");
});
HTML
<div id="categories">
<div class="drop-down">
<h3>Categories</h3>
</div>
<div class="divider-aside"></div>
<ul>
<li>123</li>
<li>12323</li>
<li>1231</li>
<li>523</li>
<li>31</li>
</ul>
</div>
I'd like to hide everything in .drop-down class excluding <h3> by clicking on <h3>. In this case only .arrow toggleClass works.
Use closest instead of parent
$(this).closest("#categories")
parent will only go back 1 level , i.e, the immediate parent. But you gotta get the container that encloses all the 3 elements
So $(this).parent(".drop-down")
supposed to be either
$(this).parent().parent() // this will break if there is an extra
// parent container gets added
or
$(this).closest("#categories") // This will work even if the no of
// parent container keep chaning
if you need toggle them all but the .drop-down .siblings is just what you need
$("div.drop-down > h3").click(function(){
var $t = $(this);
$t.parent().siblings().toggle();
});

jQuery - How to find an index of an ID within another container DIV?

I thought to use .index but it don't seem to work!
<div id="main">
<div id="one">
<div class="red"> ... </div>
</div>
<div id="two">
<div class="green"> ... </div>
</div>
<div id="three">
<div class="blue"> ... </div>
</div>
</div>
So I tried:
var isDivThere = $("main").index("#two") != -1;
but as mentioned, no go...
How can I simply look up a div inside div #main?
$("#main > div").index($("#two"))
var isDivThere = $("#main > div").index($("#two")) != -1;
Note: > is for filter only first level div's. So my solution will not work if you want to check the index of nested divs.
To check for existence, you can simply do this:
var isDivThere = !!$('#two').length;
If #two must exist inside #main:
var isDivThere = !!$('#main').find('#two').length;
If #two must be a child of #main:
var isDivThere = !!$('#main').children('#two').length;
To know the index of an element within its container just invoke index over the element id your are looking for:
var isDivThere = $("#two").index();
http://jsfiddle.net/NGhL7/
You need to add the # symbol for selecting by id. Working fiddle here:
$("#yourId");
http://jsfiddle.net/nnFh5/
You can use find() function of jquery,
$("#main").find("#two");
$Because the ID is unique within the all body this is enough to do what you do:
var isDivThere = !!$$("#two").length;
you will never find another element with an ID="two" so you have no need to identify that telling that is insode the main div

How can I hide parent element of all elements with a given class, but the parent element also has a specific class?

I want to hide all instances of an li element with class parent that have an immediate child div element with class child-1. Here's a pseudocode example, where the method hideParent() would hide the parent of the selected element(s):
$("li.parent > div.child-1").hideParent();
The following is an example of my HTML, in which the second and third li.parent elements should be hidden.
<li class="parent">
<div class="child-0"> ... </div>
</li>
<li class="parent">
<div class="child-1"> ... </div>
</li>
<li class="parent">
<div class="child-1"> ... </div>
</li>
Try this:
$("li.parent > div.child-1").parent().hide();
Select the relevant child elements directly, target their parents (filtered by the relevant selector), then hide them.
$("div.child-1").parent('li.parent').hide();
See:
parent Documentation
Another option is with using filter:
$("li").filter(function () {
var $this = $(this);
var isParent = $this.hasClass("parent");
var childMatchCount = $this.children("div").filter(".child-1").length;
return isParent && childMatchCount;
}).hide();
DEMO: http://jsfiddle.net/GEhfP/
Although this can be optimized in several ways. But to me, it's more "readable", in a very explicit sense. Using jsperf, the quickest I can get filter to work is with:
$("li.parent").filter(function () {
return $(this).children("div.child-1").length;
}).hide();
#Joe's answer was the fastest with: $("li.parent > div.child-1").parent()

Categories