Find element by class and toggle it - javascript

I have inside my html code repeating elements like this:
<li>
<a class="synth-faq-trigger" href="#0">Link</a>
<div class="synth-faq-content">
<p class="filler">Text</p>
</div> <!-- synth-faq-content -->
</li>
and I use the following command so I can toggle the class 'content-visible' that will make this element slide to reveal the contents of <p>, in this case Text.
What I am trying to do is before doing this in my code, find the previous element that had a class of 'content-visible' and toggle it, so only one element remains visible at all times.
$(this).next('.synth-faq-content').slideToggle(200).end().parent('li').toggleClass('content-visible');
I tried various things lastly being
$(this).closest('synth-faq-trigger').next().find('.synth-faq-content').toggleClass('content-visible');
that has no effect at all. Moreover the suggestions from w3school on finding an element by class failed all together.
How can I make sure that I find all my items containing 'content-visible' and I remove this class from them?

I notice you are already using hash links in your example code, and because of this, you can achieve what you are trying without any JavaScript. Browsers already have functionality to handle displaying elements depending on the hash target, so let's exploit this browser feature rather than implementing it again in JavaScript.
Live demo: http://jsfiddle.net/g105b/cj5fscah/
The href of the anchor is to a hash link, which will be put into the URL bar of the browser. Each li element has an ID that corresponds to the hash targets, and using the :target CSS selector, you can style elements differently depending on what the hash is.
With some fancy CSS you can add animations too, that will perform much better than any JavaScript can.
<ul>
<li id="0">
<a class="synth-faq-trigger" href="#0">Link</a>
<div class="synth-faq-content">
<p class="filler">Text for one</p>
</div> <!-- synth-faq-content -->
</li>
<li id="1">
<a class="synth-faq-trigger" href="#1">Link</a>
<div class="synth-faq-content">
<p class="filler">Text for two</p>
</div> <!-- synth-faq-content -->
</li>
<li id="2">
<a class="synth-faq-trigger" href="#2">Link</a>
<div class="synth-faq-content">
<p class="filler">Text for three</p>
</div> <!-- synth-faq-content -->
</li>
</ul>
ul {
width: 320px;
}
li {
background: #aaf;
}
.synth-faq-content {
overflow: hidden;
height: 0;
transition: height 200ms ease-in-out;
}
li:target .synth-faq-content {
height: 3em;
}
Edit: if you still need to manipulate the class names, a simple piece of JavaScript can trigger when the hash changes to accomplish having a class added to the correct LI element.
window.addEventListener("hashchange", function(e) {
// Remove all .content-visible elements:
[].forEach.call(document.querySelectorAll(".content-visible"), function(li) {
li.classList.remove("content-visible");
});
// Add .content-visible to the li that contains the clicked anchor:
document.querySelector("a[href='" + location.hash + "']").parentElement.classList.add("content-visible");
});
Updated demo: http://jsfiddle.net/g105b/cj5fscah/1/

You can use the sibling relation like
$('a').click(function() {
var $li = $(this).next('.synth-faq-content').slideToggle(200).closest('li').toggleClass('content-visible');
$('li.content-visible').not($li).removeClass('content-visible').find('.synth-faq-content').slideUp();
})
.content-visible > a {
color: green;
}
.synth-faq-content {
display: none;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<ul>
<li>
<a class="synth-faq-trigger" href="#0">Link</a>
<div class="synth-faq-content">
<p class="filler">Text</p>
</div>
<!-- synth-faq-content -->
</li>
<li>
<a class="synth-faq-trigger" href="#0">Link</a>
<div class="synth-faq-content">
<p class="filler">Text</p>
</div>
<!-- synth-faq-content -->
</li>
<li>
<a class="synth-faq-trigger" href="#0">Link</a>
<div class="synth-faq-content">
<p class="filler">Text</p>
</div>
<!-- synth-faq-content -->
</li>
</ul>

Related

How can i add a css class only to the h3 tag clicked using jQuery

<li>
<div id="lineop1"><h3>Softshell</h3></div>
</li>
<li>
<div id="lineop1"><h3>Option</h3></div>
</li>
<li>
<div id="lineop1"><h3>Option 1</h3></div>
</li>
I need to show which one h3 tag is clicked to show active
You need to do it like below:-
$(document).ready(function(){
$('.lineop1 a h3').click(function(e){
e.preventDefault(); // to prevent page refresh with new url
$('h3').removeClass('active'); // remove active class from other h3 tag
$(this).addClass('active'); // add active class to current clicked tag
});
});
.active{
color:green;
font-size:20px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<li>
<div class="lineop1"><h3>Softshell</h3></div>
</li>
<li>
<div class="lineop1"><h3>Option</h3></div>
</li>
<li>
<div class="lineop1"><h3>Option 1</h3></div>
</li>
Note:- id need to be unique per element. so convert id to class around <div's>
And if you want that after click on h3 when page refresh, then also the corresponding h3 tag have the active class, then you have to use localstorage concept like below:-
jQuery:-
$(document).ready(function(){
$('ul li').eq( localStorage.parent ).find('h3').addClass('active');
$('.lineop1 a h3').click(function(e){
var pagename = $(location).attr("href").split('/').pop();
localStorage.parent=$(this).closest('li').index();
});
});
Html:-
<ul>
<li>
<div class="lineop1"><h3>Softshell</h3></div>
</li>
<li>
<div class="lineop1"><h3>Option</h3></div>
</li>
<li>
<div class="lineop1"><h3>Option 1</h3></div>
</li>
</ul>
I have tested it on localhost at my end and working perfectly fine.
add a click handler to h3. Add class active to it.
$(document).ready(function(){
$(document).on('click','h3',function(){
$('h3').removeClass('active');
$(this).addClass('active');
});
});
.active{
color:#ff00eb;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<li>
<div id="lineop1"><h3>Softshell</h3></div>
</li>
<li>
<div id="lineop1"><h3>Option</h3></div>
</li>
<li>
<div id="lineop1"><h3>Option 1</h3></div>
</li>
Edit: its always good practice to attach click event to the closest unique parent element. so I have included $(document).On.
Follow this link to see working of Direct Vs Deletegated Events

Get closest element with given id using javascript

I need to add a class to the closest div with a given id after I click the div above it. My example below should make more sense of what I need.
<style>
.menuContent {display:none;}
.expandMenu {display:inherit;}
</style>
<ul>
<li>
<div class="menuIcon" onclick="expandMenu('menuContent');">+</div>
<div id="menuContent" class="menuContent">
<p>This</p>
<p>That</p>
<p>The Other</p>
</div>
</li>
<li>
<div class="menuIcon" onclick="expandMenu('menuContent');">+</div>
<div id="menuContent" class="menuContent">
<p>This</p>
<p>That</p>
<p>The Other</p>
</div>
</li>
</ul>
This is the script I have so far that searches the class names of the given element and adds or removes the 'expandMenu' class when clicked.
<script>
function expandMenu(x) {
var d = document.getElementById(x);
var c = d.className;
if (c.search("expandMenu") === -1) {
d.className += " expandMenu";
} else {
d.className = c.replace(" expandMenu","");
}
}
</script>
This is all working fine, the issue is when clicking the 'menuIcon' in the second 'li', it's the first 'li' element that the script is applied too - it's obviously just finding the first 'menuContent' and applying the className function to it.
How can I limit the function to only apply to the 'menuContent' div that is directly after it.
I don't want to use jQuery either - good ol' fashioned plain Javascript would be great.
Give the menu icons unique ids, and pass that id to the function. Toggle based on the id, instead of the class. You are right, it is choosing the first one because it has found it when running through the code.
You should not have the same id on multiple elements. Try changing one of the id's and passing the new id to the function.
<style>
.menuContent {display:none;}
.expandMenu {display:inherit;}
</style>
<ul>
<li>
<div class="menuIcon" onclick="expandMenu('menuContent1');">+</div>
<div id="menuContent1" class="menuContent">
<p>This</p>
<p>That</p>
<p>The Other</p>
</div>
</li>
<li>
<div class="menuIcon" onclick="expandMenu('menuContent2');">+</div>
<div id="menuContent2" class="menuContent">
<p>This</p>
<p>That</p>
<p>The Other</p>
</div>
</li>
</ul>

Foundation 6: Hide the Top Bar when link is clicked

I'm using Foundation 6 for a one-page website. And I'm using a Top Bar to take users to different sections of the website. So when visiting the website on mobile, when I click a link from the collapsed Top Bar, I want the Top Bar to hide after taking the user to a certain section of the website.
Here's my HTML:
<div data-sticky-container>
<div data-sticky data-sticky-on="small" data-options="marginTop:0.9;" style="width: 100%">
<div class="top-bar">
<div class="top-bar-title">
<span data-responsive-toggle="responsive-menu" data-hide-for="medium">
<span class="menu-icon dark" data-toggle></span>
</span>
</div>
<div id="responsive-menu">
<div class="top-bar-section">
<ul class="menu" data-magellan>
<li class="title"><a class="title-link" href="#home">HOME</a></li>
<li class="title"><a class="title-link" href="#events">EVENTS</a></li>
<li class="title"><a class="title-link" href="#about">ABOUT</a></li>
</ul>
</div>
</div>
</div>
</div>
</div>
I could have achieved this functionality by using this (I think):
$(function () {
$('.title-link').on('click', function () {
$("#responsive-menu").css({display: none});
});
});
But the problem is when I click the menu icon, Foundation adds and inline style of display: block; and I can't seem to change it through to JS.
Is there a way to override the inline styles, or should I use a different layout? Thanks for the help!
.css() overrides inline style. Just change this line :
$("#responsive-menu").css({display: none});
To :
$("#responsive-menu").css({"display": "none"});
Similar topic for more info : How to override inline css through javascript?
Try this one:
JS:
$(function () {
$('.title-link').on('click', function () {
$("#responsive-menu").toggleClass('myStyle');
});
});
CSS:
.myStyle {
display: block!important;
}
or
.myStyle {
display: none!important;
}
depend what you want to do.

Toggle is not clossing

I have this toggle which is working fine.
I just want to close one when second is clicked.
Right now its opening all the slides.
jQuery(function($){
$(document).ready(function() {
$("h3.symple-toggle-trigger").click(function() {
$(this).toggleClass("active").next().slideToggle("fast");
return false;
});
});
});
I don't know how your html is structured exactly but I put together an example of html that will work with a few alterations to your JavaScript. You may have to tinker around with it to get the exact desired effect your looking for but I believe it is pretty close.
Live Preview: http://codepen.io/larryjoelane/pen/yeoGNr
HTML:
<h3 class="symple-toggle-trigger">
Trigger 1
</h3>
<p class="section">
section 1
</p>
<h3 class="symple-toggle-trigger">
Trigger 2
</h3>
<p class="section">
section 2
</p>
<h3 class="symple-toggle-trigger">
Trigger 3
</h3>
<p class="section">
section 3
</p>
I removed the document ready function call from your code. You will not need it if you are loading your scripts before the closing </body> tag. If you are loading your script from the <head> element then you will need to add it back.
I rearranged your anonymous function wrap/closure so that it returns the jQuery object just in case you want to use another library with your code in the future. I don't know if that matters to you are not I just thought it might help.
JavaScript:
(function($){//begin closure
$("h3.symple-toggle-trigger").click(function() {
var active = $(this).index(".symple-toggle-trigger");
$(this).next(".section").slideToggle("fast");
$(".symple-toggle-trigger").each(function(i){//begin each
//if the element index doesn't equal the active index or the element clicked on.
if(i !== active){//begin if then
//hide the section
$(".section")[i].style.display = "none";
}//end if then
});//end each
});
}(jQuery));//end closure
li div{ display: none;}
li div.open{ display: block;}
$(document).ready(function(){
$(".symple-toggle-trigger").click(function(){
$("ul li div").slideUp();
$("ul li h3.active").removeClass("active");
$(this).addClass("active").next().slideDown();
});
});
<ul>
<li>
<h3 class="symple-toggle-trigger">Heading 01</h3>
<div>Content</div>
</li>
<li>
<h3 class="symple-toggle-trigger">Heading 01</h3>
<div>Content</div>
</li>
<li>
<h3 class="symple-toggle-trigger">Heading 01</h3>
<div>Content</div>
</li>
<li>
<h3 class="symple-toggle-trigger">Heading 01</h3>
<div>Content</div>
</li>
<li>
<h3 class="symple-toggle-trigger">Heading 01</h3>
<div>Content</div>
</li>
</ul>
Click here for Demo https://jsfiddle.net/pixeldew/u5qg21fx/

Selector :not in jQuery not working

I have a body with ID body and inside it a div with class nav-container. I want to remove certain classes when users click on the #body, but not .nav-container (it's an overlay type of menu).
Tried below code
HTML:
<body id="body">
<div class="nav-container">
X
<nav class="display">
<ul>
<li> One </li>
<li> Two </li>
<li> Three </li>
</ul>
</nav>
</div>
</body>
jQuery
$('#body :not(.nav-container)').click(function() {
$('.cover').removeClass('active-cover');
$('.nav-container').removeClass('active');
});
It does not seem to be working for me though.
It wont work as not exclude the selected elements which pass the earlier css-selector criteria since .nav-container is not part of list that is selected by #body (wont be list in this case as its ID), so you wont be able to exclude that.
So basically what you need is
$(document).on("click", "div:not('.nav-container')",function() {
$('.cover').removeClass('active-cover');
$('.nav-container').removeClass('active');
});
the first element shouldn't be the parent, like #body, rather the element. for example div:not('example') works for every div except example.
$("div:not(.nav-container)").click(function() {
alert("nav-container was not clicked");
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<body id="body">
<div class="nav-container">
X
<nav class="display">
<ul>
<li> One </li>
<li> Two </li>
<li> Three </li>
</ul>
</nav>
</div>
<br />
<div>click here </div>
</body>

Categories