4

I have a textarea over a div. In the div I highlight certain parts of the text entered into the textarea. I'm trying to get mouse over events on the highlights but obviously I can't because they are under my textarea. I was thinking if this might be possible using mousemove events on the textarea to track the mouse coordinates but then I figured that that would do me no good as I can't determine the exact boundaries if the highlight spans.

my html setup

So the question is, how do I simulate mouseover and mouseout events for elements that do not receive these because they are under other element(s)?

EDIT:

I completed a workaround for this based on Marcus' answer. Full code for mouseover / mouseout events:

var mouseDown = false;
var mouseIsOver = false;
var lastOverElem = false;
textarea.mousemove(function(e) {
    if (!mouseDown) {
        textarea.hide();
        var elm = $(document.elementFromPoint(e.pageX, e.pageY));
        textarea.show();
        if (elm.hasClass("highlighted")) {
            /* MOUSE MOVE EVENT */
            if (!mouseIsOver) {
                mouseIsOver = true;
                /* MOUSE OVER EVENT */
            }
        } else {
            if (mouseIsOver) {
                mouseIsOver = false;
                if (lastOverElem) {
                    /* MOUSE OUT EVENT */
                }
            }
        }
    }
});

$('body').mousedown (function () {mouseDown = true;});
$('body').mouseup (function () {mouseDown = false;});
19greg96
  • 2,592
  • 5
  • 41
  • 55
  • 1
    http://stackoverflow.com/questions/1009753/pass-mouse-events-through-absolutely-positioned-element has a lot of ideas which may help you out. – Scott Mutch Jun 28 '13 at 16:45
  • Very interesting. However, I need the textarea above the other element so that the user can type text, select it, context-menu it etc. pointer-events:none; disables all these functionality. Also +1 for showing me tech I never knew existed – 19greg96 Jun 28 '13 at 16:50
  • 1
    One answer on that page suggested temporarily hiding the text area then using document.elementFromPoint method to pass the event on to the covered elements. Not sure how well that would work however. – Scott Mutch Jun 28 '13 at 16:55
  • @ScottMutch Actually didn't read your comment before implementing my test case, but this is exactly how it's done :) – mekwall Jul 01 '13 at 10:37

1 Answers1

2

You can use document.elementFromPoint. Obviously this doesn't work if the textarea is in front of the underlying highlighting container, but there's an app for that. You just need to temporarily hide the textarea before calling document.elementFromPoint and then show it directly afterwards.

var textarea = $("#linksTextarea");
textarea.on("mousemove", function(e) {
    // Temporarily hide the textarea
    textarea.hide();
    // Get element under the cursor
    var elm = $(document.elementFromPoint(e.pageX, e.pageY));
    // Show the textarea again
    textarea.show();
    if (elm.hasClass("highlighted")) {
        console.log("You're mouse is over highlighted text");
    }
});

Since the DOM is updated in real-time while the rendering of it is delayed until after all of your JavaScript has been executed, you don't have to worry about any visual glitching.

See test case on jsFiddle.

mekwall
  • 28,614
  • 6
  • 75
  • 77
  • I modified your fiddle to add mousemove events. But I would like your opinion on it. So.. http://jsfiddle.net/pLQYM/1/ what do you think? Is it too hackish? Or would it stand ground in a large scale project? – 19greg96 Jul 01 '13 at 15:37
  • 1
    @19greg96 Why would it be too hackish? There's no better way to do it ;) I'd probably combine `mousedown` and `mouseup` though, and use `document` instead of `body` since its a tad bit faster to select. [Here's an updated fiddle](http://jsfiddle.net/pLQYM/3/). – mekwall Jul 01 '13 at 20:09