How to get the sibling element of a parent element using jQuery - javascript

Today I was trying to trigger the tooltip of a particular element when I hovered over a different element. I'm not that experienced in jQuery, but I eventually got this to work reading through the docs. Afterwards, I saw how I referenced the target element and it seemed really convoluted. I was wondering if there were better methods that could produce the same results.
The HTML I'm working with is as follows:
<div class="item">
<h3 class="level-title">ITEM 1
<span class="level-label" data-toggle="tooltip" data-placement="top" data-animation="true" title="Tooltip text that pops up">Title Text
</span>
</h3>
<div class="level-bar">
<div class="level-bar-inner" data-level="70%">
</div>
</div>
</div>
<div class="item">
<h3 class="level-title">ITEM 2
<span class="level-label" data-toggle="tooltip" data-placement="top" data-animation="true" title="Tooltip text that pops up">Title Text
</span>
</h3>
<div class="level-bar">
<div class="level-bar-inner" data-level="70%">
</div>
</div>
</div>
In my HTML file I have 5 or so of those item sections. What I wanted was for the tooltip to not only trigger when a viewer moused over the "Title Text", but also when they hovered over the "level-bar-inner" div. To I achieve this I came up with the following piece of JavaScript:
jQuery(document).ready(function($) {
...
$('.level-bar-inner').hover(
function(e) {
$($($(e.target).parent().siblings()[0]).children()[0]).tooltip('show');
},
function(e) {
$($($(e.target).parent().siblings()[0]).children()[0]).tooltip('hide');
}
);
...
});
It seemed like a sloppy solution but a reasonable one. This method hinges on there being only one sibling and one child, which fortunately in my case was true for all the "item" sections in my HTML file. Which leads me to asking if there are better/more efficient methods of retrieving this element or even just toggling it's tooltip in general.

You can reference the element that raised the event using the this keyword. You can also use jQuery's DOM traversal methods, instead of repeatedly getting a DOMElement from a jQuery object, and turning it back in to a jQuery object again. Try this:
$('.level-bar-inner').hover(function(e) {
$(this).parent().prev().find('span').tooltip('show');
}, function(e) {
$(this).parent().prev().find('span').tooltip('hide');
});

You better go all the way up to the parent .item then it would be much easier to find the corresponding tooltip element:
$('.level-bar-inner').hover(
function() {
$(this).parents('.item').find('.level-label').tooltip('show');
},
function() {
$(this).parents('.item').find('.level-label').tooltip('hide');
}
);

You can use this other than e.target. Along with that the prev element is probably what you are looking for, then get the child by it's class:
$('.level-bar-inner').hover(
function(e) {
$(this).parent().prev().child(".level-label").tooltip('show');
},
function(e) {
$(this).parent().prev().child(".level-label").tooltip('hide');
}
);

Another way of doing it if you are following the same structure of adding data attributes to the elements, would be
$('.level-bar-inner').hover(function(e) {
$(this).closest('[data-toggle=tooltip]').tooltip('show');
}, function(e) {
$(this).closest('[data-toggle=tooltip]').tooltip('hide');
});

Related

Jquery toggle or hide/show elements that have their links on other parents by order?

I guys, let me start that if you have seen my problem on other post or reference redirect me to that. I couldn't find anything with my specific problem.
My problem is that i want to link actions from one child to a child on other parent like so:
<div class="parent1">
<i class="link1"></i>
<i class="link2"></i>
<i class="link3"></i>
</div>
<div class="parent2">
<div class="logo-case"></div>
<div class="logo-case"></div>
<div class="logo-case"></div>
</div>
I know the js is not right (duh) but i want to illustrate an ideia of what I'm trying to accomplish.
$('.parent1 i').each(function() {
$(this).click(function(){
$('**all** .logo-case').css("height", "0");
$(' **this** .logo-case').css("height", "100%");
)};
});
Now I want that the first "i.link1" gives height to the first "logo-case" no matter of the classes added to "logo-case" which means "link1" always affects the first "logo-case" and so on.
Thanks in advance for any response.
Check out this fiddle: https://jsfiddle.net/6jaj5L0y/1/
I think it achieves what you are trying to do.
$('.parent1 i').each(function(idx, el) {
$(this).click(function(){
$(".parent2 .logo-case").css({height: '0px'})
.eq(idx).css({height: '100px'});
});
});

How to clone a jQuery object and its children, without references in IE11

I'm trying to clone a jQuery object, its children, and no references. My understanding is that clone() should accomplish this, but in IE11, the second time I try to append one of the child objects to the blank surrounding div, that child object no longer exists. You can see this by clicking "click me" twice in my snippet, using IE11.
I think my problem may be that the child references were cloned, so the blank div overwrote them, but may be wrong about this. So far, clone() has worked the best for cloning the parent element. I prefer to use jQuery rather than getElementsByClassName. I did not have luck using $.extend(true, {}, $('.allItems'));
I would appreciate any help with this!
window.$allItems = $('.carousel_item').clone();
$('.link').on('click', function(evt) {
evt.preventDefault();
$('.blue').html('').append('<div id="bills"></div>');
$('#bills').append($allItems[0]);
});
.blue {
background-color: #d0e4f2;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
clickme
<div class="blue">
<div id="bills">
<div class='carousel_item'>
<img src='http://fillmurray.com/150/200'>
<div>
<span>Tomatoes</span>
</div>
</div>
<div class='carousel_item'>
<img src='http://fillmurray.com/200/200'>
<div>
<span>Film</span>
</div>
</div>
</div>
</div>
Solved this.
To append the carousel item more than once after appending a blank div, I needed to clone the DOM elements each time the function was called. I needed to add one line to the click listener:
$allItems = $allItems.clone();

Onclick my 'button' opens all buttons of the same type

So this is what I have right now
http://jsfiddle.net/Wpn94/1755/
The first part of the javascript is just calling in the jQuery lib. Since I don't have acces to the original files I use a custom css, js plugin (mind this all in done in wordpress).
In the fiddle if you click on one the the 'meer' it only opens the one you've clicked. If you press 'minder'it nicely closes the one you've clicked.
Now to the issue, on my testing area if I click one of these buttons the other 5 open as well, which ofcource is not the intended use.
Is there any solution which could fix this? I'mn not able to link to the testing enviroment since it's about a product which isn't released yet, so sadly I do not have permissions to do so.
Possibly the issue:
$('.wrapper').find('a[href="#"]').on('click', function (e) {
or
$(this).closest('.wrapper').find('.small, .big').toggleClass('small big');
I think the issue is in one of those two. Since I look for the wrapper class which all the 'buttons'have in common.
Any help would be greatly appreciated.
(structure of the element on the test area)
<div class="column withimage ">
<div class="column-inner">
<div class="image" style="background-image: url(http://eperium.com.testbyte.nl/wp-content/uploads/2016/08/Icoon_orientatie_v02.png)"></div>
<div class="txtwrap"><h4><center>ORIËNTATIE</center></h4>
<div class="wrapper">
<div class="small">
<p style="text-align: center;">
<span style="color: #000000; font-size: 16pt;">title</span><br>
<span style="color: #000000; font-size: 12pt;">text<br>more text week. </span></p>
</div>
<p style="text-align: center;"><a class="btn" href="#">Meer informatie</a></p>
</div>
What are you doing inside this function ?
$('.wrapper').find('a[href="#"]').on('click', function (e) {
You need to toogle your class on $(this) element, not to select all element with jquery again.
As closest doesn't seem to be reliable (maybe only in your test area) it is worth a try to navigate to the desired element with .parent()
$(this).parent().parent().find('.small, .big').toggleClass('small big');
If anyone is interested in the differences:
Difference between jQuery parent(), parents() and closest() functions.
According to this, closest should actually work but parent seems to be the saver way.
You can use Jquery's findByClass.
$('.className')
This will find all the elements use className.

Need a more elegant way of finding an element in the dom tree with jQuery

I have a few elements flying around in an element that need to be altered when the window finishes loading ($(window).load...)
When the script loads, I've been struggling to find a more elegant way of finding a string.
Noticeably below, you can also see the rampant re-use of parent and next operators...
I've tried closest but it only goes up the dom tree once (from what I understand) and parents has never really worked for me, but I could be using it wrong.
Ex.
$(window).load( function(){
if($(".postmetadata:contains('Vancity Buzz')").length){
$(this).parent().parent().next().next().next().next('.articleImageThumb img').hide();
}
});
HTML output this runs through looks like this:
<div class="boxy">
<div class="read">
<div class="postmetadata">Vancity Buzz</div>
<div class="articleTitle"></div>
</div>
<div class="rightCtrls"></div>
<div class="initialPostLoad"></div>
<div class="ajaxBoxLoadSource"></div>
<div class="articleImageThumb">
<a href="#">
<img src="image.png" class="attachment-large wp-post-image" alt=""/>
</a>
</div>
</div>
I think you want to do this:
$(".postmetadata:contains('Vancity Buzz')")
.closest('.read') //Closest will get you to the parent with class .read
.siblings('.articleImageThumb').hide(); //this will get you all the siblings with class articleImageThumb
this refers to window there not the element you are checking in the if condition.
Fiddle
I don't know if your intention is to have the empty anchor tag just by hiding the image. if so just add a find to it.
You can just do this
$('.articleImageThumb img').toggle($(".postmetadata:contains('Vancity Buzz')").length)
If there are multiple divs and you do need to traverse then there are multiple ways
$(".boxy:has(.postmetadata:contains('Vancity Buzz'))").find('.articleImageThumb img').hide()
or
$('.postmetadata:contains("Vancity Buzz")').closest('.boxy').find('.articleImageThumb img').hide()
or
$(".boxy:has(.postmetadata:contains('Vancity Buzz')) .articleImageThumb img").hide()
Have you looked into parents http://api.jquery.com/parents/ you can pass a selector like so:
$(this).parents('.boxy').find(".articleImageThumb")
Careful though, If there is a parent boxy to that boxy, parents() will return it and thus you find multiple .articleImageThumb.

jQuery: get a reference to a specific element without using id

I'm tinkering a bit with jquery to show a hidden div when a link is clicked. This should be fairly simple, but there's a flaw to it in this case. I have the following markup:
<div class="first-row">
<div class="week">
<p>Uge 2</p>
<p>(08-01-11)</p>
</div>
<div class="destination">
<p>Les Menuires</p>
<p>(Frankrig)</p>
</div>
<div class="days">4</div>
<div class="transport">Bil</div>
<div class="lift-card">3 dage</div>
<div class="accommodation">
<p><a class="show-info" href="#">Hotel Christelles (halvpension)</a></p>
<p>4-pers. værelse m. bad/toilet</p>
</div>
<div class="order">
<p>2149,-</p>
<p class="old-price">2249,-</p>
</div>
<div class="hotel-info">
<!-- The div I want to display on click -->
</div>
</div>
When I click the "show-info" link I want the "hotel-info" div to display.
My backend devs don't want me to use ids (don't ask me why..) and the above markup is used over and over again to display data. Therefore I need to be able to access the "hotel-info" div in the "first-row" div where the link is clicked.
I've tried to do something like:
$(document).ready(function() {
$('.show-info').click(function() {
var parentElement = $(this).parent().parent();
var lastElementOfParent = parentElement.find(".show-hotel");
lastElementOfParent.show();
});
});
But without a result :-/ Is this possible at all?
Any help is greatly appreciated!
Thanks a lot in advance!
Try this:
$('.show-info').click(function() {
$(this).closest('.accommodation').siblings('.hotel-info').show();
});
Even better imo, as it would be independent from where the link is in a row, if every "row div" has the same class (I assume only the first one has class first-row), you can do:
$(this).closest('.row-class').find('.hotel-info').show();
Reference: .closest, .siblings
Explanation why your code does not work:
$(this).parent().parent();
gives you the div with class .accommodation and this one has no descendant with class .hotel-info.
It is not a good idea to use this kind of traversal for more than one level anyway. If the structure is changed a bit, your code will break. Always try to use methods that won't break on structure changes.
You're right in not using an ID element to find the DIV you want :)
Use closest and nextAll
Live demo here : http://jsfiddle.net/jomanlk/xTWzn/
$('.show-info').click(function(){
$(this).closest('.accommodation').nextAll('.hotel-info').toggle();
});

Categories