Adding class to one element instead of all of them, example inside - javascript

So, I'm struggling here. I want to make an on click even that when I click on a navigation, it opens nested list and add class to parent list.
That part almost works, problem is that it adds that class to all elements from parent list.
<ul>
<li><div><p class="hidden">Test 1</p>
<ul class="shown">
<li>
<p>Inner 1</p>
</li>
</ul>
</div>
</li>
<li><div><p class="hidden">Test 2</p>
<ul class="shown">
<li>
<p>Inner 2</p>
</li>
</ul>
</div>
</li>
</ul>
<ul>
jque
$(document).ready(function () {
$('.shown').hide();
$('.hidden').click(function () {
var $answer = $(this).next('.shown');
if ($answer.is(':hidden')) {
$answer.show();
$('.hidden').addClass('color1');
} else {
$answer.hide();
$('.hidden').removeClass('color1');
}
});
});
css
.color1{
background:red;
}
jsfiddle
https://jsfiddle.net/Lc5n8k81/1/

here while adding and removing color1 class change $('.hidden') to $(this).. as $('.hidden') will add class to all element with .hidden class
Jsfiddle: https://jsfiddle.net/6moznpbr/
$(document).ready(function () {
$('.shown').hide();
$('.hidden').click(function () {
var $answer = $(this).next('.shown');
if ($answer.is(':hidden')) {
$answer.show();
$(this).addClass('color1');
} else {
$answer.hide();
$(this).removeClass('color1');
}
});
});

Inside your click handler, you want to refer to $(this) not $('.hidden') - the latter means all elements with class hidden:
$('.hidden').click(function () {
var $answer = $(this).next('.shown');
if ($answer.is(':hidden')) {
$answer.show();
$(this).addClass('color1');
} else {
$answer.hide();
$(this).removeClass('color1');
}
});
https://jsfiddle.net/Lc5n8k81/2/

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>

jQuery detect class of child element

I have a button, which when clicked I want to display two additional buttons Cancel and Confirm.
When o class is added a negative margin left is added and the button disappears.
$('.a_bttn_inner_action').click(function() {
if ($(this).children().find('.button')) {
$(this).parent().find('.button').queue(function(next) {
$(this).addClass('o');
next();
});
$(this).parent().find('.confirm.yes').delay(300).queue(function(next) {
$(this).removeClass('o');
next();
});
$(this).parent().find('.confirm.no').delay(100).queue(function(next) {
$(this).removeClass('o');
next();
});
} else if ($(this).children().find('.confirm.no')) {
$(this).parent().find('.confirm.yes').delay(300).queue(function(next) {
$(this).addClass('o');
next();
});
$(this).parent().find('.confirm.no').delay(100).queue(function(next) {
$(this).addClass('o');
next();
});
$(this).parent().find('.button').queue(function(next) {
$(this).removeClass('o');
next();
});
}
});
li.o {
margin-left: -800px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="bttn_inner_action">
<ul class="action">
<a href="#" class="a_bttn_inner_action">
<li class="button ">Do something...</li>
</a>
<a href="#" class="a_bttn_inner_action">
<li class="confirm no o">Cancel!</li>
</a>
<a href="#" class="a_bttn_inner_action">
<li class="confirm yes o">Confirm...</li>
</a>
</ul>
</div>
With the jQuery I have a problem here if($(this).children().find('.button')) and here else if($(this).children().find('.confirm.no')).
I want to detect which of the current element's children were selected by the class of the li element.
Is this possible?
I've tried if($(this).children().attr('class') == 'button') also doesn't work.
I believe this is what you are looking after. For checking children you can use
.find('.button').length
it will give back 0 or a positive integer so you can use it inside an if. In your code the first if was always true, so the other would never run.
$('.a_bttn_inner_action').click(function() {
if ($(this).find('.button').length) {
$(this).parent().find('.button').queue(function(next) {
$(this).addClass('o');
next();
});
$(this).parent().find('.confirm.yes').delay(300).queue(function(next) {
$(this).removeClass('o');
next();
});
$(this).parent().find('.confirm.no').delay(100).queue(function(next) {
$(this).removeClass('o');
next();
});
} else if ($(this).find('.confirm.no').length) {
$(this).parent().find('.confirm.yes').delay(300).queue(function(next) {
$(this).addClass('o');
next();
});
$(this).parent().find('.confirm.no').delay(100).queue(function(next) {
$(this).addClass('o');
next();
});
$(this).parent().find('.button').queue(function(next) {
$(this).removeClass('o');
next();
});
}
});
li.o {
margin-left: -800px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="">
<ul class="action">
<a href="#" class="a_bttn_inner_action only-here">
<li class="button ">Do something...</li>
</a>
<a href="#" class="a_bttn_inner_action">
<li class="confirm no o">Cancel!</li>
</a>
<a href="#" class="a_bttn_inner_action">
<li class="confirm yes o">Confirm...</li>
</a>
</ul>
</div>
To simply know which button is clicked, you can use the target property of the click event to get the html element clicked =>
$('.elements').on('click', function(e){
var $targer = $(e.target);
});
You can use the hasClass() jQuery method on a jQuery element, or the is() method, to test the properties of an jQuery/html element.
I rewrite your code snippet keeping the logic, but changing some html. Look at the tests of the clicked element (target).
Your html is malformed, because children of a list ul must be an li element.
So your html should be something like this :
<div class="bttn_inner_action">
<ul class="action">
<li class="a_bttn_inner_action">
Do something...
</li>
<li class="a_bttn_inner_action">
Cancel!
</li>
<li class="a_bttn_inner_action">
Confirm...
</li>
</ul>
</div>
$('.button').click(function(e) {
var $target = $(e.target);
if ($target.hasClass('do-something')) {
$('.button.confirm.yes').delay(300).queue(function(next) {
$(this).parent('li').removeClass('o');
next();
});
$('.button.confirm.no').delay(100).queue(function(next) {
$(this).parent('li').removeClass('o');
next();
});
} else if ($target.is('.confirm.no')) {
$('.button.confirm.yes').delay(300).queue(function(next) {
$(this).parent('li').addClass('o');
next();
});
$('.button.confirm.no').delay(100).queue(function(next) {
$(this).parent('li').addClass('o');
next();
});
}
});
li.o {
margin-left: -800px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="bttn_inner_action">
<ul class="action">
<li class="li_bttn_inner_action">
Do something...
</li>
<li class="li_bttn_inner_action o">
Cancel!
</li>
<li class="li_bttn_inner_action o">
Confirm...
</li>
</ul>
</div>
The event listener can be optiomized. With $('.class').click() function, listener is attached to each .class elements. Use $('parentElement').on('click', 'subElement', function(e){...}) instead to attach just one event listener to a parent element.
See .on() function on jQuery doc.
You could just check the count of children with button class.
if ($(this).find('.button').length > 0) {
// there are some
}
children() gets all the direct child elements of the selected elements. find() gets all the child elements all the way down the hierarchy.
So $(this).children() is going to select all the <li> elements, and then find() is going to look through all of the child elements of those <li> and not at the <li> itself
What you want is just
$(this).find('.button').length
//or
$(this).find('.confirm.no').length
//or you could just find the li itself and then test for the class
var button = $(this).find('li');
if(button.is('.button')){
} else if(button.is(".confirm.no")){
}
Also note do not test against the return of children() or find() as both will return a new jQuery object wither or not anything was actually found, so the result will always test as truthy.
You could also just put the click handler on the LI themselves and not worry about the invalid wrapping them in an anchor tag
$('ul.action li').click(function() {
var $this = $(this);
if($this.is('.button')){
} else if($this.is('.confirm.no')){
}
});
The answer is the exists() function.
The following statement:
$(this).children().find('.button')
returns a JQuery object whose length is zero even there is no element selected.
So, if ($(this).children().find('.button')) is always going to be passed.
Either you can check the length of the return object or use JQuery exists() function.
Details are here.

Javascript adding styling to element with same class

I am making a dropdown menu in a dropdown, I want that I have a few head items and if you click on one, the dropdown in that head item is displayed as a block element. But the problem is that they all have the same class and when I want to add a class all the dropdowns inside the head items get that class. What am I doing wrong here?
jQuery(document).ready(function(){
var click = false;
jQuery(".navbar-collapse .nav li").click(function() {
if(click == false) {
jQuery(".navbar-collapse .nav li ul").addClass('clicked');
click = true;
} else {
jQuery(".navbar-collapse .nav li ul").removeClass('clicked');
click = false;
}
});
});
.clicked {
display: block !important;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<ul class="nav menu">
<li class="item-101 default deeper parent">
Home
<ul class="nav-child unstyled small clicked">
<li class="item-124">
Maandmail
</li>
</ul>
</li>
<li class="item-102 default deeper parent">
Contact
<ul class="nav-child unstyled small clicked">
<li class="item-125">
Contact pagina
</li>
</ul>
</li>
</ul>
Does anyone know why this is happening and how to fix this issue?
You have to make the code look at the specific UL relative to the item you've clicked on:
jQuery(document).ready(function() {
var click = false;
jQuery(".navbar-collapse .nav li").click(function(e) {
if (click == false) {
jQuery(e.currentTarget).find("ul").addClass('clicked');
click = true;
} else {
jQuery(e.currentTarget).find("ul").removeClass('clicked');
click = false;
}
});
});

Changing class of all li elements javascript/jquery button

I am working on a site with an accordion style script i've found. I'm quite new to jquery/javascript, so please bear with me...
My basic page opens an accordion, where the first one is locked open, and the other ones opens/closes if pressed. What keeps my top panel locked open is a
<li class="locked">.
The other panels have only
<li>
no class. I guess I can call them
<li class="somethingelse">
I want a button in my top panel that changes all the
to
<li class="locked">, so that the user can view the entire site.
I have tried:
<div>
<ul>
<li class="locked">Something
<button onclick="myFunction()">Click me</button>
</li>
<li id="abcd" class="somethingelse">somethingelse</li>
<li id="abcd"class="somethingelse">somethingelse</li>
</ul>
</div>
<script>
function myFunction() {
document.getElementById("abcd").class = "locked";
}
</script>
In plain JavaScript, I'd suggest:
function myFunction() {
// retrieves a NodeList of all <li> elements that do not
// have the 'locked' class-name:
var liElements = document.querySelectorAll('li:not(.locked)');
// uses Array.prototype.forEach to iterate over the array-like
// NodeList:
Array.prototype.forEach.call(liElements, function (li, index, list) {
// first argument ('li' ): the current array-element,
// second argument ('index'): unused, the index of the current
// array-element in the array,
// third argument ('list'): the array itself
// adding the 'locked' class-name to the list of classes
// of the current node:
li.classList.add('locked');
});
}
li {
opacity: 0.3;
}
li.locked {
opacity: 1;
}
<div>
<ul>
<li class="locked">Something
<button onclick="myFunction()">Click me</button>
</li>
<li class="somethingelse">somethingelse</li>
<li class="somethingelse">somethingelse</li>
</ul>
</div>
<script>
function myFunction() {
var liElements = document.querySelectorAll('li:not(.locked)');
Array.prototype.forEach.call(liElements, function (li, index, list) {
li.classList.add('locked');
});
}
</script>
Further, I'd suggest binding the event-handling in JavaScript, rather than using in-line HTML attributes (onclick, etc), which makes for easier long-term maintenance (since everything's updated in the same place, and you don't have to remember where all the event-handling was assigned):
function myFunction() {
var liElements = document.querySelectorAll('li:not(.locked)');
Array.prototype.forEach.call(liElements, function(li, index, list) {
li.classList.add('locked');
});
}
// finding the first element that matches the CSS selector.
// adding the named function (myFunction) as a 'click'
// event-handler:
document.querySelector('li.locked button').addEventListener('click', myFunction);
li {
opacity: 0.3;
}
li.locked {
opacity: 1;
}
<div>
<ul>
<li class="locked">Something
<button onclick="myFunction()">Click me</button>
</li>
<li class="somethingelse">somethingelse</li>
<li class="somethingelse">somethingelse</li>
</ul>
</div>
References:
CSS:
Negation (:not()) pseudo-class.
JavaScript:
document.querySelector().
document.querySelectorAll().
EventTarget.addEventListener().
Element.classList.
You should be changing element class as below
document.getElementById("abcd").className = "locked";
If you want to select more then one element use class name:
var nodes = document.getElementsByClassName("somethingelse");
So your final function will look like:
function myFunction() {
var nodes = document.getElementsByClassName("somethingelse");
var arr = Array.prototype.slice.call(nodes);
arr.forEach( function(node) {
node.className = "locked";
});
}
li {
color: #000000;
}
li.locked {
color: #ff0000;
}
<div>
<ul>
<li class="locked">Something
<button onclick="myFunction()">Click me</button>
</li>
<li id="abcd" class="somethingelse">somethingelse</li>
<li id="abcd" class="somethingelse">somethingelse</li>
</ul>
</div>

Links in dropdown menu aren't being followed

When user click on ABC, it should go to abc.php. But it wont. If I return true as follows in jquery code, it wont work the slide down when click on Sub. Please give me a solution.
<script type="text/javascript">
$js(document).ready(function() {
//Class 'contentContainer' refers to 'li' that has child with it.
//By default the child ul of 'contentContainer' will be set to 'display:none'
$js("#treeMenu li").toggle(
function() { // START FIRST CLICK FUNCTION
$js(this).children('ul').slideDown()
if ($js(this).hasClass('contentContainer')) {
$js(this).removeClass('contentContainer').addClass('contentViewing');
}
}, // END FIRST CLICK FUNCTION
function() { // START SECOND CLICK FUNCTION
$js(this).children('ul').slideUp()
if ($js(this).hasClass('contentViewing')) {
$js(this).removeClass('contentViewing').addClass('contentContainer');
}
} // END SECOND CLICK FUNCTIOn
//return true; If used this, slide down is not working
); // END TOGGLE FUNCTION
}); // END DOCUMENT READY
</script>
html as follows
<div id="left_menu">
<h2 style="text-align: center;margin-bottom: 0px;color: #000000">Our Ministry</h2>
<ul id="treeMenu">
<li>ABC</li>
<li>DEF</li>
<li>GHI</li>
<li class="contentContainer">Sub
<ul>
<li>JKL</li>
<li>MNO</li>
<li>PQR</li>
<li>STU</li>
</ul>
</li>
</ul>
</div>
Seems like you can simplify like so:
http://jsfiddle.net/isherwood/8s923/3
<li class="parent contentContainer">Sub
$(document).ready(function () {
$("#treeMenu li.parent > a").click(function (e) { // START FIRST CLICK FUNCTION
e.preventDefault();
$(this).closest('li').toggleClass('contentContainer contentViewing')
.children('ul').slideToggle();
}); // END TOGGLE FUNCTION
}); // END DOCUMENT READY
The solution is to only apply preventDefault to the specific anchors that operate the dropdown menu by giving them a class that isn't toggled.
Don't forget to reapply your alias.

Categories