jQuery - Get next element, regardless of DOM placing
I currently have the the following HTML structure:
<div class="article-preview">
<h1><a href="">Title</a></h1>
<a class="pic-link" title="" href=""><img src="" /></a>
<div/>
When the image link or the heading link is hovered, I want to change the color/border-color of both.
I tried to use the next()
filter:
$('.article-preview h1 a').mouseover(function(){
$(this).animate({
color: "#94c4c1"
}, 10);
$(this).next('img').animate({
borderTopColor: '#94c4c1',
borderRightColor: '#94c4c1',
borderBottomColor: '#94c4c1',
borderLeftColor: '#94c4c1'
}, 200);
});
$('.article-preview h1 a').mouseout(function(){
$(this).animate({
color: "#000000"
}, 200);
$(this).next('img').animate({
borderTopColor: 'white',
borderRightColor: 'white',
borderBottomColor: 'white',
borderLeftColor: 'white'
}, 200);
});
$('.article-preview a img').mouseover(function(){
$(this).animate({
color: "#94c4c1"
}, 10);
$(this).parent().find('a:first').animate({
borderTopColor: '#94c4c1',
borderRightColor: '#94c4c1',
borderBottomColor: '#94c4c1',
borderLeftColor: '#94c4c1'
}, 200);
});
$('.article-preview h1 a').mouseout(function(){
$(this).animate({
color: "#000000"
}, 200);
$(this).parent().find('a:first').animate({
borderT开发者_如何学CopColor: 'white',
borderRightColor: 'white',
borderBottomColor: 'white',
borderLeftColor: 'white'
}, 200);
});
This doesn't work, because next
only looks in the until the end of the heading. Is there a way to search for the next img element (from the selected element, in this case the <a>
Tag), regardless of the placing in the DOM?
Try using
$('.article-preview h1 a').hover(function() {
$(this).parent().next('a').find('img').animate({
borderTopColor: 'yellow',
borderRightColor: 'yellow',
borderBottomColor: 'yellow',
borderLeftColor: 'yellow'
}, 200);
});
You could use this
function getNextElement(currElement, className)
{
var elements = $('.' + className);
var currentIndex = elements.index(currElement);
return elements[currentIndex + 1];
}
... and add error handling for edge cases
Assuming you are sticking with this format, you could use
$(this).parent('h1').next('a').find('img').animate({...})
As for the ultra general solution, I'm not sure. I'll test and get back to you (I leave this answer as community wiki if anyone wishes to edit this answer to elaborate).
its better to do children instead of find find sometimes doesn't works in IE.
$('.article-preview h1 a').hover(function() {
$(this).parent().next('a').children('img').animate({
borderTopColor: 'yellow',
borderRightColor: 'yellow',
borderBottomColor: 'yellow',
borderLeftColor: 'yellow'
}, 200);
});
What you search for is an equivalent of XPath following
axis in jQuery. AFAIK it's not supported natively. You can add custom implementation to jQuery:
(function($){
$.fn.nextElementInDom = function(selector) {
var e = $(this);
checkNextSubtree: while (true) {
if (e.next().length) {
e = e.next();
while (!e.is(selector)) {
if (e.children().first().length) {
e = e.children().first();
continue;
} else {
continue checkNextSubtree;
}
}
return e;
} else {
if (e.parent().length) {
e = e.parent();
continue checkNextSubtree;
} else {
return null;
}
}
}
};
})( jQuery );
Usage:
$('.article-preview h1 a').nextElementInDom('img')
The implementation traverses remainder of tree after initial element. It's inspired by this solution found thanks to Nina's comment. Unlike it, it's based only on primitive operations (next sibling, parent, first child) and not recursive.
精彩评论