I have the following markup:
<div class="feed-item">
<div class="date-header">2012-06-03</div>
</div>
<div class="feed-item">
<div class="todo">Todo</div>
</div>
<div class="feed-item">
<div class="meeting">meeting</div>
</div>
I want to show only the divs of a different class name e.g. class="todo" and keep the "date-header" visible. I have the following javascript"
$('.feed-cluster,.feed-item-container').not('div:first.date-header').not(className).slideUp(speed, function(){
$('.feed-cluster' + className + ',.feed-item-container' + className).slideDown(speed);
});
Everything works fine except the bit where I am trying to exclude the first child with a class name of date-header:
.not('div:first.date-header')
Can anyone suggest an alternative?
$('div.date-header').slice(1);
Should do it.
slice Is the fastest function!
Because :first is a jQuery extension and not part of the CSS specification, queries using :first cannot take advantage of the performance boost provided by the native DOM querySelectorAll() method.
Alternative way, which still uses the querySelectorAll function:
$('div.date-header').not(':first');
.not('div:first.date-header') should be .not('.date-header:first')
As #gdoron noted: :first is not part of the css specification, but :not() and :first-child are. It is supported by all major browsers.
So you also could use this to skip the first child using a css selector inside jQuery.
$(".child:not(:first-child)").css("background-color", "blue");
div.child {
background-color: #212121;
color: #fff;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="container">
<div class="child">
<p>Im a child of .container</p>
</div>
<div class="child">
<p>Im a child of .container</p>
</div>
<div class="child">
<p>Im a child of .container</p>
</div>
</div>
legacy browsers support
If you need to support legacy browsers, or if you are hindered by the :not() selector. You can use the .child + .child selector. Which will also work.
$(".child + .child").css("background-color", "blue");
div.child {
background-color: #212121;
color: #fff;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="container">
<div class="child">
<p>Im a child of .container</p>
</div>
<div class="child">
<p>Im a child of .container</p>
</div>
<div class="child">
<p>Im a child of .container</p>
</div>
</div>
Related
I'm trying to do the same thing as this question but my parent element does not have an id. It does have a class through. Basically I have multiple elements of the same class and some have a child element. If a member of the class example contains the child, apply some CSS change. Is this possible and how would I do it?
For example:
<div class="example">
<div id="findMe"></Div>
</div>
<div class="example">
<!-- This div would not be found -->
</div>
My guess was:
let parents = $(".example");
for (var i=0; i < parents.length; i++) {
if (parents[i].find('#test').length) {
parents[i].css("prop", "value")
}
}
but parents[i].find is not a function
So you shouldn't have multiple instances of the same ID in a document. But in your example, you were pretty close. However, if you're already using jQuery it will make your life a bit easier.
<div class="example">
<div class="findMe"></Div>
</div>
<div class="example">
<!-- This div would not be found -->
</div>
jQuery:
(I'm using the $ to denote a jQuery collection you wouldn't need it)
A jQuery collection (in this case created by find) always has a length. So you need to test if it's empty. Also $.each() is basically looping through the collection.
let $parents = $('.example');
$parents.each(
function(){
var $el = $(this);
if($el.find('.findMe').length !=0){
$el.css('background', 'red');
}
}
);
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div style="height:100px;" class="example">
<div class="findMe">Hello, World!</Div>
</div>
<div style="height:100px;border: solid 1px #000" class="example">
<!-- This div would not be found -->
</div>
As Heretic Monkey said in the comments above, you can use has from jQuery to do this easily.
$(".example").has(".findMe").css("background-color", "red");
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div style="height:100px;" class="example">
<div class="findMe">Hello, World!</Div>
</div>
<div style="height:100px;border: solid 1px #000" class="example">
<!-- This div would not be found -->
</div>
What if it has few parents? (as in grandparents, great grandparents)
<div class="lvl1">
<div class="lvl1.1">
<div class="lvl1.2">
<button class="btn-submit">Click Me</button>
<div class="a1">Hello
<div>
</div>
</div>
<div class="lvl2">
<div class="b1">
<div class="b2">Make me disappear!</div>
</div>
</div>
<div class="lvl3">
<div class="c1">Thank you.
</div>
</div>
JS
$(function(){
$(".btn-submit").click(function() {
$(this).parent(".lvl1").siblings(".lvl2").children(".b2").hide();
});
});
How to use .parent, .parents, .siblings, .children, .next, .prev to show and hide the div?
If I assume that you have that structure repeated and want to remove the one in the same copy as the .btn_submit that was clicked, we go up to the .lvl1 via closest, over to the .lvl2 via .nextAll().first() (or we could just use .next), and then .find the .b2 in there:
$(".btn-submit").click(function() {
$(this).closest(".lvl1").nextAll(".lvl2").first().find(".b2").hide();
});
Your code is very close, just two things that I had to change:
Instead of using .siblings(".lvl2"), which will find all of them, I used .nextAll(".lvl2").first() to just find the one immediately after "this" .lvl1.
I used find instead of children, because children will only go down one level (direct child), not search descendants
I also used closest(".lvl1") so that if you move the .btn_submit deeper into .lvl1, it will continue working.
Live Example:
$(function() {
$(".btn-submit").click(function() {
$(this)
.closest(".lvl1")
.nextAll(".lvl2")
.first()
.find(".b2")
.hide();
});
});
<div class="lvl1">
<button class="btn-submit">Click Me</button>
<div class="a1">Hello
</div>
</div>
<div class="lvl2">
<div class="b1">
<div class="b2">Make me disappear!</div>
</div>
</div>
<div class="lvl3">
<div class="c1">Thank you.
</div>
</div>
<div class="lvl1">
<button class="btn-submit">Click Me</button>
<div class="a1">Hello
</div>
</div>
<div class="lvl2">
<div class="b1">
<div class="b2">Make me disappear!</div>
</div>
</div>
<div class="lvl3">
<div class="c1">Thank you.
</div>
</div>
<div class="lvl1">
<button class="btn-submit">Click Me</button>
<div class="a1">Hello
</div>
</div>
<div class="lvl2">
<div class="b1">
<div class="b2">Make me disappear!</div>
</div>
</div>
<div class="lvl3">
<div class="c1">Thank you.
</div>
</div>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
there is possible to disappear div directly using,
$(".b2").hide();
but if you want to use ".parent, .parents, .siblings, .children, .next, .prev",
$(".btn-submit").parent().siblings(".lvl2").children().children(".b2").hide();
need to you children() Two times... because .b2 is not directly child to .lvl2,
another best way to hide ".b2" is,
$(".btn-submit").parent().siblings(".lvl2").find(".b2").hide();
so your Ans is:
$(".btn-submit").click(function() {
$(".btn-submit").parent().siblings(".lvl2").find(".b2").hide();
});
.children selects the children and not descendants of the element. You just need to replace the .children with the .find method and your code will select the target element.
I can't figure how to achieve this in the best way:
Let's say I have:
<div class="parent">
<div class="child"></div>
</div>
<div class="parent">
<div class="child"></div>
</div>
<div class="parent">
<div class="child"></div>
</div>
And I want to move every 'child' right after it's parent.
<div class="parent"></div>
<div class="child"></div>
<div class="parent"></div>
<div class="child"></div>
<div class="parent"></div>
<div class="child"></div>
How can I achieve this?
Update: Also, how can i exclude the parents that have certain attributes? For example, I need to exclude those that have data-anchor=2 and data-anchor=3 I can't figure out how to do this.
$(".parent").each(function(){
$(this).after($(".child", this));
});
JSFiddle: https://jsfiddle.net/TrueBlueAussie/onsb12jx/
Note: $(".child", this) is just a shorter version of $(this).find(".child")
Excluding elements can use either .not() or :not() or a filter:
e.g. using .not()
$(".parent").not('[data-anchor=2],[data-anchor=3]').each(function(){
$(this).after($(".child", this));
});
or using :not pseudo selector
$(".parent:not([data-anchor=2],[data-anchor=3])").each(function(){
$(this).after($(".child", this));
});
or using a filter() function
$(".parent").filter(function(){
return $(this).data('anchor') == "2" || $(this).data('anchor') == "3";
}).each(function(){
$(this).after($(".child", this));
});
You can achieve this by looping over the .child elements and using insertAfter() to place them after their closest parent .parent element:
$('.parent .child').each(function() {
$(this).insertAfter($(this).closest('.parent'));
});
Example fiddle
Use
$(".parent").each(function() {
$(this).after($(this).find(".child"));
});
after() will help you to position the element after the selected element
You can use .after(fn) method with a function as an argument to return the desired behavior, a benefit of it is not to use a loop explicitly, This way it will do this for you internally:
$('.parent').after(function() {
return $('.child', this);
});
.parent{border:solid red 3px;}
.child{border:solid 3px green; margin:3px 0;}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="parent">
<div class="child">child</div>
parent
</div>
<div class="parent">
<div class="child">child</div>
parent
</div>
<div class="parent">
<div class="child">child</div>
parent
</div>
You can use detach method to do that like so:
$(".parent").each(function() {
$(this).after($(this).find(".child").detach());
});
Here is the JSFiddle demo
You can check the structure by Inspecting element of the age :)
I have the below page layout:
<div class="content">
<div class="main-content profile0">
<div class="messages">
</div>
<div class="moreinfo">
</div<
</div>
<div class="main-content profile1">
<div class="messages">
</div>
<div class="moreinfo">
</div<
</div>
</div>
Currently I have been doing things like
$('.messages').remove();
but I need to be able to set which div is actually the parent, so I can tell jquery to only look at the childer of the div "main-content profile1"
So that then
$('.messages').remove();
refers to the child of "main-content profile1" and not "main-content profile0"
You can use the find() like
$('.main-content.profile1').find('.messages').remove();
As AmmarCSE said, you can use find(), but you could also just change the selector.
$('.main-content.profile1 .messages')
If you have the following code:
<div class="parent">
<div class="1"></div>
<div class="2"></div>
<div class="3"></div>
<div class="4"></div>
<div class="5"></div>
</div>
How can I wrap a new div around div with class 2,3,4,5 so it looks like this:
<div class="parent">
<div class="1"></div>
<div class="sub">
<div class="2"></div>
<div class="3"></div>
<div class="4"></div>
<div class="5"></div>
</div>
</div>
wrapAll on the parent would wrap everything with a new div, is there a way to make it ignore the first div?
Use gt(0) to select all but the first one div(direct descendant) and wrapAll. This will select all divs with index greater than 0 present under .parent div.
$('.parent > div:gt(0)').wrapAll('<div class="sub">');
Fiddle
See :gt()
Output:
<div class="parent">
<div class="1">1</div>
<div class="sub">
<div class="2">2</div>
<div class="3">3</div>
<div class="4">4</div>
<div class="5">5</div>
</div>
</div>
Use the not() filter or the :not() selector.
$('.parent div').not('.1').wrapAll('<div class="sub">');
Or alternatively:
$('.parent div:not(.1)').wrapAll('<div class="sub">');
You can also use div:first-child in place of .1 if you always want to ignore the first element.
If the element you want to keep out is not necessarily the first, you could use:
$(".parent div").not("div.1").wrapAll("<div class='sub'>");
Although, this will re-order your divs so that the wrap comes first, and the unwrapped element comes last. Not a problem when it's the first element, but if it's the third, for example, the output would be:
<div class='sub'>
<div class="1"></div>
<div class="2"></div>
<div class="4"></div>
<div class="5"></div>
</div>
<div class="3"></div>
Example:
http://jsfiddle.net/tomtheman5/3TL4M/
edit: Just saw #Corion's answer... This is essentially the same, but with some more information. I'll leave it up.