I'm testing svg.js library, and have found problems declaring custom events. Here is the fiddle. Clicking on the first circle should change the color and it works:
circleOne.click(function() {
this.fill({ color: '#f06' })
})
Clicking the second circle should fire the custom event, but it doesn't:
var circleTwo = SVG.select('circle.circle-01');
circleTwo.on('myevent', function() {
alert('ta-da!')
})
function testMe() {
circleTwo.fire('myevent')
}
Changing .fire to .event doesn't help either. Any suggestions? Thanks in advance.
You never use testMe function to fire your event :)
Browser defined events are already fired when an event happens, for the custom event you have correctly defined what happens (alert) when it fires but if you intend it to go off at some point you have to fire it. You also made trigger function but you never used it.
You can fire it on browser defined triggers BUT then simply rather use those events, don't define custom.
Custom events are intended for different use cases. For example, you detected an object is untouched for 10 sec and you wanna notify some other part of the code to react to it. That event is not defined by default, you define it and have custom code checking that fire the event when the condition is met.
Try firing your event on for example click event or simply for testing put this at the end of the scrypt:
testMe();
Now you have fired your custom event when the script loads to that point and executes trigger function.
Related
I am working with a very large application with a lot of JavaScript. I am trying to determine how I can find the location where a click event is being removed from a specific element.
There is a simple event listener on a specific field added via jQuery (this is an example).
$(document).ready(function() {
$('#id-name').on('click', function(e) {
window.alert('hello');
});
});
If break execution right after this and examine the element in Chrome Inspector, I see the event attached to the element. However, once I continue execution and the page finishes loading, the element no longer has the event. Something is removing it, but I can't find out where this is happening.
Is there a way to listen for "event removal" and trigger code then, so that I can identify where and how this is getting removed? Any other suggestions in locating where the click event is being removed?
Maybe you could override the removeEventListener method and trace it back to see what's calling it.
window.removeEventListener = (type, listener, useCapture)=>console.trace(type, listener, useCapture)
My situation is that I am trying to trigger a single event using the jQuery .trigger() method. However the element I am triggering has multiple click event listeners.
Actually finding what these listeners are and what they trigger from the source code is probably not viable as its included in the sites main JS file and its all minified and pretty much unreadable.
At the moment I know that the element when clicked performs some kind of ajax call and loads more data into the DOM of the page (which is what i want to trigger), however it also displays an overlay (which is what I want to suppress temporarily).
As its just an overlay there are workaround I can make; using a display:none on it straight after click etc. However it would be much more elegant if i could somehow suppress all click events on this element except the desired event.
Any ideas if this is actually possible? And if so how I would go about it?
You need to register your own event at the top of the event chain. And cancel the event chain in your event. Here is a solution with writing a custom jquery extention.
$.fn.bindFirst = function (which, handler) {
var $elm = $(this);
$elm.unbind(which, handler);
$elm.bind(which, handler);
var events = $._data($elm[0]).events;
var registered = events[which];
registered.unshift(registered.pop());
events[which] = registered;
}
$("#elm").bindFirst("click", function(e) {
// edit: seems like preventing event does not work
// But your event triggers first anyway.
e.preventDefault();
e.stopPropagation();
});
Reference:
https://gist.github.com/infostreams/6540654
EDIT:
https://jsfiddle.net/8nb9obc0/2/
I made a jsFiddle and it seems like event preventing does not work in this example. There might be another solution.
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);
Would it be possible to somehow intercept the DOM ready event so that anything normally triggered within, say, $(document).ready(function() { ... } would not be executed? And then later manually trigger the event so that the code was executed?
In my case, I have a large amount of existing code that already relies on $(document).ready(function() { ... } and my hope is that I would not have to do a search/replace to have all of it rely on a custom manually triggered event.
jQuery.trigger() is made for such need
Any event handlers attached with
.bind() or one of its shortcut methods
are triggered when the corresponding
event occurs. They can be fired
manually, however, with the .trigger()
method. A call to .trigger() executes
the handlers in the same order they
would be if the event were triggered
naturally by the user:
If you do not want something to be "normally" triggered, it should not be in $(document).ready(on_ready_func). Everything inside it will load as soon as the DOM is loaded and before the page contents are loaded.
Instead, from on_ready_func cherrypick the things you want to trigger manually into another function say manual_func, and call that function at event of your choice.
Note that, ready function cannot be triggered using trigger, so you cannot fire the func again, unless you have it as a separate function.
Split-up is your best option.
var manual_func = function(){
// Manual loads
}
var on_ready_func = function(){
// only things to be loaded on dom ready
// e.g.
$('button#load_manual_trigger').bind('click', manual_func);
}
$(document).ready(on_ready_func);
Happy Coding.
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