Remove All onclick Events for an Element - javascript

var links = document.body.querySelectorAll("p.sourcelinks a.individual_source_link");
for(var i=0;i<links.length;i++)
{
links[i].onclick = null;
}
Is my current code, however it doesn't remove the onclick events. I have no idea what they will be since this is a greasemonkey script.

Your code only deals with events added by element.onclick case. What about events added with addEventListener (for standards compliant browsers) and attachEvent (for IE)?
You need to use removeEventListener and detachEvent to remove events as well as setting .onclick to null. Then all your bases will be covered.

This article would probably be useful:
http://www.computerhowtoguy.com/how-to-use-the-jquery-unbind-method-on-all-child-elements/
One part in particular is a recursive function that removes all click events. Remember that jQuery will remove click events IF the click event was created using jQuery. the function given in the article will remove both those created with jQuery and those that were not. The function given is this:
function RecursiveUnbind($jElement) {
// remove this element's and all of its children's click events
$jElement.unbind();
$jElement.removeAttr('onclick');
$jElement.children().each(function () {
RecursiveUnbind($(this));
});
}
You would call the function like this:
RecursiveUnbind($('#container'));
That function takes a jQuery object parameter, but you could easily change it up to pass a string as the name of the ID for the element, or however you think is best.
While this only addresses click events you could easily modify it to handle others or all.

That code doesn't work because of GM's sandbox. links is in an XPCNativeWrapper.
To get around this use setAttribute(), like so:
var links = document.body.querySelectorAll("p.sourcelinks a.individual_source_link");
for(var i=0;i<links.length;i++)
{
links[i].setAttribute ("onclick", null);
}
Note that click handlers that are set other ways, will need to be cleared other ways (removeEventListener(), for example).

Array.from(document.all).forEach(el=>{
el.onselectstart=null
el.oncontextmenu=null
document.oncontextmenu=null
})
here is the solution
Right click and select event bypassed

I am guessing you have either an href or a JavaScript function being called on the onClick for an <a> link.
You can remove either of these by removing the href tag, the onClick event or in this case both of them.
for(var i=0;i<links.length;i++)
{
links[i].href='#';
links[i].onclick = '';
}

Related

jQuery remove scroll listener after reach certain point [duplicate]

I have an input type="image". This acts like the cell notes in Microsoft Excel. If someone enters a number into the text box that this input-image is paired with, I setup an event handler for the input-image. Then when the user clicks the image, they get a little popup to add some notes to the data.
My problem is that when a user enters a zero into the text box, I need to disable the input-image's event handler. I have tried the following, but to no avail.
$('#myimage').click(function { return false; });
jQuery ≥ 1.7
With jQuery 1.7 onward the event API has been updated, .bind()/.unbind() are still available for backwards compatibility, but the preferred method is using the on()/off() functions. The below would now be,
$('#myimage').click(function() { return false; }); // Adds another click event
$('#myimage').off('click');
$('#myimage').on('click.mynamespace', function() { /* Do stuff */ });
$('#myimage').off('click.mynamespace');
jQuery < 1.7
In your example code you are simply adding another click event to the image, not overriding the previous one:
$('#myimage').click(function() { return false; }); // Adds another click event
Both click events will then get fired.
As people have said you can use unbind to remove all click events:
$('#myimage').unbind('click');
If you want to add a single event and then remove it (without removing any others that might have been added) then you can use event namespacing:
$('#myimage').bind('click.mynamespace', function() { /* Do stuff */ });
and to remove just your event:
$('#myimage').unbind('click.mynamespace');
This wasn't available when this question was answered, but you can also use the live() method to enable/disable events.
$('#myimage:not(.disabled)').live('click', myclickevent);
$('#mydisablebutton').click( function () { $('#myimage').addClass('disabled'); });
What will happen with this code is that when you click #mydisablebutton, it will add the class disabled to the #myimage element. This will make it so that the selector no longer matches the element and the event will not be fired until the 'disabled' class is removed making the .live() selector valid again.
This has other benefits by adding styling based on that class as well.
This can be done by using the unbind function.
$('#myimage').unbind('click');
You can add multiple event handlers to the same object and event in jquery. This means adding a new one doesn't replace the old ones.
There are several strategies for changing event handlers, such as event namespaces. There are some pages about this in the online docs.
Look at this question (that's how I learned of unbind). There is some useful description of these strategies in the answers.
How to read bound hover callback functions in jquery
If you want to respond to an event just one time, the following syntax should be really helpful:
$('.myLink').bind('click', function() {
//do some things
$(this).unbind('click', arguments.callee); //unbind *just this handler*
});
Using arguments.callee, we can ensure that the one specific anonymous-function handler is removed, and thus, have a single time handler for a given event. Hope this helps others.
maybe the unbind method will work for you
$("#myimage").unbind("click");
I had to set the event to null using the prop and the attr. I couldn't do it with one or the other. I also could not get .unbind to work. I am working on a TD element.
.prop("onclick", null).attr("onclick", null)
If event is attached this way, and the target is to be unattached:
$('#container').on('click','span',function(eo){
alert(1);
$(this).off(); //seams easy, but does not work
$('#container').off('click','span'); //clears click event for every span
$(this).on("click",function(){return false;}); //this works.
});​
You may be adding the onclick handler as inline markup:
<input id="addreport" type="button" value="Add New Report" onclick="openAdd()" />
If so, the jquery .off() or .unbind() won't work. You need to add the original event handler in jquery as well:
$("#addreport").on("click", "", function (e) {
openAdd();
});
Then the jquery has a reference to the event handler and can remove it:
$("#addreport").off("click")
VoidKing mentions this a little more obliquely in a comment above.
If you use $(document).on() to add a listener to a dynamically created element then you may have to use the following to remove it:
// add the listener
$(document).on('click','.element',function(){
// stuff
});
// remove the listener
$(document).off("click", ".element");
To remove ALL event-handlers, this is what worked for me:
To remove all event handlers mean to have the plain HTML structure without all the event handlers attached to the element and its child nodes. To do this, jQuery's clone() helped.
var original, clone;
// element with id my-div and its child nodes have some event-handlers
original = $('#my-div');
clone = original.clone();
//
original.replaceWith(clone);
With this, we'll have the clone in place of the original with no event-handlers on it.
Good Luck...
Updated for 2014
Using the latest version of jQuery, you're now able to unbind all events on a namespace by simply doing $( "#foo" ).off( ".myNamespace" );
Best way to remove inline onclick event is $(element).prop('onclick', null);
Thanks for the information. very helpful i used it for locking page interaction while in edit mode by another user. I used it in conjunction with ajaxComplete. Not necesarily the same behavior but somewhat similar.
function userPageLock(){
$("body").bind("ajaxComplete.lockpage", function(){
$("body").unbind("ajaxComplete.lockpage");
executePageLock();
});
};
function executePageLock(){
//do something
}
In case .on() method was previously used with particular selector, like in the following example:
$('body').on('click', '.dynamicTarget', function () {
// Code goes here
});
Both unbind() and .off() methods are not going to work.
However, .undelegate() method could be used to completely remove handler from the event for all elements which match the current selector:
$("body").undelegate(".dynamicTarget", "click")
I know this comes in late, but why not use plain JS to remove the event?
var myElement = document.getElementById("your_ID");
myElement.onclick = null;
or, if you use a named function as an event handler:
function eh(event){...}
var myElement = document.getElementById("your_ID");
myElement.addEventListener("click",eh); // add event handler
myElement.removeEventListener("click",eh); //remove it
This also works fine .Simple and easy.see http://jsfiddle.net/uZc8w/570/
$('#myimage').removeAttr("click");
if you set the onclick via html you need to removeAttr ($(this).removeAttr('onclick'))
if you set it via jquery (as the after the first click in my examples above) then you need to unbind($(this).unbind('click'))
All the approaches described did not work for me because I was adding the click event with on() to the document where the element was created at run-time:
$(document).on("click", ".button", function() {
doSomething();
});
My workaround:
As I could not unbind the ".button" class I just assigned another class to the button that had the same CSS styles. By doing so the live/on-event-handler ignored the click finally:
// prevent another click on the button by assigning another class
$(".button").attr("class","buttonOff");
Hope that helps.
Hope my below code explains all.
HTML:
(function($){
$("#btn_add").on("click",function(){
$("#btn_click").on("click",added_handler);
alert("Added new handler to button 1");
});
$("#btn_remove").on("click",function(){
$("#btn_click").off("click",added_handler);
alert("Removed new handler to button 1");
});
function fixed_handler(){
alert("Fixed handler");
}
function added_handler(){
alert("new handler");
}
$("#btn_click").on("click",fixed_handler);
$("#btn_fixed").on("click",fixed_handler);
})(jQuery);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<button id="btn_click">Button 1</button>
<button id="btn_add">Add Handler</button>
<button id="btn_remove">Remove Handler</button>
<button id="btn_fixed">Fixed Handler</button>
I had an interesting case relevant to this come up at work today where there was a scroll event handler for $(window).
// TO ELIMINATE THE RE-SELECTION AND
// RE-CREATION OF THE SAME OBJECT REDUNDANTLY IN THE FOLLOWING SNIPPETS
let $window = $(window);
$window.on('scroll', function() { .... });
But, to revoke that event handler, we can't just use
$window.off('scroll');
because there are likely other scroll event handlers on this very common target, and I'm not interested in hosing that other functionality (known or unknown) by turning off all of the scroll handlers.
My solution was to first abstract the handler functionality into a named function, and use that in the event listener setup.
function handleScrollingForXYZ() { ...... }
$window.on('scroll', handleScrollingForXYZ);
And then, conditionally, when we need to revoke that, I did this:
$window.off('scroll', $window, handleScrollingForXYZ);
The janky part is the 2nd parameter, which is redundantly selecting the original selector. But, the jquery documentation for .off() only provides one method signature for specifying the handler to remove, which requires this middle parameter to be
A selector which should match the one originally passed to .on() when attaching event handlers.
I haven't ventured to test it out with a null or '' as the 2nd parameter, but perhaps the redundant $window isn't necessary.

Get elements by event listener

Is there a way to get all elements that have a certain event listener attached to them?
I know I can get them if the event listener is defined as an attribute:
var allElemsInBodyWithOnclickAttr = $("body").find("*[onclick]");
But I have elements that have event listeners that are attached by code and thus have no onclick attribute.
So when I do (for example) this:
$("a").on("click", function(evt) {
alert("Hello");
});
..then using the code below doesn't fire the click on those anchor elements:
$("a[onclick]").trigger("click");
I guess I could loop through all the elements and check if they have the listener I'm looking for (using this SO question) but I can't imagine that's going to perform very well..
Can't add comments, but still - consider using https://github.com/ftlabs/fastclick for removing the delay.
That helped me, when i was developing app using cordova.
Also, didn't notice you have already mentioned this post, so i have written implementation for 'loop through all elements'-type-of-solution
Array.prototype.reduce.call(
$('body').children(),
(answer, node) => {
if (typeof $._data($(node)[0], 'events') != 'undefined') {
answer.push(node);
}
return answer;
},
[]
);
I think this is not possible, since it is not possible to test if a single element has an event listener attached to it.
Look here
So the only way to do that is to manage a map which contains a reference to each event handler for each event for each element.
Edit
With respect to the answer of #Ivan Shmidt, I must correct my answer: Obviously It seams to be possible with jQuery. That is because jQuery is holding a reference of attached event handlers, BUT events attached using good old .addEventListener() would bypass this and also not be found this way.

addEventListener within a loop

I don't understand why addEventListener only works outside of a loop. Using the following code, I created example in a JsFiddle (http://jsfiddle.net/E7gaZ/1/):
window.addEventListener('load', function (){
document.getElementById('myId').addEventListener(
'click', myHandler, false
);
var myClass = document.getElementsByClassName('myClass');
for(var i=0; i<myClass.length; i++) {
myClass[i].addEventListener("onclick", myHandler, false);
}
});
function myHandler(ev) {
alert(ev.target.innerHTML);
ev.preventDefault();
}
Clicking the "myId" link while alert "myId" and prevent page reload while the other links won't call myHandler.
The following method seems to work well though (still inside the window.load event (http://jsfiddle.net/E7gaZ/2/):
document.getElementById('myId').onclick = myHandler;
var myClass = document.getElementsByClassName('myClass');
for(var i=0; i<myClass.length; i++) {
myClass[i].onclick = myHandler;
}
Any idea why?
Edit: why would I want to use addEventListener instead of .onclick =? Because I can add multiple listeners on the same event.
Edit: thanks for the solution, guys. As a conclusion, it was working on myId because I was using the right syntax (click) and not on *myClass because the syntax was wrong (onclick).
I'm pretty sure this:
myClass[i].addEventListener("onclick", myHandler, false);
Needs to be:
myClass[i].addEventListener("click", myHandler, false);
To me, it doesn't make sense to attach 'onclick' as a listener.
The reason that the handlers aren't firing when using "addEventListener" is that the string for the event name you pass using "addEventListener" must be "click", not "onclick"...
...apart from Internet Explorer where you would use "onclick", but also "attachEvent" rather than "addEventListener" as the method name for attaching event listeners to an element is different in IE! (amongst other things ;))
As to your "onclick" vs. "addEventListener"-question. With onclick, you can only assign ONE listener to a single event type, whereas by adding listeners via "addEventListener"/"attachEvent" you can have multiple callback handlers fire for a single event type, should you choose to. In your jsfiddle example it doesn't matter as there is only one handler for the event.
Additionally, "onclick" is what is known as an inline handler, depending on how you're writing your JavaScript application this could mean that you would have no access to variables part of your applications object / closures which could become an architectural problem.

How to stop event propagation from within an anchor's href attribute without using onclick or onmousedown

Due to restrictions, even though it is something i avoid altogether, in a certain situation i have to use the javascript: syntax in a href attribute of an achor tag.
(EXPLANATION: In my CMS i use a rich text editor to allow the user to make changes to text elements, including links. In some cases specific javascript: calls are required and i banned onclick completely from the link editing features (to simplify the process for the user). However, as one of the links appears within a block that reacts to an onclick event, the thing double-fires)
Like this:
My problem is that this link is inside a container that already reacts to an onclick event. Therefore i wanted to pass the event object along to the doSomething() method, so that i could then use jQuery's
event.stopPropagation()
method.
Unfortunately however, it seems that passing the event object along
does not seem to work at all. Safari won't say anything while Firefox will report ReferenceError: event is not defined
I assume that this is the case because href="" is not a script-initiating attribute (such as onclick). The problem is that in this situation i won't be able to access the tag beyond what i already do.
Therefore i either need
1.) A way to pass the event object to the doSomething() function from within the href attribute
or
2.) A way to stop the event propagation right in that anchor (after its clicked) by other means.
Thank You for any constructive input!
You cannot stop event propagation from the href attribute because:
When the href code executes, it is not an event. It just executes that code, similar to the "location hack". Like entering javascript:doSomething() in the browser's address bar.
The href code executes after the events fire on the link -- including bubbling.
You can see that behavior in this jsFiddle. Note that mouseup, mousedown, and click all fire both for the link, and on the container when the link is clicked, before the href code executes.
If there are event listeners that you want to block, you'll have to find another way.
But, if you can append javascript to the document you can block the href using preventDefault().
For example:
jQuery, before version 1.7:
$("#container a").bind ("mousedown mouseup click", function (e) {
e.preventDefault();
} );
jQuery 1.7 and later:
$("#container a").on ("mousedown mouseup click", function (e) {
e.preventDefault();
} );
or (better):
$("#container").on ("mousedown mouseup click", "a", function (e) {
e.preventDefault();
} );
You can see this last version live at jsFiddle.
If you cannot alter the link itself (to use onclick) then your only option is to alter the onclick handler of the container.
Can you do something like
function containerClickHandler(e) {
e = e || event;
var el = e.target || e.srcElement;
if (el.nodeName === 'A' && someOtherMatchChecks) {
// eat event
}
else {
// process event
}
}
Well, this is an old question, but in my particular case I did find a hack around it, but it might only apply to a subset of situations. I have a div that has an onclick. But if an inside that div is clicked, I don't want that div's onclick to fire. Here is what I do:
function myOnClick () {
// loop over all <a>'s, and test if they are hovered over right now.
var allLinks = document.links;
var dont = 0;
for (var i = 0, n = allLinks.length; i < n; i++) {
// pure javascript test to see if element is hovered.
if(allLinks[i].parentElement.querySelector(":hover") === allLinks[i]) {dont = 1; }
};
if(dont)return;
// your stuff here, only fires when dont is false.
}
I learned about the queryselector trick here: https://stackoverflow.com/a/14800287/2295722
I don't know if there is a way to get the arguments if you write your javascript in href attribute. But you can get it as following in onclick, but as you say this isn't the best practice:
<a onclick="console.log(arguments)">your link</a>
in arguments array you'll get your event object.
here is a demo for you:
http://jsfiddle.net/tEw5J/1/

Setting onclick event removing the handlers attached before

What is the difference betwen setting the onclick function in this way:
obj.onclick=new Function('functionname')
and
obj.onclick=function(){ functionname();};
How can i set the onclick event removing all previrius attached? (using jquery or simply javascript)
i try something like this:
$(obj).unbind('click');
$(obj).click(function() {
functionname();
});
but the unbind seems to remove even the next attached events.
thanks
EDIT:
I set the click event using jquery:
function ON(){
$('#makecorr').unbind('click');//i unbind for some reason..
$('#makecorr').click(function() { OFF(); });
}
function OFF(){
$('#makecorr').unbind('click');//i want to remove prev attached fun
//and replace it with new event
$('#makecorr').click(function() { ON(); });
}
this doesnt work for me, when i click the object 'makecorr' it goes in loop , if i put an alert, it comes up infinitely
but when i use: '
function ON(){
$('#makecorr').get(0).onclick=new Function('OFF()');
}
function OFF()
{
$('#makecorr').get(0).onclick=new Function('ON()');
}
it works. strange where am i wrong?
This pair of lines:
$(obj).unbind('click');
$(obj).click(function() { functionname(); });
...if executed in the order above should result in just the handler you've defined there being attached. If you're seeing other behavior, it must be something else in the script.
Regarding
What is the difference betwen setting the onclick function in this way:
obj.onclick=new Function('functionname') and
obj.onclick=function(){ functionname();};
If you're dynamically adding handlers to an element and you're already using jQuery for other reasons, you don't want to use the onclick property at all; stick to the jQuery API, to avoid really confusing yourself. :-)
Even if you're not using jQuery, you almost never want to use new Function(...). There are only very special situations where you'd need that. Mostly stick to function() { functionname(); } (or just use functionname directly).

Categories