document.removeEventListener javascript - javascript

How can I remove this type of listener?
document.addEventListener("onSomething", function(){
//Do something
});
when try to remove return number argument exception, way a function in second parameter but i not have a function.
document.removeEventListener("customUploadComplete")

You need to make a reference to the function in order to remove it. So pull it out into a function so you can remove it.
var thisThing = function(){
//Do something
}
document.addEventListener("onSomething", thisThing);
document.removeEventListener("onSomething", thisThing);

You need to declare a function in order to remove it. This is because you need to reference it upon removal so that the browser can recognize which event to remove.
This will not work:
btn.addEventListener("click", function() { alert("clicked") });
btn.removeEventListener("click", function() { alert("clicked") });
because there is no reference to the function. Each function is unique, even if they have the same code within them.
If you declare a function you can store a reference to that function, and then remove it:
function clickEvent() {
alert("clicked!");
}
btn.addEventListener("click", clickEvent);
btn.removeEventListener("click", clickEvent);
Here's an example:
let $ = document.querySelector.bind(document),
btn = $("#b1"),
add = $("#b2"),
remove = $("#b3");
function clickEvent() {
alert("click");
}
btn.addEventListener("click", clickEvent);
remove.addEventListener("click", function() {
btn.removeEventListener("click", clickEvent);
alert("event removed!");
});
add.addEventListener("click", function() {
btn.addEventListener("click", clickEvent);
alert("event added!");
});
<button id="b1">click me</button>
<p/>
<button id="b2">Add Event Listener</button> <button id="b3">Remove Event Listener</button>

Related

Removing an onclick event from a div with javascript

Basically what the title says this is the code that I've tried but it doesn't work:
<div id="box" onclick="doSmt(var1, bar2)">
if (condition){
box.removeEventListener("click" , doSmt)}
I think it's better if you remove the onclick event instead of that attempt
//onclick function
function doSmt(){
console.log("something");
}
//remove onclick event, this will be inside your if condition
document.getElementById('box').removeAttribute("onclick");
<div id="box" onclick="doSmt()"> div</div>
What what I read at MDN for removeEventListener you can't remove an event listener that is part of the HTML attribute. So there's two options:
Add the event listener on page load
onClickHandler = () => doSmt(var1, var2);
document.addEventListener('DOMContentLoaded', () => {
document.getElementById('box').addEventListener('click', onClickHandler);
});
// and later
if (condition) {
document.getElementById('box').removeEventListener('click', onClickHandler)
Or if you can't modify the HTML you could modify doSMT to watch for a disabled bit.
let disableBox = false;
function doSmt() {
if (disableBox) return;
// ...
}
if (condition) {
disableBox = true;
}
Or
it can be removed by first accessing the element and then setting the attribute to null
<div id="myDiv" onclick="handleClick()">Click me</div>
<script>
function handleClick() {
alert("Div was clicked!");
}
// Remove the onclick event from the div
const div = document.getElementById("myDiv");
div.onclick = null;
</script>

How do I add another onclick function after the vote function? [duplicate]

Can we put two JavaScript onclick events in one input type button tag? To call two different functions?
This one works:
<input type="button" value="test" onclick="alert('hey'); alert('ho');" />
And this one too:
function Hey()
{
alert('hey');
}
function Ho()
{
alert('ho');
}
.
<input type="button" value="test" onclick="Hey(); Ho();" />
So the answer is - yes you can :)
However, I'd recommend to use unobtrusive JavaScript.. mixing js with HTML is just nasty.
The HTML
click
And the javascript
// get a cross-browser function for adding events, place this in [global] or somewhere you can access it
var on = (function(){
if (window.addEventListener) {
return function(target, type, listener){
target.addEventListener(type, listener, false);
};
}
else {
return function(object, sEvent, fpNotify){
object.attachEvent("on" + sEvent, fpNotify);
};
}
}());
// find the element
var el = document.getElementById("btn");
// add the first listener
on(el, "click", function(){
alert("foo");
});
// add the second listener
on(el, "click", function(){
alert("bar");
});
This will alert both 'foo' and 'bar' when clicked.
There is no need to have two functions within one element, you need just one that calls the other two!
HTML
<a href="#" onclick="my_func()" >click</a>
JavaScript
function my_func() {
my_func_1();
my_func_2();
}
You can attach a handler which would call as many others as you like:
<a href="#blah" id="myLink"/>
<script type="text/javascript">
function myOtherFunction() {
//do stuff...
}
document.getElementById( 'myLink' ).onclick = function() {
//do stuff...
myOtherFunction();
};
</script>
You could try something like this as well
<a href="#" onclick="one(); two();" >click</a>
<script type="text/javascript">
function one(){
alert('test');
}
function two(){
alert('test2');
}
</script>

Return a function from a nested function javascript

Is it possible to return an outer function from a nested one in javascript?
I have something like this:
function outer(){
$(document).on("change", "input[type='checkbox']", function(){
})
$(document).on("click", "input[type='submit']", function(event){
// i want to exit from here when this event fires
})
}
Like others already said, you can't return from something that might or might not happen in the future. If the intent is to return some value from the event handler you could use a promise.
Keep in mind that a promise can only be resolved once. Pressing the button multiple times wont fire the promise handlers again.
function outer() {
$(document).on("change", "input[type='checkbox']", function () {
// ...
});
return new Promise(resolve => {
$(document).on("click", "input[type='submit']", function (event) {
resolve("Hello World!");
});
});
}
outer().then(value => console.log(value));
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<input type="submit" />
If you want something that can fire multiple times, accept an callback function and call that instead.
function outer(callback) {
$(document).on("change", "input[type='checkbox']", function () {
// ...
});
$(document).on("click", "input[type='submit']", function (event) {
callback("Hello World!");
});
}
outer(value => console.log(value));
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<input type="submit" />
Based on your comment you aren't looking for a return value at all, but rather something like this:
function outer() {
function handleCheckboxChange(event) {
console.log(event.target.checked);
}
$(document).on("change", "input[type='checkbox']", handleCheckboxChange);
$(document).one("click", "input[type='submit']", function (event) {
$(document).off("change", "input[type='checkbox']", handleCheckboxChange);
console.log("Hello World!");
});
}
outer();
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<input type="checkbox" />
<input type="submit" />
The jQuery documentation says:
To remove events bound with .on(), see .off(). To attach an event that runs only once and then removes itself, see .one()
Those are event listeners. They fire when the event is triggered, not when a function is called. If you want you can put a function in an event listener, and call it outside of the listener as well, like this:
const doSomething = () => {
console.log("logging function")
}
document.getElementById("btn").onclick = () => doSomething()
doSomething()
<button id="btn">Click Me</button>

single onclick function for buttons with a similar id pattern - JavaScript

I want to reduce the code.
function one() {
console.log("hai");
}
document.getElementById('dealsButton_1').onclick = one;
document.getElementById('dealsButton_2').onclick = one;
//I want the above 2 lines of code reduced to one.
A single function for on click on 'dealsButton_*' patterned id elements. How can I do this. The elements are dynamically loaded.
You can use querySelectorAll and the selector [id^=dealsButton_] to add the event listener in a single line - see demo below:
function one() {
console.log("hai");
}
Array.prototype.forEach.call(
document.querySelectorAll('[id^=dealsButton_]'), function(e) {
e.addEventListener('click', one);
});
<div id="dealsButton_1">one</div>
<div id="dealsButton_2">two</div>
If the markup is dynamically loaded you can base it on a static element like this:
function one() {
console.log("hai");
}
document.addEventListener('click', function(e) {
if (e.target && /^dealsButton_/.test(e.target.id))
one();
})
// dynamically add
document.body.innerHTML = `<div id="dealsButton_1">one</div>
<div id="dealsButton_2">two</div>`;
Are you looking for something like this:
function onClick(){
//single handler
}
$('[id*="dealsbutton_"]').click(onClick)
Here is a solution where you can choose ID name as u wish without a specific pattern of name.
<html>
<body>
<div id="abc">one</div>
<div id="def">two</div>
<script type="text/javascript">
function one() {
console.log("hai");
}
function addOnclickFunc (func, idArray){
idArray.forEach(function(element) {
document.getElementById(element).onclick = func;
})
}
addOnclickFunc(one,["abc","def"])
</script>
</body>
</html>
you use jQuery with regex for this
$.each( $("button[id^='dealsButton_']"), function () {
$(this).on('click', function(){
//code here
})
});
if want to make the function call names dynamically. pass it as data attribute to button element and call it using eval function
<button id="dealButton_1" data-click="one"></button>
$.each( $("button[id^='dealsButton_']"), function () {
$(this).on('click', function(){
var function_call = $(this).attr('data-click')
eval(function_call)
})
});

addEventListener firing multiple times for the same handle when passing in arguments with anonymous function

For some reason, the event listener is firing twice for each element when passing arguments into an anonymous function. I.e., the click event on element el will register once and, thus, fire once.
el.addEventListener("click", handle, false);
el.addEventListener("click", handle, false);
But if I want to pass my own arguments to it, it will register and fire twice.
el.addEventListener("click", function() { handle(event, myArgument); }, false);
el.addEventListener("click", function() { handle(event, myArgument); }, false);
The question is why and what's the solution?
I looked elsewhere and cannot seem to find a solution or understand why this problem is occurring. I tried implementing the solutions in How to pass an argument to the listener function passed in addEventListener? but they did not help --
I did the basic anonymous function or closure and then the more advanced version, which is the shown below but it did work.
I don't get why passing no arguments causes the element event to register once and passing arguments causing the element event to register twice.
Here is the code:
<html>
<head>
<script type="text/javascript">
var handle_2 = function(evt, type) {
var test;
switch (type) {
case "focus":
console.log(evt.target.value);
break;
case "click":
console.log(evt.target.id + " was clicked");
break;
default: console.log("no type found");
}
};
window.onload = function() {
var textbox = document.getElementById("t1");
var button = document.getElementById("btn");
textbox.value = "456";
button.value = "Press";
var typeFocus = "focus", typeClick = "click";
textbox.addEventListener("focus", (function(typeFocus) { return function(evt) { handle_2(evt, typeFocus); }})(typeFocus), false);
button.addEventListener("click", (function(typeClick) { return function(evt) { handle_2(evt, typeClick); }})(typeClick), false);
// Registers again for each element. Why?
textbox.addEventListener("focus", (function(typeFocus) { return function(evt) { handle_2(evt, typeFocus); }})(typeFocus), false);
button.addEventListener("click", (function(typeClick) { return function(evt) { handle_2(evt, typeClick); }})(typeClick), false);
};
</script>
</head>
<body>
<div id="wrapper">
<input id="t1" type="text" />
<input id="btn" type="button" />
</div>
</body>
</html>
Any help would be appreciated.
The simplest solution is to create the new handler only once:
var newHandle = function(event) { handle(event, myArgument); };
el.addEventListener("click", newHandle, false);
el.addEventListener("click", newHandle, false);
If you call addEventListener multiple times on the same element with exactly the same values for event type, handler and capture then the handler is only registered once. From the DOM spec:
...
5. If eventTarget’s event listener list does not contain an event listener whose type is listener’s type, callback is listener’s callback, and capture is listener’s capture, then append listener to eventTarget’s event listener list.
...
Well,,
el.addEventListener("click", handle, false);
el.addEventListener("click", handle, false);
Registers to the same function "handle()"
el.addEventListener("click", function() { handle(event, myArgument); }, false);
el.addEventListener("click", function() { handle(event, myArgument); }, false);
Registers "function() { handle(event, myArgument)"... which are two unique anonymous functions. Thus it will fire twice.
Although I don't fully understand why you would want to register it twice, the solution would be to create a function returning your function that takes parameters.
el.addEventListener("click", crateHandle(myArgument), false);
var createHandle = function(myArgument) {
return function(event) {
.... do something
};
}
It still doesn't solve the fire twice issue though.
addEventListener registers as many listeners as it is used.
According to the documentation it takes 3 arguments, the third is useCapture which has nothing to do with registering listener twice or not. It is by default set to false, so adding false as a third parameter doesn't change much.
useEffect(()=>{
document.addEventListener('keydown', someFunction);
}, []);
use the useEffect hook, the empty array at the end will till react to not refresh the component once loaded

Categories

Resources