javascript retrieve class names from multiple elements - javascript

I have this in my page:
<div id="container">
<div>
<p>...</p>
<a href="#" class></a>
</div>
<div>
<p>...</p>
</div>
<div>
<p>...</p>
<a href="#" class></a>
</div>
</div>
Now, I want some codes to execute when each of the a elements changes its class. This doesn't work:
$('#food_container').click( function() {
if ($('#food_container a').attr('class') == "checked") {
/* some codes */
}
});
How to fix this? Thanks!

You are using wrong id in the selector. Change
$('#food_container').click( function() {
if ($('#food_container a').attr('class') == "checked") {
/* some codes */
}
});
to
$('#container').click( function() {
if ($('#container a').hasClass('checked')) {
/* some codes */
}
});

You can use .hasClass() to see if any of the elements have the class:
if ($('#container a').hasClass('checked')) {
// ...
To see if all of them have the class:
if ($('#container a').length = $('#container a.checked').length) {
// ...

var links = $("#container").children("a");
$(links).each(function(i,v){
if($(this).hasClass("checked")){
}
});

Related

Remove class if id's the correct ID

Looking to remove a class if a certain button is clicked.
<div class="slide-container">
<section class="about" id="slide-0">
<div class="menu-total">
<nav class="nav">
<button class="nav_link home" onclick="slideTo('slide-2')">HOME</button>
<button class="nav_link about" onclick="slideTo('slide-0')">ABOUT</button>
<button class="nav_link fun-stuff" onclick="slideTo('slide-1')">FUN STUFF</button>
<button class="nav_link professional" onclick="slideTo('slide-3')">PROFESSIONAL</button>
<button class="nav_link contact" onclick="slideTo('slide-4')">CONTACT</button>
</nav>
<div class="hamburger">
<span class="hamburger__patty"></span>
<span class="hamburger__patty"></span>
<span class="hamburger__patty"></span>
</div>
</div>
The one I want to remove the class on is the HOME button. So "slideTo('slide-2)". If it's clicked on the others then the class is kept. I believe someone is either wrong with my loop or not getting the ID correctly of the items/
function slideTo(slideId) {
const slide = document.getElementById(slideId);
slide.scrollIntoView({
behavior: 'smooth'
})
// above this line works fine
let nonHome = document.querySelectorAll('.slide-container section');
let nonHomeID = document.getElementById('slide-2');
var i;
setTimeout(function(){
for (i=0; i < nonHome.length; i++ ){
// i believe it's somewhere here it is wrong
if (nonHome[i].id != nonHomeID){
nonHome[i].classList.add("nav-visibility");
} else{
nonHomeID.classList.remove("nav-visibility");
}
}
}, 1000)
}
If you can use jquery library, you can write in the HTML:
<button class="nav_link" data-value="home">HOME</button>
...
and then in the JS code:
$(".nav_link").on("click", function() {
var valueClicked = $(this).data("value"); // Get the data-value clicked
$(".nav_link").each(function() { // Loop through all elements of the class 'nav-link'
var v = $(this).data("value");
if (v == valueClicked) {
$(this).removeClass("nav-visibility");
} else {
$(this).addClass("nav-visibility");
}
)
}
Not much simpler, but the HTML is cleaner.
Simpler version if it is not required to browse through all buttons at each button click:
$(".nav_link").on("click", function() {
var valueClicked = $(this).data("value"); // The value of the button clicked by the user
if (valueClicked == "home") {
$(this).removeClass("nav-visibility");
console.log('remove')
} else { $(this).addClass("nav-visibility");
console.log('add')
}
});

Error with expanding divs

I have encountered a problem with expandable divs. Here is my code:
HTML:
<div>more...</div>
<div class="expand" style="display:none">
YO DAWgGG
</div>
JS:
<script type="text/javascript" charset="utf-8">
function showHide(elementid){
if (document.getElementsByClassName("expand").style.display == 'none'){
document.getElementsByClassName("expand").style.display = '';
} else {
document.getElementsByClassName("expand").style.display = 'none';
}
}
</script>
It says that expand is undefined. But I don't see why. What am I doing wrong? Same code works if i use an ID but i need this for more than one div.
Thanks!
You need to do document.getElementsByClassName("expand")[0] as getElementsByClassName returns an array of object.
function showHide(el){
if (document.getElementsByClassName(el)[0].style.display == 'none'){
document.getElementsByClassName(el)[0].style.display = '';
} else {
document.getElementsByClassName(el)[0].style.display = 'none';
}
}
<div>more...</div>
<div class="expand" style="display:none">
YO DAWgGG
</div>
Based on the existing markup. I recommend to use document.querySelectorAll, and instead of setting an elements style, toggle its class.
var links = document.querySelectorAll('.link');
for (var i=0; i<links.length; i++) {
links[i].addEventListener('click', function(e){
e.target.parentElement.nextElementSibling.classList.toggle('show');
})
}
.expand {
display: none;
}
.expand.show {
display: block;
}
<div><a class="link" href="#">more...</a></div>
<div class="expand">
YO DAWgGG 1111
</div>
<div><a class="link" href="#">more...</a></div>
<div class="expand">
YO DAWgGG 222
</div>
<div><a class="link" href="#">more...</a></div>
<div class="expand">
YO DAWgGG 333
</div>
document.getElementsByClassName returns you a HTMLCollection and not a HTMLElement and hence you cant use .style on the collection.
So, if you need to apply some styling on all elements of the collection, you need to iterate over and apply.
Here is what you could do.
document.addEventListener('DOMContentLoaded', function() {
let anchors = document.querySelectorAll(".more");
[].forEach.call(anchors, (anchor) => {
anchor.addEventListener("click", (event) => {
event.preventDefault();
let parent = event.target.parentNode;
let ele = parent.querySelector(".expand");
if (ele.style.display == 'none') {
ele.style.display = '';
} else {
ele.style.display = 'none';
}
})
})
});
<div><a class="more" href="#">more...</a>
<div class="expand" style="display:none">
YO DAWgGG
</div>
</div>
<div><a class="more" href="#">more-2-...</a>
<div class="expand" style="display:none">
YO DAWgGG-2
</div>
</div>

jquery unable to select element using next/closest

I have the following HTML on my page;
<div id="c2">
<input type="checkbox" class="expandCollapseSection" id="my_chk">
<span>Header</span>
<div style="" class="contentDiv">
<div class="oj-inputtext oj-form-control oj-component">some things</div>
</div>
</div>
I have the following JS code;
$(".expandCollapseSection").click(function (event) {
if ($(this).prop("checked")) {
$(this).next('.contentDiv').slideDown('slow');
} else {
$(this).next('.contentDiv').slideUp('slow');
}
});
Now my question is $(this).next('.contentDiv') does not select the contentDiv
I even tried using $(this).closest('.contentDiv')
But still does not select.
Just to add $(".contentDiv") does get the div though.
Am I doing something wrong here?
use siblings( ".selected" )
$(".expandCollapseSection").click(function (event) {
if ($(this).prop("checked")) {
$(this).siblings('.contentDiv').slideDown('slow');
} else {
$(this).siblings('.contentDiv').slideUp('slow');
}
});
Demo
You can try:
$(this).closest('div').find('.contentDiv');
$(".expandCollapseSection").click(function (event) {
if ($(this).prop("checked")) {
$(this).closest('div').find('.contentDiv').css({'color':'red'});
} else {
$(this).closest('div').find('.contentDiv').css({'color':'green'});
}
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<div id="c2">
<input type="checkbox" class="expandCollapseSection" id="my_chk">
<span>Header</span>
<div style="" class="contentDiv">
<div class="oj-inputtext oj-form-control oj-component">some things</div>
</div>
</div>
<div id="c3">
<input type="checkbox" class="expandCollapseSection" id="my_chk">
<span>Header</span>
<div style="" class="contentDiv">
<div class="oj-inputtext oj-form-control oj-component">some things</div>
</div>
</div>
kapantzak's answer is correct.
However you could simply use
$(this).parent().find('.contentDiv');
Slightly more efficient, as you don't have to find closest div.
Try This Code,
$(".expandCollapseSection").click(function (event) {
if ($(this).prop("checked")) {
$(this).closest('#c2').find('.contentDiv').slideDown('slow');
} else {
$(this).closest('#c2').find('.contentDiv').slideUp('slow');
}
});
You may also use nextAll and shorten your code too, like below.
$(".expandCollapseSection").change(function (event) {
var div = $(this).nextAll('.contentDiv');
var func = this.checked ? 'slideDown' : 'slideUp';
div[func]("slow");
});
Demo#Fiddle

Display DIV onclick and hide onclick with transition

How can I show #b1 when clicked on #a1, and show #b2 when clicked on #a2? I need them to close as well (if you click, it will show and if you click again it will close). If you can add transition even better.
<div class="wrap">
<ul class="head_dd">
<li id="a1">INTERIOR</li>
<li id="a2">EXTERIOR</li>
</ul>
</div>
<div class="bt1int" id="b1" style="display: none;"></div>
<div class="bt1int" id="b2" style="display: none;"></div>
The easiest way to do this would be to attach event listeners to each of the elements and then use the .fadeToggle() method to show/hide the corresponding element.
Example Here
$('#a1').on('click', function () {
$('#b1').fadeToggle();
});
$('#a2').on('click', function () {
$('#b2').fadeToggle();
});
Since this could get relatively redundant, you could simplify it to the following:
Example Here
var mapping = {
'a1': 'b1',
'a2': 'b2'
}
$('.head_dd [id]').on('click', function () {
$('#' + mapping[this.id]).fadeToggle();
});
Without jQuery:
You could also use plain JavaScript and CSS3 transitions:
var mapping = {
'a1': 'b1',
'a2': 'b2'
}
Array.prototype.forEach.call(document.querySelectorAll('.head_dd [id]'), function (el) {
el.addEventListener('click', function () {
document.getElementById(mapping[this.id]).classList.toggle('visible');
});
});
.bt1int {
opacity: 0;
transition: opacity 1s;
}
.visible {
opacity: 1;
}
<div class="wrap">
<ul class="head_dd">
<li id="a1">a1</li>
<li id="a2">a2</li>
</ul>
</div>
<div class="bt1int" id="b1">b1</div>
<div class="bt1int" id="b2">b2</div>
Try this one.
HTML code should put data on div content to differ between them.
<div class="wrap">
<ul class="head_dd">
<li id="a1">INTERIOR</li>
<li id="a2">EXTERIOR</li>
</ul>
</div>
<div class="bt1int" id="b1" style="display: none;">a</div>
<div class="bt1int" id="b2" style="display: none;">b</div>
JS code(place this on head section or bottom of body)
<script>
$(function(){
$('#a1').on('click',function(){
$('#b2').hide();
$('#b1').show();
});
$('#a2').on('click',function(){
$('#b1').hide();
$('#b2').show();
});
});
</script>
Add name attribute of each li as target div id
<ul class="head_dd">
<li id="a1" name="b1" >INTERIOR</li>
<li id="a2" name="b2" >EXTERIOR</li>
</ul>
then add following js
$(".head_dd li").click(function(e){
var targetId = $(this).attr("name");
if($("#"+targetId).is(':visible')){
$("#"+targetId).hide();
}else{
$("#"+targetId).show();
}
});
Attach event listeners to to the elements.
var a1 = $('#a1');
var a2 = $('#a2');
var b1 = $('#b1');
var b2 = $('#b2');
a1.addEventListener('click', function(){
b1.slideToggle(600);
});
a2.addEventListener('click', function(){
b2.slideToggle(600);
});
or the alternate
$('#a1').on( 'click', function(){
$('#b1').slideToggle(600);
});
$('#a2').on( 'click', function(){
$('#b2').slideToggle(600);
});

Loop through multiple PHP generated DIVs with show/hide on hover

I just set up the following jQuery code and it's working fine, however I have a feeling it can be refined into a much shorter loop with a counter. I am just familiar enough with jQuery to know this is a possibility but get stuck on the syntax etc. Thank you, and let me know if you need more specifics.
$(".moviethumb:eq(0)").on("mouseover",
function () {
$(".moviedetail:eq(0), .hoverarrow:eq(0)").show();
$(".moviedetail:eq(1), .moviedetail:eq(2)").hide();
}
);
$(".moviedetail_wrapper:eq(0)").on("mouseleave",
function () {
$(".moviedetail:eq(0), .hoverarrow:eq(0)").hide();
}
);
$(".movieout:eq(0)").on("mouseout",
function () {
$(".moviedetail:eq(0), .hoverarrow:eq(0)").hide();
}
);
$(".moviethumb:eq(1)").on("mouseover",
function () {
$(".moviedetail:eq(1), .hoverarrow:eq(1)").show();
$(".moviedetail:eq(0), .moviedetail:eq(2)").hide();
}
);
$(".moviedetail_wrapper:eq(1)").on("mouseleave",
function () {
$(".moviedetail:eq(1), .hoverarrow:eq(1)").hide();
}
);
$(".movieout:eq(1)").on("mouseout",
function () {
$(".moviedetail:eq(1), .hoverarrow:eq(1)").hide();
}
);
$(".moviethumb:eq(2)").on("mouseover",
function () {
$(".moviedetail:eq(2), .hoverarrow:eq(2)").show();
$(".moviedetail:eq(1), .moviedetail:eq(0)").hide();
}
);
$(".moviedetail_wrapper:eq(2)").on("mouseleave",
function () {
$(".moviedetail:eq(2), .hoverarrow:eq(2)").hide();
}
);
$(".movieout:eq(2)").on("mouseout",
function () {
$(".moviedetail:eq(2), .hoverarrow:eq(2)").hide();
}
);
HTML:
<ul class="movies-holder">
<li>
<a href="#">
<div class="movieout"></div>
<div class="moviethumb">
<img src="theimage.jpg />
</div>
</a>
<div class="moviedetail_wrapper">
<div class="hoverarrow"></div>
<div class="moviedetail">
<p>The movie details.</p>
</div>
</div>
</li>
<li>
<a href="#">
<div class="movieout"></div>
<div class="moviethumb">
<img src="theimage.jpg />
</div>
</a>
<div class="moviedetail_wrapper">
<div class="hoverarrow"></div>
<div class="moviedetail">
<p>The movie details.</p>
</div>
</div>
</li>
<li>
<a href="#">
<div class="movieout"></div>
<div class="moviethumb">
<img src="theimage.jpg />
</div>
</a>
<div class="moviedetail_wrapper">
<div class="hoverarrow"></div>
<div class="moviedetail">
<p>The movie details.</p>
</div>
</div>
</li>
</ul>
$(".moviethumb").on("mouseover",
function () {
var index = $(".moviethumb").index(this);
$(".moviedetail, .moviedetail").hide();
$(".moviedetail:eq(" + index + "), .hoverarrow:eq(" + index + ")").show();
}
);
$(".movedetail_wrapper").on('mouseleave', function () {
$(this).find('.moviedetail, .hoverarrow').hide();
});
.movieout can be handled in a similar fasion as the first function. Essentially, you can get the index you want to use dynamically.
I solve this using CSS.
1) Give all divs an unique id="movie321"
2) Generate CSS rule for each.
ul.movies-holder li { display: block; }
ul.movies-holder.show320 li.movie320 { display: block; }
ul.movies-holder.show321 li.movie321 { display: block; }
3) In onmouseover:
document.getElementById('movies-holder').className = 'movies-holder show321';
This is way faster than looping in JavaScript.
Try something like this:
$(".moviethumb").on("mouseover", function() {
$(".moviedetail").hide();
$(this).parents("li").find(".moviedetail").show();
});
$(".moviedetail_wrapper").on("mouseleave", function() {
$(this).parents("li").find(".moviedetail, .hoverarrow").hide();
});
$(".movieout").on("mouseout", function() {
$(this).parents("li").find(".moviedetail, .hoverarrow").hide();
});
using $(this).parents("li") you are looking for ancestors that are . Then finding the class within that parent. You don't need to iterate.

Categories