4

I want to display (on an iframe) a virtual cursor (an image with a cursor) which position I can control.

How can I simulate the hover and click events when the cursor is at a certain position on the iframe?

So it could be something like $('iframe').triggerClick(x,y) or $('iframe').triggerHover(x,y) .

Fiddle so you can try your answer: http://jsfiddle.net/PVJzb/1/

It even is enough if it works only in Google Chrome, don't need a cross-browser solution.

Note that the iframe is on the same domain so I can access its contents.

XCS
  • 27,244
  • 26
  • 101
  • 151

2 Answers2

1

This would be quite hard to do in JavaScript, and even if you code it perfectly it might still fail in some cases and/or browsers. You have to keep in mind that JavaScript can't really trigger native events directly, although there are some browser-specific exceptions, see this question for more information on that topic.


UPDATE: I would suggest that if this is something like a "how to use tutorial" you screen-record it and then play the video on the website. If you must really do it like this, it might be easier to move the cursor from the frame following a timed sequence, and have jQuery do all the necessary events, avoiding the detection of the element at x,y coordinates.


That being said, this is how I would solve this problem:

What you can do though is to simulate most events with JavaScript + jQuery. If you wanted to simulate the click event for all elements for example, you should first create a click event handler:

// Simulate their standard behavior
// if they already had a click event handler make sure it stops propagation
// or returns false, preventDefault won't stop the browser from following 
// their href now.
// Change the #iframe accordingly
$("#iframe").contents().find("a").bind('click', function(){
      window.location.href = $(this).attr('href');
});

Now to ensure that the newly bound click event gets fired we must trigger it manually. According to you question you know the coordinates where the virtual mouse is, so I'll suppose they are in variables x and y.

In order to get the element below the virtual mouse you could use the JavaScript function elementFromPoint(), but as most really useful JavaScript functions, it doesn't work the same way in all browsers.

I haven't tested this yet, but there is an improved version of the function available at http://www.zehnet.de/2010/11/19/document-elementfrompoint-a-jquery-solution/, supposing it works as it should let's move on.

It's very important to call elementFromPoint on the iframe and not in the current document, otherwise it will return the iframe element (More information here)

// x,y should be the coordinates where the virtual mouse is
var elementUnder = $("#iframe").contents().get(0).elementFromPoint(x,y);
if($(elementUnder) !== null){
    // Now you must decide what to do, probably depending on the element type
    // and finally, if it is an anchor, trigger the click event
    if($(elementUnder).is("a")) $(elementUnder).trigger('click');
} 

There may be easier or more elegant solutions, although I can't really think of any. Since the page inside the iframe is on the same domain, I guess you already know all of its possible contents, making this much easier since you can prepare the code for all necessary events.

For the mouse over event you would do the same, but remember you must also trigger the mouse out event.

I have added to your jsFiddle the code above, so that you can see it working on an anchor tag: http://jsfiddle.net/XySmQ/4/

You have to keep in mind that there are many events that JavaScript or jQuery can't recreate, such as a dropdown dropping down.

Community
  • 1
  • 1
aurbano
  • 3,324
  • 1
  • 25
  • 39
  • "This would be quite hard to do in JavaScript"? Is there an alternative to do this without javascript? – XCS Jan 02 '13 at 20:42
  • The fact that I don't know of other ways doesn't mean there aren't, although I would be amazed if anyone found an alternative – aurbano Jan 02 '13 at 22:01
  • I have added a jsFiddle with the code working on an anchor tag – aurbano Jan 02 '13 at 22:19
  • http://jsfiddle.net/XySmQ/3/ , nothing happens when the trigger is called with coordinates on the link... – XCS Jan 02 '13 at 22:24
  • You are probably using a browser that doesn't support elementFromPoint(), as I said in my answer this will be buggy at the very least. I'm testing on Google Chrome, and it works on it – aurbano Jan 02 '13 at 22:26
  • I am also using Google Chrome, but the link isn't being followed using the triggerStuff function... Only if I directly click on it. – XCS Jan 02 '13 at 22:27
  • let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/22087/discussion-between-chevi-and-cristy) – aurbano Jan 02 '13 at 22:30
1

Edit: Because of the way jsfiddle wraps iframes I can't test the code in jsfiddle, but I setup a quick test locally and the code below works fine.


I am afraid you can't trigger css hover from javascript. If you can modify the css so that hover effect will be triggered by class, (ie. element.hover instead of element:hover) that you can trigger.

So what I suggest you try is:

var iframeDoc = $('iframe').contents().get(0);
var lastHovered = [false];

$(iframeDoc).mousemove(function(e) {
    var elementHovered = iframeDoc.elementFromPoint(e.clientX, e.clientY);
    elementHovered = $(elementHovered);
    // remove previous added hover and add a new hover class
    if (lastHovered[0] != elementHovered[0]) {
        if (lastHovered[0]) lastHovered.removeClass('hover');
        lastHovered = elementHovered;
        elementHovered.addClass('hover');
    }
}).click(function(e) { 
    var elementClicked = iframeDoc.elementFromPoint(e.clientX, e.clientY);        
    alert("clicked element "+elementHovered); });
});
Iftah
  • 9,512
  • 2
  • 33
  • 45