jquery .next isn't working? - javascript

take this simple code:
<div id="container">
<div class="box">abc</div>
<div class="box" id="secondbox">abc</div>
<div>generic</div>
<div>generic</div>
</div>
Now I add the class box to let's say the last div generic:
$('#container div:last').addClass('box');
Now if i try to select the next .box with this it doesnt' work:
$('#secondbox').next('.box')
returns .length=0

I presume what you actually mean is #container div:last.
next does not find the next element that matches a selector. It finds the next sibling element. If you supply a selector, it tests the element against that selector. If the test fails, an empty selection (i.e. length == 0) is returned.
You need nextAll:
$('#secondbox').nextAll('.box').first();

You should replace $('#container p:last').addClass('box'); with $('#container div:last').addClass('box');
And as lonesomeday said. You should use nextAll selector.

Related

jQuery - how to find element inside following child?

I need the jQuery statement to find ".findme" in this code:
$('.clicky').click(function() {
// the .find() method doesn't do it
$(this).find('.findme').css('color', 'red');
});
<div class='clicky'></div>
<div class='brother'>
<div class='findme'>Here I am</div>
</div>
I've tried variations on .find() and .next() and .children() and I can't quite work it out....
this in $(this).find('.findme') actually refers to the element that was clicked (the div with the class clicky.
.find() actually searches the descendants of the element you call it on, and since "findme" is not within the "clicky" div, it doesn't find it.
You should instead use jquery's .next() function to get the sibling immediately following the "clicky" div (that's the "brother"), and then search there for the "findme" div.
$(this).next().find(".findme").css("color", "red");
you may can try to change
$('.clicky').click(function() {
// the .find() method doesn't do it
$(this).siblings().children('.findme').css('color', 'red');
});
and i think you miss the click me inner text for the div
<div class='clicky'>click me!!!</div>
<div class='brother'>
<div class='findme'>Here I am</div>
</div>

jquery remove removing from another element

According to here, jquery's remove function should work like so..
$('div').remove('selector');
Which I'm trying in this example.
HTML:
<div class="wrapper">
<p class="unwanted">This should be removed</p>
<p class="retained">This will remain</p>
</div>​
JavaScript:
jQuery(document).ready(function($) {
$('div').remove('p.unwanted'); //not working
//$('p.unwanted').remove(); //this works
});
​
It's not working. What am I doing wrong?
You've misunderstood what the documentation is saying. It's not looking for elements that are descendants of the matched elements that match the selector, it's simply filtering down the set of already matched elements to those that match the selector, and then removing them.
If you have this HTML:
<div class="wanted">Some text</div>
<div class="wanted">Some more text</div>
<div class="unwanted">Some unwanted text</div>
and then executed this jQuery:
$('div').remove('.unwanted');
then it would only remove that third <div> (the one with the unwanted class on it), because it first selects all <div> elements, and then only removes those that match the selector.
Example jsFiddle
You're trying to remove something that is both div and p.unwanted. The filter in remove() is applied to the current set of nodes, which in this case is all div elements.
Use the children set instead:
$('div').children().remove('p.unwanted');
You should use the following:
$('p').remove('.unwanted');
Argument in remove works as a filter. So here, you first select all <p> elements and then remove only those which have class unwanted.
DEMO: http://jsfiddle.net/qwXSw/1/
try this
$(document).ready(function() {
$('div').find('p.unwanted').attr('class', '');
});

Getting the next element in a div with jquery

Say that we have this html code
<div id="test">
<h2>Title</h2>
<p>lorem ipsum</p>
</div>
And this jQuery
$("#test h2").text("Changed Title");
Now what is the correct way to continue down to the <p> and also change it's text, without going up one level.
Like next() will only look for the next h2, but is there something that gets the sibling independent of element type. Something like next("p"); maybe?
next chooses the next element: by default it does not only select an element of the same type.
$('#test h2').next(); // selects the p
$('#test h2').next('p'); // selects the p
$('#test h2').next('h2'); // does not select the p
Unless you provide a selector, next will choose the next sibling element. You can therefore do this:
$('#test h2').text('Changed title').next().text('Changed text');
The command your looking for is siblings("p")
Here is your example, updated:
$("#test h2").text("Changed Title").siblings('p').text('test');
.next( 'p' ) will do the trick:
$("#test h2").text("Changed Title")
.next( 'p' )
.text( 'Another change' );
From the jQuery docu:
Get the immediately following sibling of each element in the set of matched elements. If a selector is provided, it retrieves the next sibling only if it matches that selector.
See example fiddle here.
.next('p') will indeed work. Just chain it at the end. like this:
$('#test h2').text("Changed Title").next('p').text('I changed too');
$("#test h2").text("Changed Title").siblings().text("");
Just like you suggested,
$("#test").next("p").text('yada');
or even better:
$("#test h2").text("Changed Title").next("p").text('yada');
Exactly, you can do it by using the .next('p') method:
$("#test h2").next('p').text("...");

find index of child using jQuery?

If I have an html structure like:
<div id="parent">
<div class="child first">
<div class="sub-child"></div>
</div>
<div class="child second">
<div class="sub-child"></div>
</div>
<div class="child third">
<div class="sub-child"></div>
</div>
</div>
and I have a click handler defined through ($('#parent.child')).click() and then I click on the div with the class of second (first, second, third classes have simply been added to make demo clearer) is there a simple way to get the number 1 as it is the second child? (0 based index)?
Something like $(this).index
Just have a look at the jQuery API. The method you suggest, index, is exactly right:
$('#parent .child').click(function() {
var index = $(this).index();
});
From the docs:
If no argument is passed to the .index() method, the return value is
an integer indicating the position of the first element within the
jQuery object relative to its sibling elements.
Also note that I've changed the selector slightly from your example. I'm guessing that was just a typo in your question though. #parent.child will look for an element with ID "parent" and a class of "child", but you actually want #parent .child (note the space) to find elements with class "child" that are descendants of an element with ID "parent".
The index() method can be used for getting the position of an element inside a collection. In basic circumstances, $(this).index() should work.
But with more specific collections, you can get the position with collection.index(item). Imagine adding something simple into your #parent that should not be counted when measuring index() (a span, img, anything). With the simple method, your code is likely to break, but with the specific method, it won't.
Something like this should work for you:
var $children = $('#parent .child').click(function​ () {
console.log($children.index(this));
});​
jsFiddle Demo

Can anyone explain this bizarre behavior in jQuery next?

It works:
<div class="xpav">
Create
</div>
<div class="apr" style="display: none;">
sometext
</div>
<script>
$('.xpav').click(function() {
$(this).next(".apr").slideDown("fast");
})
</script>
It doesn't:
<div class="xpav">
Create
</div>
<br />
<div class="apr" style="display: none;">
sometext
</div>
<script>
$('.xpav').click(function() {
$(this).next(".apr").slideDown("fast");
})
</script>
Why breaks it?
.next() only looks at the element that comes after the given element, then checks that element against the selector if it's provided. In your second example, since the br is there and doesn't have the apr class, it isn't picked up. From the API docs:
Description: Get the immediately following sibling of each element in the set of matched elements. If a selector is provided, it retrieves the next sibling only if it matches that selector.
Your second example requires the use of .nextAll() instead to search through all the next siblings:
$('.xpav').click(function() {
$(this).nextAll(".apr").slideDown("fast");
});
To pick up only the first .apr that's matched, use .eq(0):
$('.xpav').click(function() {
$(this).nextAll(".apr").eq(0).slideDown("fast");
});
under my impression next() only works if the sibling objuect is the same DOM tage,
what does work is:
$('.xpav').click(function() {
console.log($(this).next(".apr"));
$(this).siblings(".apr").slideDown("fast");
})
It's exactly that what the documentations says: "Description: Get the immediately following sibling of each element in the set of matched elements. If a selector is provided, it retrieves the next sibling only if it matches that selector."
http://api.jquery.com/next/
Because next() takes you to the immediate next DOM element which is <br />. Why not use this:
$(".apr").slideDown("fast");
Simply because you are using the next() method in your code. The next DOM element from $('.xpav') in the second version of your code is a <br />, and since that doesn't match the filter, it doesn't slide anything down!
If you want it to work, you should consider using nextAll() instead of next(), as the latter ONLY gets the very next DOM element, where the former gets all siblings that are after itself in the DOM.

Categories