Check if next element has a specific class - javascript

html structure:
<div class="row">
<div class="span"></div>
<div class="span"></div>
<div class="navMenu">
<ul>
<li>Link 1</li>
<li>Link 1</li>
</ul>
</div>
</div>
Then I am adding a "new" div just after the above html:
<div class="row">
<div class="span"></div>
<div class="span"></div>
<div class="navMenu">
<ul>
<li>Link 1</li>
<li>Link 1</li>
</ul>
</div>
</div>
<div class="new"></div>
$(".navMore li a").each(function() {
$(this).on("click", function() {
$('<div class="new"></div>').insertAfter($(this).closest('.row'));
$('<div class="span"></div>').appendTo('.new');
});
});
Finally I need to check if a div with class .new exists RIGHT AFTER the div containing the menu, and if so add a .span div in it, and if a div with class .new doesn't exist, then create it and then insert a div with class .span in it:
$(".navMore li a").each(function() {
$(this).on("click", function() {
if($(this).next().hasClass("new")){
$('<div class="span"></div>').appendTo('.new');
}
else {
$('<div class="new"></div>').insertAfter($(this).closest('.row'));
$('<div class="span"></div>').appendTo('.new');
}
});
});
It is IMPORTANT that the new div with class .new is a div with such a class right next the div container the menu. The reason why is because I will many menus with many different .row divs, so I wanted to target the correct one.
The above final code doesn't work tho

You don't need the each loop - also you notice how .new and .row are siblings?
$(".navMore li a").on("click", function() {
var $el = $(this);
var $row = $el.closest('.row'); // <-- get to row first
if($row.next('.new').length){ // check next element
$('<div class="span"></div>').appendTo('.new');
}
else {
$('<div class="new"></div>').insertAfter($row);
$('<div class="span"></div>').appendTo('.new');
}
});
You also have your classes mixed up.. So you need to make sure they match
<div class="navMenu"> <!-- <-- here -->
<ul>
<li>Link 1</li>
<li>Link 1</li>
</ul>
</div>
and
$(".navMore li a") // <-- here

The foreach loop is unnecessary. You can just bind a click event to all the items in a selector directly rather than looping through a set and binding them individually.
I would bind the click event to the .row divs since the click event will bubble up ... this will make your selectors very easy to test if the next sibling has a .new class.
$('.row').click(function() {
var newDiv = $(this).next();
if(newDiv.hasClass('new')){
$('<div class="span"></div>').appendTo(newDiv);
}
else {
newDiv = $('<div class="new"></div>');
newDiv.insertAfter($(this));
$('<div class="span"></div>').appendTo(newDiv);
}
});
Edit:
The reason why I chose to bind to the .row is because part of the DOM rules about how events propagate up to their parents says that if someone clicks an Anchor tag then it will send the event up the parents in the DOM. So this means that if we are listening for a click on a parent of an tag, it will appear as if the click came from that said parent (in this case, a .row div).

$(".navMenu ul li a").on("click", function () {
if ($(this).closest('.row').next('.new').length) {
$('<div class="span"></div>').appendTo('.new');
} else {
$('<div class="new"><div class="span">This is a span.</div></div>').insertAfter($(this).closest('.row'));
}
});

Related

Add active class to <li> and leave it after hover

I have this code
<script>
$("li").hover(
function () {
$(this).addClass('active');
},
function () {
$(this).removeClass('active');
}
);
</script>
In order to add class active to my li in a menu.
<ul class="list-first-level">
<div about="" typeof="" class="ds-1col entity entity-paragraphs-item paragraphs-item-modulo-de-enlaces-item view-mode-modulo_de_enlaces_01_d clearfix">
<li id="elm" class="active always">
Undergraduate programmes
<ul>
<li>
Law
</li>
</ul>
</li>
</div>
</ul>
I need to not remove the active class after Im not hover on the element.
Just use this:
$("li").hover(function(){
$(this).addClass("active");
});
Although, you will end up with many active LI and does not provide a good UX.
When you hover over an element, remove the 'active' class from all li elements then add it back to the current element. This still means that if the user moves away from the last, hovered element - that element will remain in an 'active' state.
<script type="text/javascript">
$("li").hover(
function () {
$("li").removeClass('active');
$(this).addClass('active');
}
);
</script>

add active class to main menu using javascript

I have searched a lot for adding active class to the parent menu using javascript.
I found many more examples but not a single one is working for me, below is my code
HTML
<div id="menu1" class="hmenu">
<ul>
<li>Item1
<ul>
<li>SubItem1
<ul>
<li>SubSubItem1</li>
<li>SubSubItem2</li>
</ul>
</li>
<li>SubItem2 </li>
<li>SubItem3
<ul>
<li>SubSubItem1</li>
<li>SubSubItem2</li>
</ul>
</li>
</ul>
</li>
<li>Item2</li>
<li>Item3
<ul>
<li>SubItem1
<ul>
<li>SubSubItem1</li>
<li>SubSubItem2</li>
</ul>
</li>
</ul>
</li>
</ul>
<br style="clear: left" />
</div>
My requirement is when i click on SubItem1 then both Item1 and SubItem1 should be active.
And when i click on SubSubItem1 then SubSubItem1 ,SubItem1 and Item1 should be active.
Means when click on any link then its all parent link and the same link should be active.
I have tried with this javascript code :
$(document).ready(function () {
$('.hmenu ul li ul').find('li').click(function () {
//removing the previous selected menu state
$('.hmenu').find('li.active').removeClass('active');
//adding the state for this parent menu
$(this).parents('li').addClass('active');
});
});
Actually i don't have any experience with javascript coding and unable to figure out the problem in my code.
Can anyone suggest me for the same.
The issue comes from .find('li').click().
As you use nestsed <li>, this will cause the event to be fired two times when you click on a child <li>. This causes problems. Can not you add the click() to <a> elements?
$(document).ready(function () {
$('.hmenu a').click(function () {
//removing the previous selected menu state
$('.hmenu').find('li.active').removeClass('active');
//adding the state for this parent menu
$(this).parents("li").addClass('active');
});
});
It works just fine: https://jsfiddle.net/6put8tdx/
Note that your page will be bumped to the top while clicking to a tab because of # anchor. If you want to prevent this, you may pass the event to the function .click(function (event) {...} and add event.preventDefault inside.
If you need the click target to be the LI element (as opposed to Delgan's answer)
you can use .not() over the targeted LI's parents to prevent messing with the bubbling event targets:
$(document).ready(function () {
$('.hmenu').find('li').click(function(event) {
event.preventDefault(); // Prevent page jumps due to anchors
var $par = $(event.target).parents("li"); // get list of parents
$(".hmenu .active").not( $par ).removeClass("active"); // not them
$(this).addClass('active'); // let the event propagation do the work
});
});
$(document).ready(function () {
$('.hmenu').find('li').click(function(event) {
event.preventDefault();
var $par = $(event.target).parents("li");
$(".hmenu .active").not($par).removeClass("active");
$(this).addClass('active');
});
});
.active > a{
background: gold;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="menu1" class="hmenu">
<ul>
<li>Item1
<ul>
<li>SubItem1
<ul>
<li>SubSubItem1</li>
<li>SubSubItem2</li>
</ul>
</li>
<li>SubItem2 </li>
<li>SubItem3
<ul>
<li>SubSubItem1</li>
<li>SubSubItem2</li>
</ul>
</li>
</ul>
</li>
<li>Item2</li>
<li>Item3
<ul>
<li>SubItem1
<ul>
<li>SubSubItem1</li>
<li>SubSubItem2</li>
</ul>
</li>
</ul>
</li>
</ul>
<br style="clear: left" />
</div>
To better understand the above
The following example works out-of-the-box, and the clicked one and all it's LI parents get the "active" class.
Why? Cause the event target is li, means any li of .hmenu - so that click is attached to any of them, and clicking the subsub LI the event will propagate to the LI parents - triggering the same click behavior (this add class)!
$(".hmenu").on("click", "li", function(){
$(this).addClass("active"); // Wow! Event propagation rulez!!
});
But we need to remove existing .active and here it gets messy...
$(".hmenu").on("click", "li", function(){
$(".active").removeClass("active"); // triggered on every event bubble :(
$(this).addClass("active"); // leaving only the main parent with active class
});
That's caused by the concurrency that happens while the event bubbles and triggers the same actions for the parent elements.
One way to prevent that concurrency would be using a setTimeout of 1ms:
$(".hmenu").on("click", "li", function(){
$(".active").removeClass("active");
setTimeout(function(){ // Let the previous finish the bubbling mess
$(this).addClass("active"); // Yey! all fine! Every LI has the active class
}, 1);
});
But here the timeout of 1ms can lead to visual "blinking" issues.
Try this:
$(function () {
$("li a")
.on("click", function () {
$(this).toggleClass("active");
$(this).closest("ul").parent().children("li a").toggleClass("active")
.parent().parent().parent().children("li a").toggleClass("active");
});
});
fiddle
Traverse from the clicked element. And use toggleClass() to avoid the mundane checking if hasclass removeClass ...

Add class to element this element is child of?

I'm trying to add a class "active" to the li that was clicked on, however in my script, I'm retrieving the a that was clicked on since I'd like to retrieve the href of "". What's the script to do that?
<ul class = "tab-links">
<!-- Each tab is Anchored to its Contents -->
<li class = "active">Panel 1</li>
<li>Panel 2</li>
<li>Panel 3</li>
<li>Panel 4</li>
</ul>
<script type="text/javascript">
$(function ()
{
//Listen for tab-links clicks
$('.tab-panels .tab-links a ').on('click', function (e)
{
//Remove current active panelToShow
$('.tab-panels .tab-links li.active').removeClass('active');
//Make panelToShow link active
//??How do I addClass active to the li that was clicked on, when "this" refers to an "a" element?
//????$(this).addClass('active');
... })
}
</script> ...
You use parent
$(this).parent("li").addClass('active');
You can simply do:
$(this).parent('li').addClass('active');
This will add the class active to the nearest parent of the link which is a li

Add new div in a nested HTML structure

I have this html structure and code:
<ul class="navMore">
<li>Link 1</li>
<li href="#"><a>Link 2</a><?li>
</ul>
<div class="row-fluid"></div>
$(".navMore li a").each(function() {
$(this).on("click", function() {
$('<div class="row-fluid"></div>').insertAfter($(this).closest('.row-fluid'));
$('<div id="content" class="span4"></div>').insertAfter($(this).next('.row-fluid'));
});
});
I need to add a new .row-fluid div just after the previous .row-fluid
Expected result:
<ul class="navMore">
<li>Link 1</li>
<li href="#"><a>Link 2</a><?li>
</ul>
<div class="row-fluid"></div>
<div class="row-fluid"></div>
But if we already added a new .row-fluid div, then the #content div should be put inside this newly added row-fluid div
How do I achieve this?
<ul class="navMore">
<li>Link 1</li>
<li href="#"><a>Link 2</a><?li>
</ul>
<div class="row-fluid"></div>
<div class="row-fluid">
<div id="content" class="span4"></div>
</div>
Finally, how can I do that if we have inserted 3 #content div, start again with a new .row-fluid div and all again?
Here you go.
<script type="text/javascript" >
$(document).ready(function () {
$(".navMore li a").click(function() {
var countOfDiv = $(".row-fluid").length;
if(countOfDiv < 2)
$('<div class="row-fluid"></div>').insertAfter(".row-fluid");
else
$(".row-fluid:last").html("<div id=\"content\" class=\"span4\"></div>");
});
});
</script>
Link 1
Link 2
function insertRow() {
$newdiv = $("<div class='row-fluid'/>");
$newdiv.insertAfter(".row-fluid:last");
return $newdiv;
}
// assume you're passing a content object into the routine
function insertContent( contentObj) {
$lastRow = $(".row-fluid:last");
if( $lastRow.children().length >= 3) {
insertRow().append( contentObj);
} else {
$lastRow.append( contentObj);
}
return contentObj;
}
Eventually I went with this:
$(".navMore li a").on("click", function() {
var $el = $(this);
var $row = $el.closest('.row');
if($row.next('.new').length){
$('<div class="span"></div>').appendTo('.new');
}
else {
$('<div class="new"></div>').insertAfter($row);
$('<div class="span"></div>').appendTo('.new');
}
});

Hide selected by anchor's href

I'm trying to figure out a function that will allow me to hide divs and show them if referring link is clicked.
Hard to explain but here is what I am looking for:
<ul>
<li>Link 1</li>
<li class="active">Link 1</li>
<li>Link 1</li>
<ul>
<div id="id-1">Some content</div> // Hidden
<div id="id-2">Some content</div> // This should only show in document
<div id="id-3">Some content</div> // hidden
Whenever other anchor is being clicked other divs should hide.
I hope his make sense and thank you for your help in advance
Dom
You can use something like this (untested so may need tweaking):
$(document).ready(function() { //fires on dom ready
$("a").click(function(e) { //assign click handler to all <a> tags
$(".classForYourDivs").hide(); //hide all divs (put class on ones you want to hide)
var element = $(e.target);
var href = element.attr("href"); //get the attribute
$(href).show(); //show the relevent one
return false; //important to stop default click behavior of link
});
});
Incidentally you should consider using something other than the href to store this information... take a look at the docs for the jquery data() function
Add a class to the ul and the divs.
<ul class="myUL">
<li>Link 1</li>
<li class="active">Link 1</li>
<li>Link 1</li>
<ul>
<div id="id-1" class="myDivs">Some content</div> // Hidden
<div id="id-2" class="myDivs">Some content</div> // This should only show in document
<div id="id-3" class="myDivs">Some content</div> // hidden
then in CSS,
.myDivs { display: none; }
and Try below js code,
var $myDivs = $('.myDivs');
$('.myUL a').on('click', function () {
$myDivs.hide();
$($(this).attr('href')).show();
});
DEMO: http://jsfiddle.net/LYKVG/
$("body").on("click","a", function(){
var divtoshowselector = $(this).attr("href");
$(divtoshowselector).show().siblings().hide();
})
http://jsfiddle.net/
html
<ul>
<li>Link 1</li>
<li class="active">Link 2</li>
<li>Link 3</li>
<ul>
<div id="id-1">Some content 1</div>
<div id="id-2">Some content 2</div>
<div id="id-3">Some content 3</div>​
css
div {display: none;}
javascript/jquery
$("a").click( function(e) {
e.preventDefault();
var elId = $(this).attr('href');
$('div').hide();
$(elId).show();
});​
I've set up a fiddle for you, check out: http://jsfiddle.net/UsGag/
function currentActive()
{
return $("li.active a").attr("href");
}
$("div:not(" + currentActive() + ")").hide();
$("li a").on("click", function()
{
//hide old active div
$("div" + currentActive()).hide();
$("li").removeClass("active");
//activate new div
$(this).parent().addClass("active");
$("div" + currentActive()).show();
});
Hope this helps you, extend to your own needs. And just for completeness: Don't use the - in ids / classnames.
​
Try
$("a").click( function( ) {
var elId = $(this).attr("href");
$(elId).show().siblings("div[id^=id-]").hide();
});
Fiddle here

Categories