Finding the source of a click in event bubbling - javascript

I have the following code:
<div id="buttons">
<button id="btn1">1</button>
<button id="btn2">2</button>
</div>
I attach an event handler to the <div> to handle clicks.
When I click a button, the event is captured by the div. Is there a way to get the source of the event?
For example, if the event were on each of the the buttons then the this keyword would refer to the buttons. When it's on the <div> it refers to that.
When the click is caught by the div, is there a way to locate the source of the click? i.e. which actual button was clicked?
Thanks all
Dave

You can use the originalTarget property of the event object to find out the source of the event.
JSFiddle
HTML
<div id="buttons">
<button id="btn1">1</button>
<button id="btn2">2</button>
</div>
JavaScript
document.getElementById('buttons').onclick = function (evt) {
var source = evt.srcElement || evt.originalTarget
alert(source.id);
}

If you use jQuery, this should help:
$("#buttons").click(function(evt){
alert($(evt.target).attr("id"));
});

Related

when jquery .html() is used to set inner HTML, .click() event on form button no longer works

I have a html form which contains a button. This button has a .click() event attached within a js file. This was working fine, until I used jquery .html() to substitute my main page content with the form content. The form shows on the page but clicking the button no longer triggers the event. I am wondering why this is? Code below...
html:
<body>
<div id="mainContent">
<!-- Visible page content will show here -->
</div>
<div id="otherScreens">
<form id="loginForm">
<label for="email">Email</label>
<input type="text" id="email" spellcheck="false">
<label for="password">Password</label>
<input type="password" id="password">
<button type="submit" id="signInBtn">Sign In</button>
<ul id="signInMessages"></ul>
</form>
</div>
css:
#otherScreens {
display: none;
}
js:
const mainContentArea = $(document).find('#mainContent');
let onPageContent = $(document).find('#loginForm').html();
$(document).ready(function () {
mainContentArea.html(onPageContent);
});
$('#signInBtn').click(function (event) {
event.preventDefault();
console.log("Hello world!");
}
I tested changing the .click() event to target #mainContent and it triggered upon clicking anywhere within the div on the webpage, as expected. So I'm not quite sure what's happening with the form button?
(does not seem to relate to suggested duplicate Q)
Just put your click function in document.ready(function()
Please check below full jQuery code and replace it with your current code:
const mainContentArea = $(document).find('#mainContent');
let onPageContent = $(document).find('#loginForm').html();
$(document).ready(function () {
mainContentArea.html(onPageContent);
$('#signInBtn').click(function (event) {
event.preventDefault();
console.log("Hello world!");
});
});
Thanks.
This is quite logical (and can be explained). You create an object, wire events to that object - then replace that object with a similar object and you expect the events to magically be wired.. That doesn't happen.
Each time you dynamically add (delete, replace, whatever) elements with events bound to that element, you need the DOM to be aware of that event. Even so, you could even end-up having more than one event wired to the same element.
So let's say (as an example).
function replaceElement(htmlContent) {
$('.mybutton').off('click'); // drop the event handler
$('#mainContent').html(htmlContent); // replace content
// add event handler
$('.mybutton').click(function() {
console.log('yup, working again');
});
}

Alternative way to use $(element).on('change', () => {})

I have a problem I hope you can help me:
I'm using bootstrap selectpicker which use the onchange event of the element (I think)
I need to add another event handler to the select element, I did and both works right, the problem is that with every certain changes in my page the table that I use reloads all the data and when that happens the table will add that event handler again to the select element and will do the same thing twice (or more)
So, before assignment of the event I tried to use
$('.selectpicker.call').off('change')
But when I do that I remove the event handler of the bootstrap selectpicker too
Do you guys know any other trick that I could use instead of jquery onchange?
Thank you!
You can use namespaces for the events this way you can distinguish just the events you've added as opposed to other events.
Let's take a very simple example - there is a button with some default functionality (Click me) and we can add more event handlers to it. We also want to clear the event handlers but not break the default functionality:
//assume some code outside our control
$("#clickme").on("click", () => console.log("Default functionality"));
//our code
$("#set_message").on("click", () =>{
const message = $("#message").val();
$("#clickme").on("click", () => console.log(message));
});
$("#clear_message").on("click", () =>{
$("#clickme").off("click");
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div>
<input id="message" value="add your message here">
<button id="set_message">Set message</button>
<button id="clear_message">Clear message</button>
</div>
<div>
<button id="clickme">Click me</button>
</div>
This doesn't work because the "Clear message" button removes all event handlers - those added by others or not.
Instead, we can namespace events. For example click.myEvent is still a click event but within the myEvent namespace. If we remove click.myEvent it only removes events from that namespace leaving anything else intact. So "Clear message" now only clears our event handlers:
//assume some code outside our control
$("#clickme").on("click", () => console.log("Default functionality"));
//our code
$("#set_message").on("click.myEvent", () =>{
const message = $("#message").val();
$("#clickme").on("click.myEvent", () => console.log(message));
});
$("#clear_message").on("click.myEvent", () =>{
$("#clickme").off("click.myEvent");
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div>
<input id="message" value="add your message here">
<button id="set_message">Set message</button>
<button id="clear_message">Clear message</button>
</div>
<div>
<button id="clickme">Click me</button>
</div>
Change this $('.selectpicker.call').on('change',function(){....}) to $('body').on('change'','.selectpicker.call',function(){....}) and load this function only once.
What this does is it assigns the function to body and triggers whenever a change event is triggered on .selectpicker.call element. So even if your data keeps changing, this function doesn't.

My button does nothing when i click on it

I have a button
<script>
function changeMap() {
container.setMap(oMap);
}
</script>
<button onClick="changeMap"> Click here </button>
The content of container is correct. it has a control.
The set Map property exists from what i see in the console.
When the page loads all is correct. but when i click the button the property doesn't set OR the content of the page doesn't change.
Do i need to load some other way? Thank you in advance :)
Change your HTML to this:
<button onclick="changeMap()">Click here</button>
The attribute is called onclick not onClick, Apparently html attributes are fully case insensitive, so both will work.
However you also need parentheses after the name of the function.
<button onclick="changeMap(event)">Click Here</button>
here the event is a browser global that allows us to pass an event to the handler. In your case, you aren't using the event, so it is not necessary.
Please also note that if you add the event in javascript, you will not use the parentheses.
I have included a demo of three different ways to add a click handler to a button below.
function log(message){
var line = document.createElement('div');
var text = document.createTextNode(message);
line.appendChild(text);
messages.appendChild(line);
}
function handleClick(e){
log("Click from " + e.target.id);
}
// add an event listener to b2
b3.onclick = handleClick;
// add an event listener to b3
b4.addEventListener('click', handleClick);
<button onclick="handleClick(event);" id="b1" >Button 1</button>
<button onClick="handleClick(event);" id="b2" >Button 2</button>
<button id="b3">Button 3</button>
<button id="b4">Button 4</button>
<div id="messages">
</div>

level 2 DOM handling not working javascript

hello I'm having trouble using level 2 DOM to handle events, i've looked around but just don't quite understand how it works, and allways end up doing simple code like:
<element onClick = " some code" > </element>
instead of reaching the element from outside of html code, please help, I know this is an easy topic but just can't make it work...
there is also some css code but its not relevant to my question so here's my code:
<script type="text/javascript">
function rotate( xy , deegrees){
document.getElementById("cube").style.WebkitTransform = " rotate"+xy+"("+deegrees+"deg)";
}
// so this is where its supposed to be but not working
// whats wrong ?
document.getElementById("upp").addEventListener("click", rotate('X', 540), true);
myFunction();
</script>
</head>
<body>
document.getElementById('cube').style.WebkitTransform = 'rotateX(90deg)';
<div id="button_container">
<button id="upp" onMouseOver=" rotate('X',90); "> UP</button>
<button id="downn" onMouseOver = " rotate('X',-90); "> DOWN</button>
<button id="leftt" onMouseOver = " rotate('Y',00); "> LEFT</button>
<button id="rightt" onMouseOver = " rotate('Y',-90); "> RIGHT</button>
</div>
<section class="container">
<div id="cube">
<figure class="front">front</figure>
<figure class="back">back</figure>
<figure class="right">right</figure>
<figure class="left">left</figure>
<figure class="top">top</figure>
<figure class="bottom">bottom</figure>
</div>
</section>
This is a function call:
rotate('X', 540)
It's a function call no matter where it appears, like when you call addEventListener:
document.getElementById("upp").addEventListener("click", rotate('X', 540), true);
Thus, you're passing the result of calling your "rotate" function instead of the function itself:
document.getElementById("upp").addEventListener("click", function() { rotate('X', 540) }, true);
By wrapping the function call in another function, you correctly supply addEventListener() with an event handler to be called when the "click" happens.
In addition to that, you're trying to add the event handler in a script block that appears before the DOM element you're trying to affect. When the script runs, there won't be an element in the DOM with the id you're looking for. Either wrap your event handler setup in a "load" event handler, or move the script block to the end of the <body>.
Your code likely is running before your DOM is applied. Move script tag to bottom of page or use onload function to execute your code after the DOM has completed its load phase.
http://api.jquery.com/ready/
Validate this by ensuring you can log a element you are attempting to get a reference to...
console.log(document.getElementById("upp"));
Should return a DOM element.

Multiple click events

I have some popup dialogs on my webpage, in each of these dialogs I have defined some click event with jQuery :
$(".links_view").click(function(e){ //code });
But the problem is when I activate one this click event, it will be executed in each dialog...
$(".links_view").click(function(e){ e.preventDefault() });
also have your dialogs different class OR id!?
I believe you want to isolate your click attachment; to do this, just make your selector (currently ".links_view") more specific.
For example, if you have the following HTML
<div id="one">
<button class="links_view">Hi</button>
</div>
<div id="two">
<button class="links_view">Ho</button>
</div>
the code $('.links_view') will grab both, but you can use $('#one .links_view') to just get the first or $('#two .links_view') for the second.
Here's a good tutorial on selectors: http://reference.sitepoint.com/css/selectorref

Categories