Div inside of another Div avoid click - javascript

Hello my friends so this is my question i have two divs, one of them is inside of the other one
like this schema below.
<div class="button1" onclick={buttonOnePressed}>
<div class="button2" onclick={buttonTwoPressed}">
</div>
</div>
i Want to click on the div with class "button2" and call only one function that is the "buttonTwoPressed". But when i click on the div "button2" i accidentally also call the function "buttonOnePressed", so this way two functions are called but i just wish one. What can i do to prevent that ? Thank you for reading

Event bubbles up. Use .stopPropagation() to stop it from moving to parent.
let buttonTwoPressed = (event) =>{
event.stopPropagation();
}

Related

Trying to manipulating classes with JS to get a div element to close

I'm in the process of creating a web app that tracks real estate transactions. Part of that process is to track all the offers that come in on a specific property. An overview of the offers are displayed at first glance vertically on the page. When you click on an offer a control panel drops so that further info and/or actions can be viewed/taken. The code to drop the control panel is working and I've also got it so that if you click on another offer it closes any open control panels.
I've also included a div that I've given the class name of "close-bttn". This button is located within the main control-panel and is supposed to close the control-panel that it is a child of.
The close-bttn is supposed to close the open control panel, but it does not.
Here's a code shot of the structure
<div class="offer">
<div id="offer-amount"># dollarformat( offer_amount )#</div>
<div id="buyer-premium"># dollarFormat( buyer_premium )#</div>
<div id="buyer-name"># buyer_name #</div>
<div id="agent-name"># agent #</div>
<div id="agent-email"># agent_email #</div>
<div class="control-panel">
<div class="close-bttn">X</div>
</div>
</div>
Here is the code that I'm using to manipulate the elements
const eachOffer = document.querySelectorAll(".each-offer");
const controlPanels = document.querySelectorAll(".control-panel");
// This adds a click event to the <div class="offer"> element that opens the control-panel div
// by adding the class "scaley". The scaley class definition: .scaley{transform: scaleY(1)}
eachOffer.forEach((offer)=>{
// This. targets the specific control-panel for the offer
var o = offer.querySelector(".control-panel");
offer.addEventListener('click', ()=>{
// See function for explanation
// This closes any open control-panels
toggleControlPanel()
o.classList.toggle("scaley")
})
})
function toggleControlPanel(){
//There are multiple control-panels, one for each offer. This loops over all the control-panels
// on the page and if the classList contains "scaley" it is removed which closes the ocntrol-panel
document.querySelectorAll(".control-panel").forEach((o)=>{
if( o.classList.contains("scaley") ) o.classList.toggle("scaley")
});
}//END
Here's the code to add the click event to use the close-bttn to close the control-panel
controlPanels.forEach((panel)=>{
panel.querySelector(".close-bttn").addEventListener("click",()=>{
//This does not seem to be working.
// I've tried to use classList.toggle as well with no result
panel.classList.remove("scaley")
})
})
Not sure what to do here. Any ideas??
In addition I've used
classList.toggle
classList.remove
classList.value
//ClassList.value contains all the classes an element has
//So the control-panel has a classList.value="control-panel scaley" at onset
//I tried to do classList.value="control-panel". that didn't work.
Here is a link to a codepn example that I posted: https://codepen.io/Hugh-Rainey/pen/wvxjgpJ?editors=1111
Your remove() function is working, only problem is your click event is bubbling up and triggering the handler on your offer divs (which re-toggles them back open). You need to stop the event from bubbling up.
controlPanels.forEach((panel)=>{
panel.querySelector(".close-bttn").addEventListener("click",(e)=>{
e.stopPropagation(); // stop event bubbling, don't forget to add e to your param list
panel.classList.remove("scaley")
})
})
querySelectorAll returns a NodeListOf which is not an array. So use a for loop like this:
for (let i = 0; i < controlPanels.length; i++) {
panel.querySelector(".close-bttn").addEventListener("click",()=>{
panel.classList.remove("scaley")
})
}

Onclick event not works after "show" class added to parent div

I have two screens on the page. Every screen has 5 tables, there is only one table that can be seen. I want to change the visible table with these buttons. There are 2 buttons (previous, next) for each screen.
Here is my Javascript code to buttons:
document.querySelector('.screen.show .screen-table-buttons .next').onclick = function(){
...
}
This code works when the page is loaded the first time, but when added the show class to other screens, and I want to use it, it's not working. I want to use these buttons when the screen parent has a show class.
I changed the show class, added it to other screens, reloaded the page, and then other buttons worked on the other screen, but the first buttons didn't work.
So, I just want to use all buttons when the div parent has the show class. If the parent does not have the show class, don't work, If has it, just do it.
As mentioned in the comments this is a good case for event delegation - a single listener is attached to the document (or relevant ancestor) and functions are called based on target attributes.
Here it is attached to the document and it first checks if the clicked target has an ancestor with class screen.show using closest() if it does we check the classList of the target using classList.contains() to trigger the relevant function call.
function next_fn() {
console.log('next');
}
function previous_fn() {
console.log('previous');
}
document.addEventListener('click', (event) => {
if (event.target.closest('.screen.show')){
if (event.target.classList.contains('next')) {
next_fn();
}
if (event.target.classList.contains('previous')) {
previous_fn();
}
}
});
<div class='screen'>
<h6>Screen no-show (buttons won't trigger)</h6>
<button type='button' class='next'>Next</button>
<button type='button' class='previous'>Previous</button>
</div>
<div class='screen show'>
<h6>Screen show (only these buttons work)</h6>
<button type='button' class='next'>Next</button>
<button type='button' class='previous'>Previous</button>
</div>
<div class='not-screen'>
<h6>Not-screen (buttons won't trigger)</h6>
<button type='button' class='next'>Next</button>
<button type='button' class='previous'>Previous</button>
</div>
As Teemu said in the comment, the way you're binding the click event means that you're binding the click event to the button that is already visible (i.e. the one that has the show class at the moment the line you've put in the question is hit) - it isn't designed to cater for elements that may or may not exist at some point in the page lifecycle.
You'll either need to rebind the click event each time you switch the show class, or you can bind the event regardless of the show class.
In order to rebind the event each time, you'd be better off pulling the function out into its own area - something like this:
document.querySelector('.screen.show .screen-table-buttons .next').onclick = NextClicked
function NextClicked() {
... do the normal click event stuff, and move the show class to the other screen
document.querySelector('.screen.show .screen-table-buttons .next').onclick = NextClicked
}
Alternatively, you could bind the click event once and do a check to see whether the one clicked is the right one - something along these lines:
document.querySelector('.screen .screen-table-buttons .next').onclick = function(e){
if (e.target.parentElement.parentElement.hasClass('show')){
...
}
}

How to handle more than one eventListener?

I have two divs like this :
<div id="sun" > </div> <div id="thu" > </div>
I want once one of them clicked the eventListener
document.getElementById(currentId).addEventListener("click",function(e){});
fires the selected one knowing the id of the div.
You need this :
function eventHandler(e) {
//what needs to be done after user clicks the divs will come here
}
document.getElementById('sun').addEventListener("click", eventHandler, false);
document.getElementById('thu').addEventListener("click", eventHandler, false);
It is really simple. Basically the context of the event callback function is the actual html Element that is clicked. So the "this" selector is the actual source of the event.
document.getElementById(currentId).addEventListener("click",function(e){
var id=this.getAttribute('id');
});
I think you are looking for one common event hander for both div.
If yes, then you can achieve this by giving common class to both div and then register event hander by class selector like below:
HTML code:
<div id="sun" class="myClass"> </div>
<div id="thu" class="myClass" > </div>
java script code:
var classname = document.getElementsByClassName("myClass");
for(var i=0;i<classname.length;i++){
classname[i].addEventListener('click', event_handler_name, false);
}
or
$('.myClass').click(event_handler_name);
jQuery does the looping part for you, where as you need to do in plain javascript.

how can I detect a click on an element and all the elements inside except one?

I am trying to click on a div and trigger a function (in javascript/jquery) but dont triger it if I click a child element of that div.
Well, basically, I have this structure
<div class="parent">
<div class="child_1">
<div class="child_2">
<button id="myButton"></button>
</div>
</div>
</div>
What I want to do, is that I want to detect if I click on .parent and triger a function, but dont triger it if i click on #myButton
so far, Ive tried many ways but I cannot figure out the proper way, if I have a
$(".parent").click(function(){...})
seems to call it as well if I click on myButton, any ideas?
Check the event target:
$(".parent").click(function(e){
if (e.target.id == "myButton") return false;
//code
})
Le fiddle: http://jsfiddle.net/rz6oqbh0/

Detecting onclicks with javascript

Does anyone know of a way of detecting which one out of a series of image input buttons has been clicked on, and execute some javascript accordingly?
for example if an 'about' button is clicked, the 'about' header on the page would turn blue.
I can do this individually but is there a loop or something to slim it down? Thanks in advance!
If your buttons share a class you can use document.querySelectorAll to select all buttons and Array.prototype.forEach.call for the iteration:
<button class="about-button" id="a">a</button>
<button class="about-button" id="b">b</button>
<button class="about-button" id="c">c</button>
<script>
[].forEach.call(document.querySelectorAll('.about-button'), function(el) {
el.addEventListener('click', imageButtonClickHandler);
});
function imageButtonClickHandler() {
alert('button clicked: ' + this.id);
}
</script>
If you are using jQuery you can use the .on method:
$("#about").on("click", function(event){
$(this).css("background-color", "blue"); // Or RGB color, just like in the CSS
});
Source: http://api.jquery.com/on/ and http://api.jquery.com/css/
The question is not fully clear, but I'll try to answer it based on some assumptions.
If you are creating the image buttons dynamically, then I would attach one onclick event handler to all the images buttons being added, and pass 'this' as the parameter to the handler. That way the click handler can look at the DOM element passed in.
<a onclick="imageClicked(this)"><img src="about.jpg" /></a>
If the elements are declared on the page, and not added dynamically, I would bind the click event for each image button if they are not that many (as #Joshua Brodie has pointed out). If there are a lot of them, I would have one click handler and have data specific to the image button in a "data" attribute.
<a class="imgbtn" data-buttonname="about"><img src="about.jpg" /></a>
$('.imagebtn').bind('click', function () {
console.log($(this).data('buttonname')); // about
});

Categories

Resources