understanding jQuery parent, children and sibling - javascript

I am struggling to figure out where I am going with the current show and hide function I am trying to incorporate on my site. I have a drop down menu show and hide function similar to the one currently implemented at Hippodrome Mobile Casino. Which is identical to my HTML. My div class I am noticing with my Jquery when i click the next button .regNext it hides all three .regGroupContent divs. However i want to add and remove the active class which i current have as display:none on my site.
$('.regGroupContent').removeClass('active');
$('.regGroupContent').eq(0).addClass('active');
$('.regNext').click(function () {
var $this = $(this);
$('.regGroupContent').hide().removeClass('active');
$this.parent().children($('.regGroupContent')).show().addClass('active');
});
Html
<div class="vengeForm">
<div class="regGroupContent">
<div class ="fieldset">
<ul class="fieldset">
<li class="editor-next">
</li>
</ul>
</div>
</div>
</div>

This line has a bit of a syntax issue:
$this.parent().children($('.regGroupContent')).show().addClass('active');
In the children selector, you don't need a jQuery object, rather just the class name. Also, your .parent() selector is only going one level up, you need to get to the top of the element tree. Try changing it to:
$this.parents('.vengeForm').children('.regGroupContent').show().addClass('active');

Related

Change the style of an element when another element has class dynamically applied

I have a rollover menu that has a class applied to <li> elements on hover, which toggles the visibility of a div inside it.
The class is called "cbp-hropen" and is applied when the <li> is hovered.
I'd like to trigger the visibility of another completely separate element called "menuDimmer" when this class is applied to the <li>.
<div class="menuDimmer"></div>
<div id="menu" class="main">
<ul>
<li>
MENU
<div class="cbp-hrsub">content...</div>
</li>
<li>
MENU 2
<div class="cbp-hrsub">content...</div>
</li>
</ul>
So I'd like something similar to:
if ($("li").hasClass('cbp-hropen')) {
$(".menuDimmer").fadeIn(100);
} else {
$('.menuDimmer').fadeOut(100);
}
(sorry, I know that code is poor but just trying to get the message across)
This has to work dynamically, rather than on page load, as the trigger element itself is only active on hover.
You can use an event to add the class :
$('#id').on('mouseover',function(){
//addclass
}
then you remove the class of your div
$('#id').on('mouseout',function(){
//removeclass
}
You can use the MutationObserverAPI
to listen for DOM changes on specified elements. Take a look at the provided code in this question, as it shows how to use MutationObserver to detect class changes. The MDN doc linked above provides a more general example too.

Adding and removing classes not working

I've used this exact code on a different div element and it works perfectly. When I went to add the same code to another div element with a different id it registers the element has been clicked but it doesn't add or remove any of the classes.
$('#quoteClick').click(function(){
$('#cbox-1').addClass('displayCboxBackground');
$('#cbox-2').removeClass('displayCboxBackground');
$('#cbox-3').removeClass('displayCboxBackground');
$('#dbox-1').addClass('displayBlock');
$('#dbox-2').removeClass('displayBlock');
$('#dbox-3').removeClass('displayBlock');
console.log("clicked");
});
The html structure is as follows:
<div id="cbox-1">
<div id="dbox-1">
content...
</div>
</div>
<div id="cbox-2">
<div id="dbox-2">
content...
</div>
</div>
<div id="cbox-3">
<div id="dbox-3">
<div id="quoteClick">
a quote
</div>
</div>
</div>
JSFiddle: https://jsfiddle.net/m81c23cx/1/
In the fiddle you can see the content will changes when each header is clicked. When the "quoteClick" element is clicked I want it to change to the second headers content exactly how it does when the second header is clicked.
I can see in Chrome's console that when I click the div element that it highlights all the classes but it doesn't change any of them. I have the jQuery inside a document.ready() function so it should be waiting for the DOM to load and it works perfectly when I just write the lines into the console.
I'm surprised that nobody actually questioned your use of ids (instead of suggesting that you should double-check for dupes). The reason why this code is hard to debug is because it's too complicated. As a result, you'll have a hard time fixing issues similar to this in the future too.
Drop it, do it better.
I didn't even go through your fiddle. Instead, I'm going to propose that you change your approach altogether.
Update your HTML and use classes instead of ids. Something similar to this:
<div class="cbox">
<div class="dbox">
content...
</div>
</div>
<div class="cbox">
<div class="dbox">
content...
</div>
</div>
<div class="cbox">
<div class="dbox">
<div id="quoteAdvert">
a quote
</div>
</div>
</div>
Update your JavaScript and use this to get the context of the current box:
$('.cbox').click( function cboxClicked () {
// Remove the previous class from all .cbox & .dbox elements; we don't care which
$('.cbox').removeClass('displayCboxBackground')
$('.dbox').removeClass('displayBlock')
// Add a new class to the clicked .cbox & it's child .dbox
$(this).addClass('displayCboxBackground')
$(this).children('.dbox').addClass('displayBlock')
})
The beauty of this? You can have 1000 boxes, it'll still work. No need to add any extra lines of code.
Here's a fiddle showing it in action.
The example code you provided is not consistent with the jsfiddle you created.
In your fiddle, you use the jquery selector $('#quoteClick') but there is no element with that id. There is a #quoteAdvert element however. Change that and you'll see the click in the console.
The classList property returns a token list of the class attribute of the element in question. Luckily for us, it also comes with a few handy methods:
add - adds a class
remove - removes a class
toggle - toggles a class
contains - checks if a class exists
// adds class "foo" to el
el.classList.add("foo");
// removes class "bar" from el
el.classList.remove("bar");
// toggles the class "foo"
el.classList.toggle("foo");
// outputs "true" to console if el contains "foo", "false" if not
console.log( el.classList.contains("foo") );
// add multiple classes to el
el.classList.add( "foo", "bar" );

How to temporarily block selectable elements

I am working on a popup menu on my webpage. The menu contains various selectable items, and I would like to only allow selection of certain items after a top-selection has been made. Now I could hide all items lower-down, but that would make the popup look weird. I'd rather show them, but dimmed. My idea was to enclose the follow-up selections in a div, and have that div act as a blocker. Now the question is how to do it - I tried setting the z-index of the selBlocker div higher than the rest, also to give it absolute positioning, but didn't get anywhere yet. I am using a javascript library to handle the selections in general.
<div id="SelPopup" >
<div id="topSelect"></div>
<div id="selBlocker">
<div id="selectable2"></div>
<div id="selectable3"></div>
</div>
</div>
I would append a class to the items you dont want to select, and add the not() selector to your jQuery.
For example:
$("div:not('.selected').....
Instead of
$("div").....
Ofcourse you can add an opacity to the class .selected, to make it a little bit less visible.
You can try below:
Instead of using id for selection blocked element use class="selectBlocked" and for menu div use class="selectMenu"
<div id="SelPopup" >
<div id="topSelect" class="selectMenu"></div>
<div id="selBlocker1" class="selectMenu selectBlocked">
<div id="selectable2"></div>
<div id="selectable3"></div>
</div>
<div id="selBlocker4" class="selectMenu selectBlocked">
<div id="selectable5"></div>
<div id="selectable6"></div>
</div>
</div>
Now right jQuery for handling selection of menu and do nothing if selected menu is with class="selectBlocked"
$('.selectMenu').click(function(){
if($(this).hasClass("selectBlocked"))
return false;
// do your stuff if above condition fails
});
Thank you all for the suggestions, I actually found what I was looking for:
$("#selBlocker").css("pointer-events", "none");
This will nicely disable all interaction, and with
$("#selBlocker").css("pointer-events", "all");
I can restore it. Can add the change in opacity easily alongside it.

select a parent with jQuery

Hello I have some HTML that looks like this,
<div id="music_interests">
<ul class="interests">
<li >
<div class="interest inline">
<img src=""/>
<div class="interest_popup">
1 users have this interest.
Remove interest </div>
</div>
</li>
</ul>
When users clicks the remove button I need to select the parent div (in this case music_interests). How would I go about that?
I have tried doing the following,
$(this).parent().parent().parent().parent() but is there a more elegant way?
To complicate things futher I will not actually no the parents ID when in the app as the remove button occurs in 4 or 5 different areas on the page.
you should use closest()
$(this).closest('div#music_interests');
//find the nearest div with id "music_interests"
//if i omitted the id, it retrieves the div with class "interest_popup"
or parents()
$(this).parents('div:eq(1)');
//get ALL the ancestor divs (until it reaches root tag)
//since music_interests is just 2 levels up, use :eq(1)
If the ID of the DIV you want to remove is static you should only use the ID selector (not something like $("div#music_interests")) as the ID selector is directly mapped to the DOM function document.getElementsById which is pretty fast:
$("#music_interests").remove();
If the ID isn't static you could get the UL just like that:
$(function(){ //execute when page has been loaded
$(".remove").click(function(){ //attach click handler
var removeDiv = $(this).closest("ul").parent().remove(); //get next UL -> DIV is its parent
return false; //stop further processing of "click" event
});
});
if remove button always exist in ul tag (in all your 4 or 5 different areas) then you can use the following code.
$(this).closest("ul").parent()
in this case u don't even need to give id to DIV tags

jQuery click function using same classes

I have a dropdown function that I need to work only on the div clicked, not all (I have 14+ of the same classes on the page that need to be displayed when a certain one is clicked)
At the moment my jQuery is as follows.
$('.qacollapsed').hide();
$('.qa').click(function () {
$('.qacollapsed').slideToggle();
$(this).toggleClass('active');
});
Of course, that is toggling all qacollapsed classes when there is 14 on the page (Q&A)
Is there a way for it to only drop down the one that is clicked?
the HTML
<div class="qa">
<h4 class="question"> </h4>
</div>
<div class="qacollapsed">
<p> </p>
</div>
It would be helpful to provide a snippet of HTML here, but I'll take a guess at the structure of your markup for now..
Instead of referencing all .qacollapsed elements, you need find elements that are close to the .qa that was clicked, e.g.:
$('.qa').click(function () {
$(this) // start with the clicked element
.find('.qacollapsed') // find child .qacollapsed elements only
.slideToggle();
$(this).toggleClass('active');
});
This will work if .qacollapsed is inside .qa - if not, you might need to use next (for siblings), or one of the other jQuery tree traversal methods.
Yo could find() it or use this as a context in the selector to choose only a descendent of the clicked object
$('.qa').click(function () {
$('.qacollapsed', this).slideToggle();
//You could do $(this).find('.qacollapsed').slideToggle();
$(this).toggleClass('active');
});
Check out the jQuery selectors and why not just use $(this)?
$('.qacollapsed').hide();
$('.qa').click(function () {
$(this).toggleClass('active').next().slideToggle();
});
Personally, I'd give all the divs IDs, the clickable bit being the ID of the question in the database for example, and the answer just being id='ID_answer' or something, then use jquery to slide in the div with the id corresponding to the link clicked, ie
Var showIt = $(this).attr('id') + '_answer'
$('.qacollapsed').not('#'+showIt).hide();
$('#'+showIt).slideToggle;
That will hide all the divs without that ID and show the required one.
Dexter's use of .next above looks simpler though, I've not tried that as being relatively new to jquery too.

Categories

Resources