I wrote a Chrome Extension that automatically fills some registration forms. There are some select fields that need to be triggered on "change" event in order to start some Ajax calls.
First I use JQuery attr or val to change the value of the select field, and than I use .trigger to invoke the "change" event, but this last one doesn't work.
Example:
I want to select the option that contains the word "London" and invoke
the change element in order to start some operations of the native
code that have some listeners on "change" event
jQuery("#SelectElement option:contains('London')").attr("selected", "selected");
jQuery("#SelectElement").trigger("change"); <--- not works
I tried also:
jQuery("#SelectElement option:containt('London')").attr("selected", "selected").change();
But if I try this code on console, it works.
Suggestions?
I had the same problem and as far as I know it's because of something called framework event listeners. that you cannot trigger from your code by jquery! but the solution is trigger the event this way:
$(selector)[0].dispatchEvent(new Event("eventName"))
In my case,
var event = new CustomEvent('change');
did not work.
I had to initialize the event like this:
var evt = document.createEvent("HTMLEvents");
evt.initEvent("keyup", true, true);
First arg 'bubbles' should be true so the event should bubble up through the event chain.
event.initEvent(type, bubbles, cancelable);
Source:
https://developer.mozilla.org/en-US/docs/Web/API/Event/initEvent
Related
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);
I want to do something like this:
function('string', function2(){})
where I leave the to user to write what he wants in the string parameter and than execute function2.
The catch is here: string is an event listener. When the user writes click, I want to call onClick(), when the user writes mouse I want to call onMouseOver and so on.
I have in mind doing something with case, but how can I access all event listeners?
You should use addEventListener.
element.addEventListener("string", function() {}, false);
However, in the case of IE <= 8, you will need to use attachEvent as it does not follow the standard:
element.attachEvent("string", function() {});
Finally, as kybernetikos mentions in his comment, you can then use a simple dictionary to map mouse to mouseover.
If you wish to fire events, you should use dispatchEvent.
If you add the event listeners using the old model (i.e. elem.onclick = function(){ /* */ };), you can use
elem['on' + event]();
Keep in mind that this only fires the event listeners, but doesn't create an event (e.g. it won't bubble).
If you won't to create a event, which fires event listeners added using addEventlistener, and bubbles, and does all things a real event does, you must
Create your event using event constructors: Event or CustomEvent
Fire it with dispatchEvent
See MDN page for more information and examples.
you can use .trigger to do this. Check out this example in jsfiddle. type "dblclick" in the input box.
http://jsfiddle.net/jspatel/Suj4H/1/
<input id="writehere"> </input>
$('#writehere').dblclick(function() {
alert ('dblclick');
});
$('#writehere').bind('keypress', function(e) {
if(e.keyCode==13){
$(this).trigger( $(this).val() );
}
});
I need to trigger event when user selects text in android touch device.In web browsers am able to trigger event by checking on each mouse up event whether window.getselection is null.
Touch select text event not triggering.
document.addEventListener('touchend', function(event)
{
if( window.getSelection){
t = window.getSelection().toString();
alert(t);
}
});
I tried in touchend event.But when user selects text event not triggering.
Why not try a jQuery solution using the .change() function? First you add the jQuery library immediately above your included JavaScript file declaration, then you've got jQuery capability in the document. Next read up on .change() and try something like:
$('#touchend').change(function(){
if(your condition){var $t = window.getSelection().toString();}
});
or whatever JavaScript code you want in the function. jQuery is simply a JavaScript library, so you can use it freely with your JavaScript. It's a gamechanger!
You actually want to listen to the event selectionchange.
Note that it will fire for both creating a selection and clearing the selection so when you get that event, you want to query the selection with window.getSelection() and check the status of isCollapsed.
What all events can be triggered programmatically using jQuery? Also is there any important differences to be remembered when one is doing event triggering using jQuery Vs a natural way of it being triggered?
Every event can be programmatically fired, just use the callback-less version of it.
Example:
$('#button').click(function() { alert('event hanlder'); });
$('#button').click(); // generate the event
About your second question, there should be no difference between the native and jQuery event handlers.
One thing that is neat though is that jQuery binds this to the element that received the event, inside the callback (this doesn't happen in native event handlers):
$('#button').click(function() { alert(this); }); // here 'this' == document.getElementById('button');
Warning: the element referenced by this is not "jQuery augmented". If you want to traverse or modify it with jQuery goodness you'll have to do something like var $this = $(this);
You should know the differences between trigger and triggerHandler in jQuery.
trigger
trigger attempts to replicate the natural event as best as it can. The event handler for the event being triggered get's executed, but the default browser actions will not always be replicated exactly. For example $('a#link).trigger('click'); will execute the javascript function bound to the links click event handler, but will not redirect the browser to the href of the anchor, like a normal click would. EX: http://jsfiddle.net/AxFkD/
All the short forms of the trigger call behave exactly like trigger IE. click(), mouseup(), keydown(), etc
triggerHandler
triggerHandler prevents bubbling up ( EX. http://jsfiddle.net/LmqsS/ ), it avoids default browser behaviour and just executes the events callback, and it returns the return value of the event handler instead of a jQUery object for chaining.
You should also be aware that trigger affects all elements matched by a selector, but triggerHandler only affects the first one EX: http://jsfiddle.net/jvnyS/
You can trigger any event programmatically. But most of the events cannot be simulated as the natural event using programmatic triggers.
//to trigger a click event on a button
$("buttonSelector").trigger("click");
First, for obvious reasons, you cannot trigger the ready event.
That said, events raised by trigger() behave the same way as if they were triggered by the user. In particular, the event handlers are called in the same order.
The only difference I know of is that triggered events did not bubble up the DOM tree in older versions of jQuery (that behavior was fixed in version 1.3).
I have a page with a select list (ASP.NET MVC Page)
The select list and onchange event specified like this:
<%=Html.DropDownList("CompanyID", Model.CompanySelectList, "(select company)", new { #class = "data-entry-field", #onchange = "companySelectListChanged()" })%>
The companySelectListChanged function is getting called twice?
I am using the nifty code in this question to get the caller.
both times the caller is the onchange event, however if i look at the callers caller using:
arguments.callee.caller.caller
the first call returns some system code as the caller (i presume) and the second call returns undefined.
I am checking for undefined to only react once to onchange, but this doesnt seem ideal, whcy would onchange be called twice?
UPDATE:
ok, found the culprit! ...apart from me :-) but the issue of calling the companySelectListChanged function twice still stands.
The onchange event is set directly on the select as mentioned. This calls the companySelectListChanged function.
..notice the 'data-entry-field' class, now in a separate linked javascript file a change event on all fields with this class is bound to a function that changes the colour of the save button. This means there is two events on the onchange, but the companySelectListChanged is called twice?
The additional binding is set as follows:
$('.data-entry-field').bind('keypress keyup change', function (e) { highLightSaveButtons(); });
Assuming its possible to have 2 change events on the select list, its would assume that setting keypress & keyup events may be breaking something?
Any ideas?
ANOTHER UPDATE:
The select element looks fine and all works if I remove the additional 'change' binding. when the 'change' binding is added that event fires once and the hard-wired 'onchange' is fired twice.
If both events are bound via jQuery all works ok, it seems that mixing hard-wired onchange and jquery bound change events cannot be mixed? I guess this answers my question but seems like an issue with IE and binding these events with jquery.
I agree with your assessment. I've updated my small example at http://gutfullofbeer.net/onchange.html to include a jQuery handler in addition to the DOM 0 handler (the one set with the "onchange" attribute). It appears to be a jQuery bug, or at least a failure of jQuery to deal with the IE weirdness.
I logged jQuery ticket 6593.
I also encountered this issue when using IE8 and made some changes to fix this.
Instead of specifying the onchange event on the dropdownlist, I used the jquery.change() event.
Markup:
#Html.DropDownList("drpList", myList, new { #class = "myClass", id = "drpList" })
Script:
$(function () {
$('#drpList').change(function () {
.... your functionality
});
});
This works for me.. Hopes this help.