How do I get the clicked div if the divs both got same class.
For an example:
<div class="box"></div> <div class="box"></div>
And I want to add another class to the div I click on.
New at JavaScript but I have figured out that I should use "this" in some way.
What I have done so far:
box = document.getElementById("box");
box.addEventListener("click, function(event) {
event.target.classList.toggle("clicked");
}
But of course this only works for a div with an Id and not for multiple divs.
You can use document.querySelectorAll here like:
var boxes = document.querySelectorAll('.box');
Array.from(boxes).forEach(box => {
box.addEventListener('click', function(e) {
e.target.classList.toggle('clicked');
});
});
If you want to use document.getElementById() you need to add element the id attribute:
<div id="box1" class="box">
By design, ids are meant to be unique, so if you can assign each element an id, it shoud be enough.
I'd suggest an approach where you add the listener on a parent (or whole document) and check for the clicked element inside:
document.addEventListener('click', function (event) {
if(event.target.classList.contains('box')) {
event.target.classList.toggle('clicked');
}
}
This approach is better performance-wise as it creates only one event handler, not a handler per element.
with jquery
$('.box').click(function() {
console.log($(this).text());
})
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="box">one</div><div class="box">two</div>
If you want to keep using pure JavaScript without any additional lib, I believe Query Selectores should help you (https://developer.mozilla.org/pt-BR/docs/Web/API/Element/querySelectorAll).
Evolving your snippet:
document.querySelectorAll("box").forEach( function (){
this.addEventListener('click', function(event) {
event.target.classList.toggle("clicked");
});
});
If you attach the eventListener onto a containing element, here I've just used body, but more targeted selectors can give better performance.
You could then check the class of the item clicked.
Example below..
document.body.addEventListener("click", function (evt) {
var el = evt.srcElement;
if (el.classList.contains("box"))
el.classList.toggle("clicked");
});
.clicked {
background-color: yellow;
}
<div class="box">Box 1</div>
<div class="notabox">Not a Box</div>
<div class="box">Box 2</div>
Related
I have a container that opens via an onclick function. I then have a cross within the container that should close the parent element however I receive a
TypeError: undefined is not an object (evaluating 'parent.id')
Code is here
<div class="post" onclick="postClick(el)">
...
...
</div>
JavaScript
function postClick(el) {
document.getElementById(el.id).classList.add("read");
}
function postClose(event) {
var parent = this.parentNode;
console.log(parent.id);
parent.id.classList.remove("read");
}
Use event.target to get the reference to the HTML element.
And you have an extra .id in the parent.id.classList expression.
function postClick(event) {
const el = event.target;
document.getElementById(el.id).classList.add("read");
}
function postClose(event) {
const el = event.target;
const parent = el.parentNode;
console.log(parent.id);
parent.classList.remove("read");
}
<div class="post" onclick="postClick(event)">
...
...
</div>
One way of doing this is using pure Javascript and bind the event listener like this
document.querySelector('#toggle').addEventListener('click', function (e) {
console.log(this.parentNode.classList.remove('read'))
});
div {
padding: 20px 50px;
}
div.read {
background-color: red;
}
<div class="read">
<button id="toggle">Remove Parent Class</button>
</div>
Jut use this and you are done : 😊
element.parentNode.classList.remove("class-name");
if the project is complex and needs interactivity more than often then you use jquery library for the interactivity.
//to remove class
$( "p" ).removeClass( "myClass yourClass" )
$("#div123").toggle(); //if you want to temp hide elements
as your code suggests the 'read' items must be disabled, you can toggle them once an event handler is wrapped over the toggle method. you can pass this or $(this) in case you want to do stuff with the owner of the function call.
well i agree some adept devs didnt like this answer, it will be surely of some help to some beginner dev in future who is looking for an alternative option to hide elements or remove classes
DEMO
I am doing a simple jquery accordian effect as below.
JQUERY
$(function ($) {
$('.Accordian').find('.Btn').click(function () {
$(this).next('.Content').slideToggle('fast');
$('.Content').not($(this).next()).slideUp('fast');
});
});
HTML
<div class="Accordian">
<div class="Btn"></div>
<div class="Content"></div>
</div>
This work great however if content is placed between .Btn and .Content then it breaks.
QUESTION
How to directly target the next available class name relative to the
button clicked?
How to target all elements of a class name except the next available
class name relative to button clicked?
Try with siblings()
$(function ($) {
$('.Accordian').find('.Btn').click(function () {
//cache the value so that it can be used in the next statement
var $content = $(this).siblings('.Content').slideToggle('fast');
$('.Content').not($content).slideUp('fast');
});
});
Try to use .nextAll() along with .first() to accomplish your task, Actually here we have used .first() for a safety purpose.
$('.Accordian').find('.Btn').click(function () {
var targetElem = $(this).nextAll('.Content').first();
targetElem.slideToggle('fast');
$('.Content').not(targetElem).slideUp('fast');
});
DEMO
What I'd like to do is have all elements of class collapsible_list not displayed by default (with one exception... see below*), and then toggle their display when their parent <div class="tab_box"> is clicked. During the same click, I'd also like for every other element of class collapsible_list to be hidden so that only one of them is expanded at any given time.
*Furthermore, when the page initially loads I'd also like to check to see if an element of collapsible_list has a child a element whose class is activelink, and if there is one then I'd like that link's parent collapsible_list element to be the one that's expanded by default.
Here's some sample html code:
<style>
.collapsible_list {
display: none;
}
.collapsible_list.active {
display: block;
}
</style>
<div id="sidebar">
<div class="tab_box">
<div class="collapsible_tab">2014</div>
<div class="collapsible_list panel-2014">
1
2
3
</div>
</div>
<div class="tab_box">
<div class="collapsible_tab">2013</div>
<div class="collapsible_list panel-2013">
<a class="activelink" href="/2013/1">1</a>
2
3
</div>
</div>
</div>
And here's where I'm currently at with the javascript (although I've tried a bunch of different ways and none have worked like I'd like them to):
$(document).ready(function() {
// This looks redundant to me but I'm not sure how else to go about it.
$(".collapsible_list").children("a.activelink").parent(".collapsible_list:not(.active)").addClass("active");
$(".tab_box").click(function() {
$(this).children(".collapsible_list").toggleClass("active").slideToggle("slow", function() {
$(".collapsible_list.active:not(this)").each(function() {
$(this).slideToggle("slow");
});
});
});
});
I hope that's not too confusing, but if it is then feel free to let me know. Any help is much appreciated.
Since you have a dom element reference that needs to be excluded use .not() instead of the :not() selector
jQuery(function ($) {
// This looks redundant to me but I'm not sure how else to go about it.
$(".collapsible_list").children("a.activelink").parent(".collapsible_list:not(.active)").addClass("active").show();
$(".tab_box").click(function () {
var $target = $(this).children(".collapsible_list").toggleClass("active").stop(true).slideToggle("slow");
//slidup others
$(".collapsible_list.active").not($target).stop(true).slideUp("slow").removeClass('active');
});
});
Also, instead of using the slide callback do it directly in the callback so that both the animations can run simultaniously
Also remove the css rule .collapsible_list.active as the display is controlled by animations(slide)
Try This.
$('.collapsible_tab a').on('click', function(e){
e.preventDefault();
$('.collapsible_list').removeClass('active')
$(this).parent().next('.collapsible_list').toggleClass('active');
});
Fiddle Demo
I think your code would be less complicated if you simply remembered the previously opened list:
jQuery(function($) {
// remember current list and make it visible
var $current = $('.collapsible_list:has(.activelink)').show();
$(".tab_box").on('click', function() {
var $previous = $current;
// open new list
$current = $('.collapsible_list', this)
.slideToggle("slow", function() {
// and slide out the previous
$previous.slideToggle('slow');
});
});
});
Demo
i have this jQuery code:
$(document).ready(function () {
$("#hide").click(function () {
$("div1").hide();
});
$("#show").click(function () {
$("div1").show();
});
});
and this jsp/html
for{int=0;i<V_loopnumber;i++)
{
%>
<button id='show' height:10px>showit</button>
<div1>
something
<button id='hide' height:10px>hideit</button>
</div1>
<%
}
For example if I have 3 elements, it produces 3 divs. However,if I push the button all the divs will be showed or hided cause they got the same name.
how can I differentiate the button with the respective divs?
Your markup has a few problems. You can not assign the same ID twice. Also div1 is not a valid tag name.
Perhaps you can restructure your markup along the lines of the following example:
<div class="container">
<button class="show">showit</button>
<div class="inner">
something
<button class="hide">hideit</button>
</div>
</div>
I assigned the buttons classes instead of ids and got rid of the div1 elements.
Now you can listen for a click event on the buttons and hide the related elements using the .closest() (http://api.jquery.com/closest/) method like this:
$(".hide").click(function () {
$(this).closest(".inner").hide();
});
$(this).closest(".inner") will retrieve the the closest element with the class inner up in the dom tree.
$(".show").click(function () {
$(this).parent().find(".inner").show();
});
$(this).parent().find(".inner") will go up one level in the dom tree and find the element with the class inner.
http://jsfiddle.net/KGk7B/
First, element ids must be unique. Use a class instead. Second, <div1> isn't a valid tag. Use a div with a class instead. Third, use traversal functions to find the specific element to toggle.
$(document).ready(function () {
$(".hide").click(function () {
$(this).closest('.show-hide-container').hide();
});
$(".show").click(function () {
$(this).next('.show-hide-container').show();
});
});
for{int=0;i<V_loopnumber;i++)
{
%>
<button class='show' height:10px>showit</button>
<div class="show-hide-container">
something
<button class='hide' height:10px>hideit</button>
</div>
<%
}
id must be unique on your page, use class
<button class='show' height:10px>showit</button>
and use $(this) in event callback function instead of using selector
$(".hide").click(function(){
$(this).parent().hide(); // this is hard select of your div1, i wrote only for your html
});
IMPORTANT: Use div instead of div1, div1 tag is undefined.
For example I have simple html.
<body>
<div class="a">
<div class="child"></div> <!-- div element I click -->
<div class="childINeedToSelect"></div> <!-- div element I need to be selected -->
<div class="child"></div>
</div>
<div class="a">
<div class="child"></div>
<div class="childINeedToSelect"></div>
<div class="child"></div>
</div>
</body>
When I click on top first child class div I need to change, for example, border ONLY of the first childINeedToSelect class div. They have the same parent - a class div, but the difficult is that there are more than just one element with class a. I've already tried:
$(document).ready(function () {
var child = $('.child');
child.bind('click', function() {
detectElement($(this));
});
});
var belt;
function detectElement(arrow) {
belt = arrow.parent('.a').children('childINeedToSelect').eq(1);
belt.css("background-color", "red");
}
As you see I'm trying to send $(this) as parameter to detectElement() to determine which div was clicked. But my target div background doesn't change, and when I try to use element belt later, after it was detected by detectElement() function, Opera javascript debugger gives me error
Unhandled Error: Cannot convert 'belt.css('marginLeft')' to object
in line
var currentMargin = parseInt(belt.css('marginLeft').toString().replace('px', ''));
but this line of code worked perfectly, before calling detectElement() function; What am I doing wrong? How should I select element I need?
I'd suggest:
function detectElement(arrow) {
arrow.parent().find('.childINeedToSelect').css('background-color','red');
}
$(document).ready(function(){
$('.child').click(function(){
detectElement($(this));
});
});
JS Fiddle demo.
Or you could use the nextAll() method to find the sibling childINeedToSelect:
function detectElement(arrow) {
arrow.nextAll('.childINeedToSelect').css('background-color','red');
}
JS Fiddle demo.
And if you should have multiple .child and childINeedToSelect elements, you can pass the :first selector into the nextAll() method:
function detectElement(arrow) {
arrow.nextAll('.childINeedToSelect:first').css('background-color','red');
}
JS Fiddle demo.
I'm unsure why you were using bind(), but on the off-chance that you might be trying to account for dynamically-added elements (added after the event-handlers are bound to the various DOM nodes/jQuery objects), you could instead use on():
$('.a').on('click','.child', function(){
detectElement($(this));
});
JS Fiddle demo.
References:
find().
:first selector.
nextAll().
on().
parent().
Try this fiddle
$(document).ready(function () {
var child = $('.child');
child.bind('click', function() {
detectElement($(this));
});
});
var belt;
function detectElement(arrow) {
belt = arrow.siblings('.childINeedToSelect').eq(0);
belt.css("background-color", "red");
}
Try something like
jQuery('.a').children().first().click(function(){
jQuery('.childINeedToSelect').attr('background-color','red');
)}