通过iframe检测mousemove?

时间:2011-04-13 06:54:50

标签: javascript iframe javascript-events onmousemove

我有一个占据整个窗口的iframe(100%宽,100%高),我需要主窗口才能检测鼠标移动的时间。

已经在iframe上尝试了onMouseMove属性,但显然无效。还尝试将iframe包装在div中,如下所示:

<div onmousemove="alert('justfortesting');"><iframe src="foo.bar"></iframe></div>

..它没有用。有什么建议吗?

12 个答案:

答案 0 :(得分:23)

如果您的目标不是Opera 9或更低版本以及IE 9或更低版本,则可以使用css属性pointer-events: none

我发现这是忽视iframe的最佳方式。我将此属性的类添加到onMouseDown事件中的iframe,并在onMouseUp事件中删除。

适合我的作品。

答案 1 :(得分:22)

iframe捕获鼠标事件,但如果满足跨域策略,则可以将事件传输到父作用域。方法如下:

// This example assumes execution from the parent of the the iframe

function bubbleIframeMouseMove(iframe){
    // Save any previous onmousemove handler
    var existingOnMouseMove = iframe.contentWindow.onmousemove;

    // Attach a new onmousemove listener
    iframe.contentWindow.onmousemove = function(e){
        // Fire any existing onmousemove listener 
        if(existingOnMouseMove) existingOnMouseMove(e);

        // Create a new event for the this window
        var evt = document.createEvent("MouseEvents");

        // We'll need this to offset the mouse move appropriately
        var boundingClientRect = iframe.getBoundingClientRect();

        // Initialize the event, copying exiting event values
        // for the most part
        evt.initMouseEvent( 
            "mousemove", 
            true, // bubbles
            false, // not cancelable 
            window,
            e.detail,
            e.screenX,
            e.screenY, 
            e.clientX + boundingClientRect.left, 
            e.clientY + boundingClientRect.top, 
            e.ctrlKey, 
            e.altKey,
            e.shiftKey, 
            e.metaKey,
            e.button, 
            null // no related element
        );

        // Dispatch the mousemove event on the iframe element
        iframe.dispatchEvent(evt);
    };
}

// Get the iframe element we want to track mouse movements on
var myIframe = document.getElementById("myIframe");

// Run it through the function to setup bubbling
bubbleIframeMouseMove(myIframe);

您现在可以在iframe元素或其任何父元素上侦听mousemove - 事件会像您预期的那样冒出来。

这与现代浏览器兼容。如果您需要使用IE8及以下版本,则需要使用特定于IE的createEventinitMouseEventdispatchEvent替换。

答案 2 :(得分:7)

iframe中的页面是完整的文档。它将消耗所有事件,并且没有与其父文档的直接连接。

您需要从子文档中的javascript中捕获鼠标事件,然后以某种方式将其传递给父文件。

答案 3 :(得分:6)

MouseEvent.initMouseEvent()现已弃用,所以@Ozan的答案有点陈旧。作为他答案中提供的内容的替代方案,我现在正在这样做:

var bubbleIframeMouseMove = function( iframe ){

    iframe.contentWindow.addEventListener('mousemove', function( event ) {
        var boundingClientRect = iframe.getBoundingClientRect();

        var evt = new CustomEvent( 'mousemove', {bubbles: true, cancelable: false})
        evt.clientX = event.clientX + boundingClientRect.left;
        evt.clientY = event.clientY + boundingClientRect.top;

        iframe.dispatchEvent( evt );

    });

};

我在哪里设置clientX&amp; clientY您要将内容窗口事件中的任何信息传递给我们将要发送的事件(即,如果您需要传递screenX / screenY之类的内容,请执行此操作有)。

答案 4 :(得分:5)

在你的父母身上&#34;框架,选择你的孩子&#34; iframe并检测您感兴趣的事件,在您的情况下mousemove

这是您的父母&#34;中使用的代码示例。帧

document.getElementById('yourIFrameHere').contentDocument.addEventListener('mousemove', function (event) {
                console.log(, event.pageX, event.pageY, event.target.id);
            }.bind(this));

答案 5 :(得分:4)

另一种解决方法对我来说很有效的方法是在iframe(s)上禁用鼠标移动事件,类似于mouse down

$('iframe').css('pointer-events', 'none');

然后,在iframe(s)上的mouse up上重新启用鼠标移动事件:

$('iframe').css('pointer-events', 'auto');

我尝试了上面的其他一些方法并且它们有效,但这似乎是最简单的方法。

感谢:https://www.gyrocode.com/articles/how-to-detect-mousemove-event-over-iframe-element/

答案 6 :(得分:3)

<script>
// dispatch events to the iframe from its container
$("body").on('click mouseup mousedown touchend touchstart touchmove mousewheel', function(e) {
    var doc = $("#targetFrame")[0].contentWindow.document,
        ev = doc.createEvent('Event');
    ev.initEvent(e.originalEvent.type, true, false);
    for (var key in e.originalEvent) {
        // we dont wanna clone target and we are not able to access "private members" of the cloned event.
        if (key[0] == key[0].toLowerCase() && $.inArray(key, ['__proto__', 'srcElement', 'target', 'toElement']) == -1) {
            ev[key] = e.originalEvent[key];
        }
    }
    doc.dispatchEvent(ev);
});
</script>
<body>
<iframe id="targetFrame" src="eventlistener.html"></iframe>
</body>

答案 7 :(得分:2)

我找到了一个相对简单的解决方案,因为我遇到了类似的问题,我希望调整iframe的大小,并且在旁边坐着一个div。一旦鼠标移过iframe,jquery将停止检测鼠标。

为了解决这个问题,我有一个div坐在iframe中,除了div的z-index(设置为0)和iframe(设置为1)之外,它们都填充相同的样式。这允许在不调整大小时正常使用iframe。

<div id="frameOverlay"></div>  
<iframe></iframe>

调整大小时,div z-index设置为2,然后再返回0。这意味着iframe仍然可见,但覆盖层阻挡了它,允许检测到鼠标。

答案 8 :(得分:1)

文档中的基本方式

var IE = document.all?true:false;

// If NS -- that is, !IE -- then set up for mouse capture
if (!IE) document.captureEvents(Event.MOUSEMOVE);

// Set-up to use getMouseXY function onMouseMove
document.onmousemove = getMouseXY;

// Temporary variables to hold mouse x-y pos.s
var tempX = 0;
var tempY = 0;

// Main function to retrieve mouse x-y pos.s

function getMouseXY(e) {
  if (IE) { // grab the x-y pos.s if browser is IE
    tempX = event.clientX + document.body.scrollLeft;
    tempY = event.clientY + document.body.scrollTop;
  } else {  // grab the x-y pos.s if browser is NS
    tempX = e.pageX;
    tempY = e.pageY;
  }  
  // catch possible negative values in NS4
  if (tempX < 0){tempX = 0}
  if (tempY < 0){tempY = 0}  

  // show the position values in the form named Show
  // in the text fields named MouseX and MouseY
  console.log(tempX, tempY);
  return true;
}

检测鼠标移过 Iframe

window.frames['showTime'].document.onmousemove = getMouseXY;

检测鼠标在父 Iframe 下的子 Iframe 中移动

window.frames['showTime'].document.getElementById("myFrame").contentWindow.onmousemove = getMouseXY;

当浏览器中没有鼠标移动时触发空闲检测功能。

答案 9 :(得分:0)

此代码似乎有效,但效果不是很好:

<div id="test" onmousemove="alert('test');">
    <iframe style="width:200px; height:200px; border:1px solid black;">
        <p>test</p>
    </iframe>
</div>  

该事件会在每次鼠标移动时触发mot触发,但仅限于其中一些。我不知道该事件中是否存在某种内部事件缓冲区..

答案 10 :(得分:0)

您可以在拖动开始时(onmousedown事件)在iframe顶部添加叠加层,并在拖动结束时移除它(在mouserup事件上)。 jquery UI.layout plugin使用此方法来解决此问题。

答案 11 :(得分:0)

这是我使用jQuery的解决方案。您可以按照以下步骤检测多个事件。必须将.on()事件处理程序放入.on('load')事件处理程序中,因为否则当iframe导航到新页面时,它将停止检测iframe内容事件。此外,由于安全原因,我认为这仅在iframe内容与父页面位于同一域中时有效,并且无法解决此问题。

$(document).ready(function() {
    $('#iframe_id').on('load', function() {
        $('#iframe_id').contents().on('click mousemove scroll', handlerFunction);
    });
});

handlerFunction() {
    //do stuff here triggered by events in the iframe
}