views:

1357

answers:

7

I want to have java script clicking a link on the page..I found something on the net that suggests adding a function like this:

function fireEvent(obj,evt){

    var fireOnThis = obj;
    if( document.createEvent ) {
      var evObj = document.createEvent('MouseEvents');
      evObj.initEvent( evt, true, false );
      fireOnThis.dispatchEvent(evObj);
    } else if( document.createEventObject ) {
      fireOnThis.fireEvent('on'+evt);
    }
}

Then call it using:

fireEvent(document.getElementById('edit_client_link'),'click');

This seems to work fine for FF but with IE it doesn't work!

Any ideas?

+5  A: 

I think you still need to call document.createEventObject -- you only checked that it's there. Untested code follows, but based on the docs it should work.

function fireEvent(obj,evt){

    var fireOnThis = obj;
    if( document.createEvent ) {
      var evObj = document.createEvent('MouseEvents');
      evObj.initEvent( evt, true, false );
      fireOnThis.dispatchEvent(evObj);
    } else if( document.createEventObject ) {
      document.createEventObject();
      fireOnThis.fireEvent('on'+evt);
    }
}
Anonymous
I went ahead and tested this myself in IE 7 and it works; nice job! I loathe the fact that everyone and their mom always jumps on the framework bandwagon when someone simply asked a JavaScript question. Yes, we know, we know, jQuery can do everything AND make dinner for you, but sometimes it's nice to know how things work without such a library. (I use both jQuery and MochiKit, but I still enjoy plain ol' JavaScript).
Jason Bunting
Wait, this doesn't make sense. You're calling `document.createEventObject()`, but not doing anything with the event it returns. How is this different from the code in the question, and why does it (supposedly) work? I'm tempted to think that Jason changed something else that made his code start working.
Sidnicious
+1  A: 

In JQuery it is like this:

$("#edit_client_link").click();

Works in IE, FireFox, Chrome, and Safari.

Chris Brandsma
+1 But I would use mootools ;-) The point is, use a Framework, why bother with that? (Aimed at the question writer).
Itay Moav
Not sure what's wrong here but I tried with the # before edit_client_link it didn't work neither in IE nor in FF. Then I removed the # so it because $("edit_client_link").click(); it worked with IE and not FF!! the other way around :).. For Itay: mootools is good and light, it's just that jQuery comes with Rails frameworks that I use and I'm using elsewhere...thanks for the tip
Tam
Sometimes learning the raw metal is a smart way before going into the metal itself. What I'm trying to say is it's smarter to learn javascript first then jQuery. How can you master the language if you dont have any idea of the raw codes?
rymn
@rmyn: Exactly - for example that's why I always tell people: before learning a higher-level language such as assembly, you should first try implementing some simple algorithms with transistors on a circuit board. Why bother learning to code if you don't understand the basic principles behind it, right?
Cam
A: 

This didn't work for me at first and then I saw the code is missing a parameter for the IE portion. Here's an update that should work:

function fireEvent(obj, evt) { var fireOnThis = obj;

if (document.createEvent) {
    // alert("FF");
    var evtObj = document.createEvent('MouseEvents');
    evtObj.initEvent(evt, true, false);
    fireOnThis.dispatchEvent(evtObj);
} 

else if (document.createEventObject) {
    // alert("IE");
    var evtObj = document.createEventObject();
    fireOnThis.fireEvent('on'+evt, evtObj);
}

}

Craig
A: 

I am testing a web app using WebDriver/Selenium-2.0a4 with IE8. My goal is to simulate a right-click in JavaScript since WebDriver doesn't allow it yet. As a way to get there, I am trying to simulate a left-click. I am using Eclipse IDE. Posts recommend creating an event and firing it with element.fireEvent; however I could not get that to work. It does not throw an error, but nothing else happens. Does this call work in WebDriver/Selenium-2.0a4 with IE8?

To give an example using JavaScript element.click() -- this DOES work to do a left-mouse click:

StringBuffer javaScript = new StringBuffer();
javaScript.append(" var element=document.getElementsByTagName('a');");
javaScript.append(" for (var i = 0; i < element.length; i++){ "); javaScript.append(" if (element[i].innerHTML.indexOf('approveRecordingDiv+')!=-1) {myElement= element[i]; } "); javaScript.append(" }");
javaScript.append(" myElement.click();");

((JavascriptExecutor) driver).executeScript(javaScript.toString()); Thread.sleep(3000);

But this does NOT work for me to left-click. Any suggestions?

// Same code as above, but, this is instead of myElement.click(); javaScript.append(" var fired = myElement.fireEvent('onclick');");

((JavascriptExecutor) driver).executeScript(javaScript.toString()); Thread.sleep(3000);

For right-click, I have tried several approaches which involve creating an event and using init to populate the values. The init statement causes an error.

I also read that for right click, you have to call use the parent document, rather than the element itself for the event. Neither approach has worked though.

javaScript.append(" var evt = elmnt.ownerDocument.createEventObject();"); -- I have also tried with passing MouseEvents and MouseEvent javaScript.append(" var evt = elmnt.ownerDocument.createEventObject('MouseEvents');");

javaScript.append("evt.initMouseEvent('click', true, true,"); javaScript.append(" elmnt.ownerDocument.defaultView, 1, 0, 0, 0, 0, false, false, false, false, 2, null);"); javaScript.append(" elmnt.fireEvent('onclick',evt); ");

The posts on line also do not seem to be using the JavascriptExecutor object, but maybe they just removed those references to make the code easier to read?

When I use the init, this is the error returned in Eclipse: Failed to execute: Exception occurred: System info: os.name: 'Windows XP', os.arch: 'x86', os.version: '5.1', java.version: '1.6.0_20' Driver info: driver.version: ie (function() { return function(){ var element=document.getElementsByTagName('a'); for (var i = 0; i < element.length; i++){ if (element[i].innerHTML.indexOf('approveRecordingDiv+')!=-1) {myElement= element[i]; } } var evt = myElement.ownerDocument.createEventObject('MouseEvents');evt.initMouseEvent('click', true, true);};})();

Rich
Is this an answer to the question?
molnarm
A: 

If you want to simulate clicks only for links, you can use this:

function clickLink(id){
location.href=document.getElementById(id).href;
}
molnarm
A: 

Thanks for the help, but there is still something missing from the explanation using fireEvent. The return result from the fireEvent is 'true' so the fireEvent is actually successful; however, the web element's event handler is not triggered. In my case, clicking the link runs some javascript, as below. The same code clicking on a button works.

<a href="javascript:swapVisibility('approveRecordingDiv-', 'approveRecordingDiv+');toggleDisplay('approveRecordingDiv')"><div id="approveRecordingDiv-">-</div><div style="display: none;" id="approveRecordingDiv+">+</div></a>

If I can get this to work, next step is to try right-click.

Rich
A: 

We found a simpler way to simulate right click (tested in IE8). Use a double click or two single clicks, then right-click using Shift-F10. I don't know exactly why this works, but it does. In the sample code below, we use the Selenium method to click twice, then use the IE Driver to find the WebElement and send the key sequence Shift-F10, which emulates the right-mouse button click. We use this to testing GWT based web apps. One place this did not work as well was in a tree control where the context menu was set to appear at the mouse's coordinates. Often, the mouse coordinates were negative, so right-clicking the menu item did not cause the child menu options to get displayed. To handle this case, we added a bit of code to the control so that if the mouse coordinates were negative, the context menu appears at a 0,0.

selenium.click("//td[@role='menuitem' and contains(text(), 'Add')]");
selenium.click("//td[@role='menuitem' and contains(text(), 'Add')]");
new InternetExplorerDriver().findElement(By.xpath("//td[@role='menuitem' and contains(text(), 'Add')]")).sendKeys(Keys.SHIFT, Keys.F10);
Rich