Intercept javascript event - javascript

Here's what I'm trying to do :
I have a page with some links. Most links have a function attached to them on the onclick event.
Now, I want to set a css class to some links and then whenever one of the links is clicked I want to execute a certain function - after it returns , I want the link to execute the onclick functions that were attached to it.
Is there a way to do what I want ? I'm using jQuery if it makes a difference.
Here's an attempt at an example :
$("#link").click(function1);
$("#link").click(function2);
$("#link").click(function(){
firstFunctionToBeCalled(function (){
// ok, now execute function1 and function2
});
}); // somehow this needs to be the first one that is called
function firstFunctionToBeCalled(callback){
// here some user input is expected so function1 and function2 must not get called
callback();
}
All this is because I'm asked to put some confirmation boxes (using boxy) for a lot of buttons and I really don't want to be going through every button.

If I understand you correctly, is this wat you wanted to do..
var originalEvent = page.onclick; //your actual onclick method
page.onclick = handleinLocal; //overrides this with your locaMethod
function handleinLocal()
{ ...your code...
originalEvent ();
// invoke original handler
}

I would use jQuery's unbind to remove any existing events, then bind a function that will orchestrate the events I want in the order I want them.
Both bind and unbind are in the jQuery docs on jquery.com and work like this...
$(".myClass").unbind("click"); // removes all clicks - you can also pass a specific function to unbind
$(".myClass").click(function() {
myFunctionA();
myFunctionB($(this).html()); // example of obtaining something related to the referrer
});

An ugly hack will be to use the mousedown or mouseup events. These will be called before the click event.

If you can add your event handler before the rest of handlers, you could try to use jQuery's stopImmediatePropagation

Related

Define custom event

I wanna learn how to define a custom event, but not exactly as it is said over the net! let me illustrate:
In the jQuery Website in the part Introducing Custom Events it teaches you how to create a custom event in your code:
e.g.
$(document).on('myEvent',function(){
alert('Hello World');
});
then on an event, you'll call:
$(document).trigger('myEvent');
Well, no problem until here. to go further I have to give you another example:
The Question:
let's say we've defined:
$.fn.myEvent=function(callback){
$(document).bind('contextmenu',this,callback);
};
so we can use it as:
$(document).myEvent(function(){
alert('Hello World');
});
my question here is, how can we define "myEvent" so that we can use it as:
$(document).on('myEvent',function(){
alert('Hello World');
});
with the functionality of the $(document).myEvent(); so that we can pass a callback function to it without needing to actually trigger the event?
More Explanation:
for example, when we call $(document).on('click'); we don't actually need to trigger the click event elsewhere like $(document).trigger('click') in order to get it to work, so whenever click happens the function fires. I wanna have an event listener for "myEvent" so that when the conditions are matched, the function fires.
In another word (as mentioned below in the comments), I wanna know if there's a way to let jQuery treat "myEvent" as if it is one of the default events (click, mousemove, submit, etc).
Any answer or idea is highly appreciated.
I wanna have an event listener for "myEvent" so that when the conditions are matched, the function fires.
How would the engine know what "conditions" you mean? No, "custom events" are called custom because they are not natively trigged (through some lower-level action), but by custom code.
You may trigger a custom event whenever you see the condition matched that you're looking for.
About the definition of $.fn.myEvent, you might want to have a look at how the shortcuts for native events are created (where name would be "myEvent").
You're lumping together two different points:
how events work on general, and
how a browser environment dispatches events related to user action.
For the first point, I'll quote from another answer of mine:
In JavaScript, a custom event is simply a message, broadcast to all event listeners, that says, "Attention everyone: event X just happened!" Any listener that cares about that event can then run some function.
That's how events work in JavaScript. You set up listeners, and later something triggers the event. The trigger acts as a message to the listeners, telling them to run.
I've just said something triggers an event: we'll call that thing the initiator of the event. With custom events, the initiator is always other JavaScript code that you write (or that comes from a library, etc.). However, with native events the initiator is the browser itself. There is no way for JavaScript to control how the browser chooses to dispatch events.
The best you can do is listen for native browser events and then have those listeners dispatch custom events themselves.
For people who are wondering (like I did in the last 2 years) you can create a custom event (using pure javascript) as explained below:
var myEvent = new Event('myEvent');
and then you can use it like this:
document.querySelector('button').addEventListener(myEvent, function () {});
Simple Usage Example DEMO
Let's say we have a variable called bgColor and we want to change background color of 5 buttons, color of a paragraph and border color of an input anytime the bgColor value changes AND we don't want to use an interval to check on the value change and we also don't want to repeat the same code over and over again anytime the variable changes.
First we need to define our variables:
var bgColor='red',
eventName = 'bgColorChanged';
Then we need to listen for the event:
function Listen(elems,eventName,callback){
var event=new Event(eventName); //create the custom event
for(var i=0, elemsLength=elems.length; i < elemsLength; i++){ //iterate over the selected elements
elems[i].addEventListener(event,callback); //add event listener for our custom event
elems[i][eventName]=event; //store the event
//store the element
if(window.affectedElems){
window.affectedElems.push(elems[i])
}
else{
window.affectedElems=[];
window.affectedElems.push(elems[i])
}
//----------------------------
}
}
Now we can listen for our custom event like this:
Listen(document.querySelectorAll('button'),eventName,function(){
this.style.backgroundColor=bgColor;
});
Then we need a function to Dispatch/Fire our Event:
function dispatchEvent(eventName) {
var event=document.createEvent("HTMLEvents"), //defining the type of the event
elems=window.affectedElems; //getting the stored elements
//iterating over each element and dispatching the stored event
for(var i=0, elemsLength=elems.length; i < elemsLength; i++){
event.initEvent(elems[i][eventName], true, true);
event.eventName = eventName;
elems[i].dispatchEvent(event);
}
//-----------------------------------
}
Now we can fire our event like this:
dispatchEvent(eventName);
Now that everything's ready we just need to change the value of bgColor and just fire the event and let our system do the work.
bgColor='blue';
dispatchEvent(eventName);

Append my Event handler before existing handler

Let's suppose there is an <img> element that has some onclick event handler. For example onclick it does alert("OldEventHandler").
I would like to add my event handler there, before the existing one. For example my event handler function does alert("NewEventHandler").
So on click I would like to see "NewEventHandler" popup, and then "OldEventHandler" popup.
This needs to be implemented in pure JavaScript; no jQuery Please.
You can save the original handler, then call it after yours is done:
var oldHandler = myElement.onclick;
myElement.onclick = function() {
// do your stuff here
...
// then call the original
oldHandler.apply(this, arguments);
}
Another approach to this problem would be to create a generic event handler that stores an array of functions in some predefined order. When the onclick() event is fired, you can call the functions you need in that order.

Jquery remove and add back click event

Is it possible to remove than add back click event to specific element? i.e
I have a $("#elem").click(function{//some behaviour});, $(".elem").click(function{//some behaviour});(there are more than 1 element) while my other function getJson is executing I'd like to remove the click event from the #elem, and add it again onsuccess from getJson function, but preserve both mouseenter and mouseleave events the whole time?
Or maybe create overlay to prevent clicking like in modal windows? is that better idea?
edit :
I've seen some really good answers, but there is one detail that I omitted not on purpose. There are more than one element, and I call the click function on the className not on elementId as I stated in the original question
Rather than using unbind(), which means you'll have to rebind the same event handler later, you can use jQuery's data() facility with the ajaxStart and ajaxStop events to have your elements ignore click events during all AJAX requests:
$(".elem").click(function() {
if (!$(this).data("ajaxRequestPending")) {
// some behaviour
}
}).ajaxStart(function() {
$(this).data("ajaxRequestPending", true);
}).ajaxStop(function() {
$(this).removeData("ajaxRequestPending");
});
EDIT: This answer is also id-to-class-proof (see questioner's edit), since everything matching the selector will handle the AJAX events the right way. That's the main selling point of jQuery, and it shows.
You are looking for .unbind(). Pass it 'click' and it will destroy the click event.
I would put it just before your getJSON and re-bind the click event inside the success handler of your ajax call.
You have to do some additional scripting. There is no callback for that. Take a look over here: jQuery - How can I temporarily disable the onclick event listener after the event has been fired?
Rather than unbinding/binding the click event, you could check the state of another variable to see if it should do the action.
var MyObject = {
requestActive = false;
};
function MyJsonFunction() {
// when requesting
MyObject.requestActive = true;
//...
// when request over
MyObject.requestActive = false;
}
$("#elem").click(function{
if (MyObject.requestActive == true) {
//do something
}
});

In jQuery, is there any way to only bind a click once?

I have an ajax app that will run functions on every interaction. I'd like to be able to run my setup function each time so all my setup code for that function remains encapsulated. However, binding elements more than once means that the handler will run more than once, which is obviously undesirable. Is there an elegant way in jQuery to call bind on an element more than once without the handler being called more than once?
User jQuery one function like Tom said, but unbind the handler each time before binding again. It helps to have the event handler assigned to a variable than using an anonymous function.
var handler = function(e) { // stuff };
$('#element').unbind('click', handler).one('click', handler);
//elsewhere
$('#element').unbind('click', handler).one('click', handler);
You can also do .unbind('click') to remove all click handlers attached to an element.
You could attach the event to document with the one() function:
$(document).one('click', function(e) {
// initialization here
});
Once run, this event handler is removed again so that it will not run again. However, if you need the initialization to run before the click event of some other element, we will have to think of something else. Using mousedown instead of click might work then, as the mousedown event is fired before the click event.
You can also use .off() if unbind doesn't do the trick. Make sure the selector and event given to .off exactly match the ones initially provided to .on():
$("div.selector").off("click", "a.another_selector");
$("div.selector").on("click", "a.another_selector", function(e){
This is what worked for me in resolving the same ajax reloading problem.
The answer from Chetan Sastry is what you want. Basically just call a $(element).unbind(event); before every event.
So if you have a function like loadAllButtonClicks() that contains all the
$(element).on("click", function (){});
methods for each button on your page, and you run that every time a button is clicked, this will obviously produce more than one event for each button. To solve this just add
$(element).unbind(event);
before every
$(element).on("click", function (){});
and it will unbind all events to that element, then add the one click event.

Event handling jQuery unclick() and unbind() events?

I want to attach a click event to a button element and then later remove it, but I can't get unclick() or unbind() event(s) to work as expected. In the code below, the button is tan colour and the click event works.
window.onload = init;
function init() {
$("#startButton").css('background-color', 'beige').click(process_click);
$("#startButton").css('background-color', 'tan').unclick();
}
How can I remove events from my elements?
There's no such thing as unclick(). Where did you get that from?
You can remove individual event handlers from an element by calling unbind:
$("#startButton").unbind("click", process_click);
If you want to remove all handlers, or you used an anonymous function as a handler, you can omit the second argument to unbind():
$("#startButton").unbind("click");
Or you could have a situation where you want to unbind the click function just after you use it, like I had to:
$('#selector').click(function(event){
alert(1);
$(this).unbind(event);
});
unbind is your friend.
$("#startButton").unbind('click')
Are you sure you want to unbind it? What if later on you want to bind it again, and again, and again? I don't like dynamic event-handling bind/unbind, since they tend to get out of hand, when called from different points of your code.
You may want to consider alternate options:
change the button "disabled" property
implement your logic inside "process_click" function
Just my 2 cents, not an universal solution.

Categories