I need to simulate a click or mouse event. I tried various things but the lib i am using doesnt seem to respond to it or does respond but only on specific browsers. ATM i do $('#target').val($('#target2').val()); which works on firefox and opera. Fails on chrome, IE8 and safari.
I could add events to the libs but i wouldnt know which event to add (or how to do it properly). Anyways how do i solve this? basically i am setting the textarea text with .val() and the lib doesnt seem to pick up that event.
You could use the DOM Level 2 Event Model, like:
function simulateClick(element) {
var evt = document.createEvent("MouseEvents");
evt.initMouseEvent("click", true, true, window, 0, 0, 0, 0, 0, false, false, false, false, 0, null);
cb.dispatchEvent(element);
}
Demo: http://www.jsfiddle.net/4yUqL/66/
This will truly simulate a mouseclick on an element. Regardless how events were bound.
.trigger('click') in jQuery might achieve what you're trying to do. It will fire all the handlers attached to the click event.
In case anyone bumps into this looking for a framework agnostic way to fire any HTML and Mouse event, have a look here: How to simulate a mouse click using JavaScript?
Related
Recording onmousedown and onmouseup to use in onmousemove does not work because onmouseup only fires once if the buttons are released outside the window: http://jsfiddle.net/f1nqproy/5/
event.button only returns meaningful results in Internet Explorer.
event.buttons only exists in Firefox.
So what to do with other browsers?
EDIT:
MouseEvent.buttons has been standardized now, so this problem has been solved:
https://developer.mozilla.org/en-US/docs/Web/API/MouseEvent/buttons
If you want to do something browser agnostic the easiest way is to use jQuery
jQuery is a fast, small, and feature-rich JavaScript library. It makes
things like HTML document traversal and manipulation, event handling,
animation, and Ajax much simpler with an easy-to-use API that works
across a multitude of browsers. With a combination of versatility and
extensibility, jQuery has changed the way that millions of people
write JavaScript.
You can easly bind to mouseup,mousedown event and forget about browser compatibility
$( window).mouseup(function(e){
console.log("mouseup:", e.button);
});
$( window).mousedown(function(e){
console.log("mousedown:", e.button);
});
-----UPDATE------
IE (as usual) do another work so you will not get the mouseup event if the pointer is outside the window.
An hack is to use the mouseleave event:
//hack for IE
$( window).mouseleave (function(e){
console.log("mouseleave");
});
JsFiddle
May be, the problem is that events onmouseup are triggered simultaneously by browser. Every time it checks, whether event triggered at the moment when mouse cursor is on the element, to which event was bound.
So, in your case first event triggers (don't know why), while the second doesn't work - it is correct behavior - instead mouseleave event triggered.
Try to catch mouseleave:
var buttonDown = [false, false, false];
$( window).on('mouseup mouseleave', function(e){
buttonDown[e.button] = true;
console.log("Buttons up:", buttonDown);
buttonDown = [false, false, false];
});
$( window).on('mousedown', function(e){
buttonDown[e.button] = true;
console.log("Buttons down:", buttonDown);
buttonDown = [false, false, false];
});
Is there a way to detect if a browser supports event capturing as well as event bubbling? I have checked http://modernizr.com/ but can't see any information in the documentation.
Am I correct in thinking that IE < 9 doesn't support event capture but in other browsers it should be ok?
For clarity I want to detect if the browser supports the event capture phase of the event DOM model as well as the event bubble phase.
There may be better approaches to this, but this is the first thing I came up with. You would need to create an element, bind an event handler to it in capture phase, fire an event on it, and check the eventPhase property in the event handler:
var button = document.getElementById("example");
document.addEventListener("click", function (e) {
console.log(e.eventPhase); // 1 === capture, 2 === target, 3 === bubble
}, true);
evt.initMouseEvent("click", true, true, window, 0, 0, 0, 0, 0, false, false, false, false, 0, null);
button.dispatchEvent(evt);
You would probably want to add in all sorts of other checks (e.g. for dispatchEvent support) and you'd need to actually create the button element in the code (and insert it into the DOM, hidden).
Here's a fiddle containing the above code to get you started.
I am thinking about making a Firefox add-on of my own and doing some experiments for the functionality I might be adding in it.
As I am just checking the feasibility of things for now, I just got a skeleton created from Mozilla add-on builder and started working in it. What I am trying right now is to send mouse click or key press events.
I have tried the available ways to send event but somehow it's not working for key events
I tried it using dispatchEvent:
onMenuItemCommand: function(e) {
netscape.security.PrivilegeManager.enablePrivilege('UniversalXPConnect');
var evt1 = document.createEvent("MouseEvents");
evt1.initMouseEvent("click", true, true, window,
0, 0, 0, 0, 0, false, false, false, false, 0, null);
//it's returning me null for document.getElementById... so I changed it.
var cb1 = gBrowser.selectedBrowser.contentDocument.getElementById("strict");
var canceled1 = !cb1.dispatchEvent(evt1);
var evt = document.createEvent("KeyEvents");
evt.initKeyEvent("keydown", true, false, window,
false, false, false, false, 0x42, 0);
var cb = gBrowser.selectedBrowser.contentDocument.getElementById("filter");
var canceled = !cb.dispatchEvent(evt);
if(canceled)
{
// A handler called preventDefault
alert("canceled");
}
else
{
// None of the handlers called preventDefault
alert("not canceled");
}
}
When I tried this code in Firefox, it did updated the checkbox which means click event worked, but nothing happened in textbox where I was expecting it to print a character. But it showed alert box with "not Cancelled" proving that event was not cancelled!
As event was not cancelled, I decided to put a keypressed handler on window.document... and it got invoked when add-on send these events! Which means the events are getting generated and are bubbling as well.
Then why only mouse events are working and key events are not? Am I missing something here?
(I have also tried sendKeyEvent with nsIDOMWindowUtils. still had no luck with it.)
btw, I am using Firefox 3.6.15 with Gecko :1.9.2.15
You have to focus the element before you can dispatch a key event to it.
EDIT:
This is only true for web pages. Extensions can dispatch keypress events to any text field.
EDIT:
Text entry is done via keypress events, not keydown events.
EDIT:
You won't get any characters inserted if you don't provide a character code. (Sorry for overlooking that, it should have been obvious.) Also although it seems to work with your window you should pass in the browser's contentWindow as the defaultView.
I want to simulate a click to an anchor tag with all extras like correct target handling.
There seems to be a "[click()][3]" method for anchor's DOM object but not all browsers support that. Firefox throws this error:
Error: anchorObj.click is not a function
It also works strangely on Opera 10 and Konqueror, causing infinite clicks to happen when it's called inside onclick handler of a surrounding div. I guess only IE8 works fine with it. Anyway I don't want it since major browsers mostly have problems with it.
I found this alternate solution for Firefox in Mozilla forums:
var evt = document.createEvent("MouseEvents");
evt.initMouseEvent("click", true, true, window,
0, 0, 0, 0, 0, false, false, false, false, 0, null);
anchorObj.dispatchEvent(evt);
This seems too ugly and cumbersome for me. I don't know how compatible it is and I want to avoid writing browser specific code as much as possible.
I can't use location.href = anchorObj.href; because it doesn't handle "target" attribute. I can do some hard coding based on target's value but I'd like to avoid that as well.
There is suggestion of switching to JQuery but I'm not sure how well it handles target property either since I haven't worked with it before.
Here is a complete test case that simulates the click event, calls all handlers attached (however they have been attached), maintains the "target" attribute ("srcElement" in IE), bubbles like a normal event would, and emulates IE's recursion-prevention. Tested in FF 2, Chrome 2.0, Opera 9.10 and of course IE (6):
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<script>
function fakeClick(event, anchorObj) {
if (anchorObj.click) {
anchorObj.click()
} else if(document.createEvent) {
if(event.target !== anchorObj) {
var evt = document.createEvent("MouseEvents");
evt.initMouseEvent("click", true, true, window,
0, 0, 0, 0, 0, false, false, false, false, 0, null);
var allowDefault = anchorObj.dispatchEvent(evt);
// you can check allowDefault for false to see if
// any handler called evt.preventDefault().
// Firefox will *not* redirect to anchorObj.href
// for you. However every other browser will.
}
}
}
</script>
</head>
<body>
<div onclick="alert('Container clicked')">
<a id="link" href="#" onclick="alert((event.target || event.srcElement).innerHTML)">Normal link</a>
</div>
<button type="button" onclick="fakeClick(event, document.getElementById('link'))">
Fake Click on Normal Link
</button>
<br /><br />
<div onclick="alert('Container clicked')">
<div onclick="fakeClick(event, this.getElementsByTagName('a')[0])"><a id="link2" href="#" onclick="alert('foo')">Embedded Link</a></div>
</div>
<button type="button" onclick="fakeClick(event, document.getElementById('link2'))">Fake Click on Embedded Link</button>
</body>
</html>
Demo here.
It avoids recursion in non-IE browsers by inspecting the event object that is initiating the simulated click, by inspecting the target attribute of the event (which remains unchanged during propagation).
Obviously IE does this internally holding a reference to its global event object. DOM level 2 defines no such global variable, so for that reason the simulator must pass in its local copy of event.
Quoted from https://developer.mozilla.org/en/DOM/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.
Unfortunately it sounds like you have already discovered the best solution to your problem.
As a side note, I agree that your solution seems less than ideal, but if you encapsulate the functionality inside a method (much like JQuery would do) it is not so bad.
There is a simpler way to achieve it,
HTML
Bootstrap is life !
JavaScript
// Simulating click after 3 seconds
setTimeout(function(){
document.getElementById('fooLinkID').click();
}, 3 * 1000);
Using plain javascript to simulate a click along with addressing the target property.
You can check working example here on jsFiddle.
well, you can very quickly test the click dispatch via jQuery like so
$('#link-id').click();
If you're still having problem with click respecting the target, you can always do this
$('#link-id').click( function( event, anchor )
{
window.open( anchor.href, anchor.target, '' );
event.preventDefault();
return false;
});
None of the above solutions address the generic intention of the original request. What if we don't know the id of the anchor? What if it doesn't have an id? What if it doesn't even have an href parameter (e.g. prev/next icon in a carousel)? What if we want to apply the action to multiple anchors with different models in an agnostic fashion? Here's an example that does something instead of a click, then later simulates the click (for any anchor or other tag):
var clicker = null;
$('a').click(function(e){
clicker=$(this); // capture the clicked dom object
/* ... do something ... */
e.preventDefault(); // prevent original click action
});
clicker[0].click(); // this repeats the original click. [0] is necessary.
I'm attempting to write a Vimperator plugin to allow use of hints mode to simulate mouse over on drop down menus. I have the hints mode working and can correctly choose elements that have mouseover events attached. The problem is my function to simulate the mouse over is not working. This is what I currently have:
function SimulateMouseOver(elem)
{
var evt = elem.ownerDocument.createEvent('MouseEvents');
evt.initMouseEvent('mouseover',true,true,
elem.ownerDocument.defaultView,0,0,0,0,0,
false,false,false,false,0,null);
var canceled = !elem.dispatchEvent(evt);
if(canceled)
alert('Event Cancelled');
}
The above code works for some pages but not for others. For example it doesn't work on AccuWeather. Any ideas how to simulate a mouse over that will work for most pages?
here's some code to start with to create the event, simpler and works for more browsers (if you don't need to specify exact mouse coordinates)
if( document.createEvent ) {
var evObj = document.createEvent('MouseEvents');
evObj.initEvent( 'mouseover', true, false );
elem.dispatchEvent(evObj);
} else if( document.createEventObject ) {
elem.fireEvent('onmouseover');
}
hope that helps
In case anyone bumps into this looking for a framework agnostic way to fire any HTML and Mouse event (and set some options, if needed), have a look here: How to simulate a mouse click using JavaScript?
You may only trigger mouseover event on fields/elements that have a mouseover event bound to them. You can't just hijack the mouse.