Assume I get a table element with ID="emTab", how do I call JS to click it?
Thanks.
document.getElementById("emTab").onclick = function() {
// your code goes here
};
See element.onclick
To trigger click event
document.getElementById("emTab").click();
See element.click
The click method is intended to be
used with INPUT elements of type
button, checkbox, radio, reset or
submit. Gecko does not implement the
click method on other elements that
might be expected to respond to
mouse–clicks such as links (A
elements), nor will it necessarily
fire the click event of other
elements.
Non–Gecko DOMs may behave differently.
When a click is used with elements
that support it (e.g. one of the INPUT
types listed above), it also fires the
element's click event which will
bubble up to elements higher up the
document tree (or event chain) and
fire their click events too. However,
bubbling of a click event will not
cause an A element to initiate
navigation as if a real mouse-click
had been received.
Cross browser way
If you can use jQuery then it would be
$("#emTab").trigger("click");
Firing events cross-browser - http://jehiah.cz/archive/firing-javascript-events-properly
its simple using JQuery
$('#emTab').click(functionToCall);
while in JS
document.getElementById('emTab').onclick = function() {};
for details on DOM events:
http://www.howtocreate.co.uk/tutorials/javascript/domevents
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)
When I run both codes in the console, eventTarget.click() returns undefined but actually clicks the target element whereas eventTarget.dispatchEvent(new Event("click")) returns true but doesnt click the target element. I am trying to understand but I cant figure out why there are 2 different outcomes. Can you please explain why and how they are different? Arent both of them supposed to click the element on the page?
document.getElementById("button").click()
and
document.getElementById("button").dispatchEvent(new Event("click"))
The click() method is used to simulate a mouse click on the element. It fires the click event of the element on which it is called. The event bubbles up to elements higher in the document tree and fires their click events also.
The Event constructor is used to create a new event to be used on any element. The ‘click’ event can be passed to the constructor of Event to create a click event. This created Event has various properties which can be accessed to customize the event.
I will suggest using the MouseEvent instead of Event. Check below example
document.getElementById('eventTarget').click()
alert('before next')
document.getElementById('eventTarget').dispatchEvent(new MouseEvent("click"))
<input type="button" value="test" id="eventTarget" onclick="alert('clicked');"/>
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.
Ok, in my code I have for example, this:
$('.follow').click(function(){
var myself = $(this);
var data = {
id: this.getAttribute('data-id')
}
$.post('/users/setFriend', data, function(msg){
myself.text(msg);
myself.attr('data-status-friends', (myself.attr('data-status-friends').toLowerCase() == 'follow') ? 'following' : 'follow');
});
})
However, i put a class of 'auth' on certain elements that if the user is logged out, run this bit of JS:
$('.auth').click(function(e){
e.preventDefault();
alert('not logged in');
});
This works for the majority of elements, but with the above POST, it seems to still action the POST. How can I definitively cancel the events fired by other bits of code if .auth is clicked?
I don't think we should talk about propagation or defaultAction preventing here. The point is that you create two different series of event handlers: one attached to the .follow elements, another - to the .auth elements. Of course, if an element has two classes, clicking it will trigger both handlers automatically - and they both will be attached to this element (hence no propagation).
The most simple solution here, I think, is to remove click handler from an element when you assign .auth class to it.
Or, alternatively, you can check $(this).hasClass('auth') condition within the .follow handler function - and return false immediately if that's the case.
Rather than stopping the events, I think a better approach would be either to simply not put events into elements which aren't supposed to be doable without logging in, or track the auth state in your JS code with a variable and check that before doing actions. The latter would probably be a better approach to use if you are building a client-side MVC style application.
You could have two issues going on here with different sets of solutions.
The listeners are attached to different elements in reverse of what they should be
The listeners are being attached to the same element
Different Elements
Your handlers are out of order, swap them so that e.stopPropogation() is on the inner(child) element and the $.post() call is on the outter(parent) element.
Same Element
If the listeners are on the same element, neither e.stopPropogation() nor e.preventDefault() will do what you wish as the event listeners will still fire on the same element.
stopPropogation()
Description: Prevents the event from bubbling up the DOM tree,
preventing any parent handlers from being notified of the event.
Propagation according to the DOM Level 2 Spec will still execute all listeners on the same element but not events attached to the parent:
If the capturing EventListener wishes to prevent further processing of
the event from occurring it may call the stopProgagation method of the
Event interface. This will prevent further dispatch of the event,
although additional EventListeners registered at the same hierarchy
level will still receive the event.
preventDefault()
Description: If this method is called, the default action of the event
will not be triggered.
Default actions are are based on which element is being acted upon (W3C). For a link this would be the redirect to the href="" value, input element to focus it, etc. This is not what you desire as you are most likely not the 'default behavior'.
One option is to attach the handler that calls $.post to an element that is higher on the DOM.
$('.follow').parent().click(function(e){e.stopPropogation()})
You might have to alter your target HTML so that you have an inner(child) and outter(parent) element to attach your events to. The goal being to have the $.post handler as the outer(parent) and the inner(child) handler cancel the event.
Another option is to add a check to see if the other class is present on your element.
$('.follow').click(function(){
var myself = $(this);
if(!$(this).hasClass('.auth')){
var data = {
id: this.getAttribute('data-id')
}
$.post('/users/setFriend', data, function(msg){
myself.text(msg);
myself.attr('data-status-friends', (myself.attr('data-status- friends').toLowerCase() == 'follow') ? 'following' : 'follow');
});
}
});
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).