JavaScript event target - javascript

I have problem with event target. I want to check which element were clicked but it don't work. What is the solution this problem ?
var prod = document.querySelectorAll("button");
function dodaj(e) {
var tar = e.target;
console.log(tar);
}
for(var i = 0; i < prod.length; i++) {
prod[i].addEventListener("click", function() {
dodaj();
}, false);
}

You haven't passed anything into dodaj. You could just pass dodaj directly into addEventListener.
prod[i].addEventListener("click", dodaj, false);

The issue is that your click event handler was an anonymous function that was putting in a call to the actual function that does the work (dodaj) and that function was not receiving the reference to the event - the anonymous function was.
You can change the anonymous function so that it receives the event and then passes it to dodaj like this:
prod[i].addEventListener("click", function(evt) {
dodaj(evt);
}, false);
However, since that "wrapper" function really wasn't adding any value to your code, you can/should remove it entirely and just register the actual callback function as the click event handler.
var prod = document.querySelectorAll("button");
function dodaj(e) {
console.log(e.target);
}
for(var i = 0; i < prod.length; i++) {
// When any button gets clicked, call the dodaj function
// directly. This is the function that will receive a
// reference to the click event.
prod[i].addEventListener("click", dodaj);
}
<button id="one">Click Me</button>
<button id="two">Click Me</button>
<button id="three">Click Me</button>
<button id="four">Click Me</button>

Related

How to get value from button after it has been clicked

I'm struggling with this assignment: Pin an event listener to the buttons.
Create a function that gets called when one of the buttons is clicked. Check this with a console.log. Make sure the click event is passed to this function.
Make sure you have access to the value of the button clicked in this function. Check this with console.log. The outcome you want to see in the console when you click is: Leopard / Lion / Elephant / Rhino or Buffalo.
fiveButtons = document.getElementsByClassName("big-five-button");
for (var i = 0; i < fiveButtons.length; i++) {
fiveButtons[i].addEventListener("click", function () {
Array.from(fiveButtons).forEach(function (nameButton) {
console.log(nameButton.innerHTML);
})
});
}
This is what I wrote so far. When I'm clicking the button now, the outcome is the text from all the buttons. While I want the outcome to only be "Lion" after the button lion has been clicked.
<h1>The Big Five</h1>
<ul class="big-five-list">
<li class="big-five-list-item">
<button class="big-five-button">Lion</button>
</li> etc.
when creating an addEventListener you can use the event object to target the element clicked, like this:
fiveButtons[i].addEventListener("click", function (event) {
console.log(event.target.innerHTML);
});
You can change the button to include an onclick function like the below:
https://www.w3schools.com/jsref/event_onclick.asp
<!DOCTYPE html>
<html>
<body>
<button onclick="myFunction('Lion')">Lion</button>
<input type="text" value="" id="getValue">
<p id="demo"></p>
<script>
function myFunction(value) {
document.getElementById("getValue").value = value;
}
</script>
</body>
</html>
The onclick function will then have a value inside the () for the function name. This will pass the value you want across to the function and it can be called whatever you want. The above snippet shows an example of how it can be used
Try this solution!
fiveButtons = document.getElementsByClassName("big-five-button");
for (var i = 0; i < fiveButtons.length; i++) {
fiveButtons[i].addEventListener("click", function (item) {
console.log(item.target.innerHTML);
});
}
The function you pass to addEventListener gives an event argument:
fiveButtons = document.getElementsByClassName("big-five-button");
for (var i = 0; i < fiveButtons.length; i++) {
fiveButtons[i].addEventListener("click", function (event) { // use the first argument
console.log('element value:', event.target.value); // log the 'value' of the event target;
// I suspect you want the innerHTML or innerText
console.log('element innerText:', event.target.innerText);
});
}
You can then get the required information from the DOM node in event.target
You don't need the Array.from inside the for loop. You can just do that:
fiveButtons = document.getElementsByClassName("big-five-button");
for (let i = 0; i < fiveButtons.length; i++) {
fiveButtons[i].addEventListener("click", function () {
console.log(fiveButtons[i].innerText);
});
}
EDITED
// Get all the buttons
const fiveButtons = document.getElementsByClassName("big-five-button");
// Iterate through the collection of buttons
// Here is let i = 0 instead of var i = 0, since var has functional scope and let has block scope
// If we used var i = 0 it would not work implicitly because i would exist in the scope of a function,
// and all the event handlers (for each button) would share the same value of i
for (let i = 0; i < fiveButtons.length; i++) {
// For each button register event handler
fiveButtons[i].addEventListener("click", _ => {
// When button is clicked this part of a code is being called
// Because of javascript CLOSURE, it remembers the i value
console.log(fiveButtons[i].innerHTML)
});
}
If this is not understandable please read about closures in javascript.

addEventListener null, onclick works (onload did not work and js is in separate document)

I can use onClick in my HTML file to call upon functions created in my JavaScript file, however, attempting to use addEventListener does not work and I am not sure why. Error in console.log says that the addEventListner is null.
I am attempting to change the display of my web page via a click event.
I understand that addEventListener does not cancel out the previous event called, but even the first event called in my code does not trigger the change which is confusing.
After looking this up I tried the following:
Using window.onload = function(){} and placing the below code within the function.
document.getElementById('begin_game').addEventListener('click', beginGame);
document.getElementById('select_category').addEventListener('click', selectCategory);
Using this code independent of the window.onload function but the addEventListener still returned as null.
The beginGame and selectCategory functions reference the following code in the js file:
function Hide(x) {
const hidden = document.getElementsByClassName(x);
for (var i=0, length= hidden.length; i < length; i++) {
if ( hidden[i].style.display != 'none') {
hidden[i].style.display = 'none';
}
}
}
function Display(x) {
const show = document.getElementsByClassName(x);
for (var i = 0, length = show.length; i < length; i++) {
if (show[i].style.display != 'flex') {
show[i].style.display = 'flex';
}
}
}
//Below is how the functions are referenced
function beginGame() {
document.getElementById('welcome').style.display = 'flex';
Hide('start');
}
function selectCategory () {
Hide('welcome-content');
Display('category');
}
// Where I would place the event listeners I mentioned above
// document.getElementById('begin_game').addEventListener('click', beginGame);
// document.getElementById('select_category').addEventListener('click', selectCategory);
// When I used the window.onload function, I placed it at the bottom of the js page
Buttons from HTML file
<button type='submit' class='welcome-content' id='select_category'>
Categories
</button>
</div>
<h1 class= 'start'>
Math Maniacs
</h1>
<button type='submit' class='start' id='begin_button'>
START
</button>
Using window.onload was the correct solution, I realized that I was not enveloping all of the relevant js code with the onload function.
Before I did this
window.onload = function() {
document.getElementById('begin_game').addEventListener('click', beginGame);
document.getElementById('select_category').addEventListener('click', selectCategory);
}
However, I believe that didn't work because I did not place the functions the event listeners were referencing into the window.onload function.
Once I wrote the below
window.onload = function() {
function beginGame() {
document.getElementById('welcome').style.display = 'flex';
Hide('start');
}
document.getElementById('begin_button').addEventListener('click', beginGame);
function selectCategory() = {
Hide('welcome-content');
Display('category');
}
document.getElementById('select_category').addEventListener('click', selectCategory);
}
The code worked as intended

Event Listener Trouble

I am trying to use an event listener for when I click on an object.
My HTML file
<div id="left">
</div>
<div id="right">
</div>
My JavaScript file
function changeImg(which)
{
if(which === "left")
{
alert("left");
}
else
{
alert("right");
}
}
var leftClick = document.getElementById("left");
leftClick.addEventListener("click", changeImg("left"), true);
var rightClick = document.getElementById("right");
rightClick.addEventListener("click", changeImg("right"), false);
Here is my JSFiddle, https://jsfiddle.net/pb4759jh68/zqzdhcnw/1/
My question is, why does my function run as soon as I run the page, rather than waiting until I click on either the left or right div?
Thanks!!!
The problem is with these 2 lines:
leftClick.addEventListener("click", changeImg("left"), true);
rightClick.addEventListener("click", changeImg("right"), false);
The changeImg function is being called immediately, since you are using the parenthesis after the function name. You can do this to prevent it:
var leftClick = document.getElementById("left");
leftClick.addEventListener("click", function() {
changeImg('left');
}, true);
var rightClick = document.getElementById("right");
rightClick.addEventListener("click", function() {
changeImg('right');
}, false);
Here, we pass an anonymous function as a refernce, which will be called by the browser upon the click event. Inside the function, we are calling our own function changeImg.
addEventListener requires a function as second argument. You're currently evaluating the handler function changeImg("left"), and assigning the result as the event handler. Try this instead:
var leftClick = document.getElementById("left");
leftClick.addEventListener("click", function() { return changeImg("left") }, true);
var rightClick = document.getElementById("right");
rightClick.addEventListener("click", function() { return changeImg("right") }, false);

addEventListener firing automatically within loop - or only last element works

I have a loop, and I am creating a button within each iteration. I am attaching an event listener to each newly created button, and I need to pass unique parameters through. Please see the code below (in this case, just passing the index from the loop through the event listener)
for (i = 0; i <= worklog.worklogs.length; i++) {
if (worklog.total > 0) {
var theButton = document.createElement("button");
theButton.addEventListener("click", alertButton(i));
theButton.innerHTML = "Add";
mySpan.appendChild(theButton);
}
}
function alertButton(arg) {
return function () {
alert(arg);
};
}
Currently, the event listener fires on only the button implemented on the very last iteration. If I remove the "return function(){}" within my alertButton function, then the event listener is fired on each iteration without the user clicking on the button.
If you have any ideas I would be extremely appreciative. I am finding other people who have had this problem, yet the solutions provided don't seem to work so well for me. Hopefully I am overlooking something simple.
Thanks!
Issue is in the way you are assigning listener:
theButton.addEventListener("click", alertButton(i));
in above code, alertButton(i) will call function and not assign to it. If you want to pass a value to a function assignment, you should bind value.
theButton.addEventListener("click", alertButton.bind(this,i));
As pointed by #Andreas, a working example.
function createButtons() {
for (var i = 0; i < 5; i++) {
var theButton = document.createElement("button");
theButton.addEventListener("click", alertButton.bind(this, i));
theButton.innerHTML = "Add";
content.appendChild(theButton);
}
}
function alertButton(arg) {
console.log(arg)
}
createButtons();
<div id="content"></div>

how to get javaScript event source element?

Is there a way to retrieve the element source of an inline javaScript call?
I have a button like this:
<button onclick="doSomething('param')" id="id_button">action</button>
Note:
the button is generated from server
I cannot modify the generation process
several buttons are generated on the page, I have control only on client side.
What I have tried:
function doSomething(param){
var source = event.target || event.srcElement;
console.log(source);
}
On firebug I get event is not defined
Edit:
After some answers, an override of the event handling using jQuery is very acceptable. My issue is how to call the original onClick function with it's original prameters, and without knowing the function name.
code:
<button onclick="doSomething('param')" id="id_button1">action1</button>
<button onclick="doAnotherSomething('param1', 'param2')" id="id_button1">action2</button>.
<button onclick="doDifferentThing()" id="id_button3">action3</button>
.
.
and so on..
So the override would be:
$(document).on('click', 'button', function(e) {
e.preventDefault();
var action = $(this).attr('onclick');
/**
* What to do here to call
* - doSomething(this, 'param'); if button1 is clicked
* - doAnotherSomething(this, 'param1', 'param2'); if button2 is clicked
* - doDifferentThing(this); if button3 is clicked
* there are many buttons with many functions..
*/
});
Your html should be like this:
<button onclick="doSomething" id="id_button">action</button>
And renaming your input-paramter to event like this
function doSomething(event){
var source = event.target || event.srcElement;
console.log(source);
}
would solve your problem.
As a side note, I'd suggest taking a look at jQuery and unobtrusive javascript
You should change the generated HTML to not use inline javascript, and use addEventListener instead.
If you can not in any way change the HTML, you could get the onclick attributes, the functions and arguments used, and "convert" it to unobtrusive javascript instead by removing the onclick handlers, and using event listeners.
We'd start by getting the values from the attributes
$('button').each(function(i, el) {
var funcs = [];
$(el).attr('onclick').split(';').map(function(item) {
var fn = item.split('(').shift(),
params = item.match(/\(([^)]+)\)/),
args;
if (params && params.length) {
args = params[1].split(',');
if (args && args.length) {
args = args.map(function(par) {
return par.trim().replace(/('")/g,"");
});
}
}
funcs.push([fn, args||[]]);
});
$(el).data('args', funcs); // store in jQuery's $.data
console.log( $(el).data('args') );
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<button onclick="doSomething('param')" id="id_button1">action1</button>
<button onclick="doAnotherSomething('param1', 'param2')" id="id_button1">action2</button>.
<button onclick="doDifferentThing()" id="id_button3">action3</button>
That gives us an array of all and any global methods called by the onclick attribute, and the arguments passed, so we can replicate it.
Then we'd just remove all the inline javascript handlers
$('button').removeAttr('onclick')
and attach our own handlers
$('button').on('click', function() {...}
Inside those handlers we'd get the stored original function calls and their arguments, and call them.
As we know any function called by inline javascript are global, we can call them with window[functionName].apply(this-value, argumentsArray), so
$('button').on('click', function() {
var element = this;
$.each(($(this).data('args') || []), function(_,fn) {
if (fn[0] in window) window[fn[0]].apply(element, fn[1]);
});
});
And inside that click handler we can add anything we want before or after the original functions are called.
A working example
$('button').each(function(i, el) {
var funcs = [];
$(el).attr('onclick').split(';').map(function(item) {
var fn = item.split('(').shift(),
params = item.match(/\(([^)]+)\)/),
args;
if (params && params.length) {
args = params[1].split(',');
if (args && args.length) {
args = args.map(function(par) {
return par.trim().replace(/('")/g,"");
});
}
}
funcs.push([fn, args||[]]);
});
$(el).data('args', funcs);
}).removeAttr('onclick').on('click', function() {
console.log('click handler for : ' + this.id);
var element = this;
$.each(($(this).data('args') || []), function(_,fn) {
if (fn[0] in window) window[fn[0]].apply(element, fn[1]);
});
console.log('after function call --------');
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<button onclick="doSomething('param');" id="id_button1">action1</button>
<button onclick="doAnotherSomething('param1', 'param2')" id="id_button2">action2</button>.
<button onclick="doDifferentThing()" id="id_button3">action3</button>
<script>
function doSomething(arg) { console.log('doSomething', arg) }
function doAnotherSomething(arg1, arg2) { console.log('doAnotherSomething', arg1, arg2) }
function doDifferentThing() { console.log('doDifferentThing','no arguments') }
</script>
Cross-Browser solution
I believe the solution by #slipset was correct, and it doesn't need jQuery, BUT it wasn't cross-browser ready.
According to Javascript.info, events (when referenced outside markup events) are cross-browser ready once you assure it's defined with this simple line: event = event || window.event.
So the complete cross-browser ready function would look like this:
function logMySource(param){
event = event || window.event;
var source = event.target || event.srcElement;
console.log("sourceID= "+source.id,"\nsourceTagName= "+source.tagName,"\nparam= "+param);
}
<button onclick="logMySource('myVariable')" id="myID">action</button>
Try it!
I've included returns of useful information of the source.
You can pass this when you call the function
<button onclick="doSomething('param',this)" id="id_button">action</button>
<script>
function doSomething(param,me){
var source = me
console.log(source);
}
</script>
Try something like this:
<html>
<body>
<script type="text/javascript">
function doSomething(event) {
var source = event.target || event.srcElement;
console.log(source);
alert('test');
if(window.event) {
// IE8 and earlier
// doSomething
} else if(e.which) {
// IE9/Firefox/Chrome/Opera/Safari
// doSomething
}
}
</script>
<button onclick="doSomething('param')" id="id_button">
action
</button>
</body>
</html>
USE .live()
$(selector).live(events, data, handler);
As of jQuery 1.7, the .live() method is deprecated. Use .on() to attach event handlers.
$(document).on(events, selector, data, handler);

Categories

Resources