在 iframe 上检测鼠标移动?

IT技术 javascript iframe dom-events onmousemove
2021-03-05 15:45:37

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

已经onMouseMove在 iframe 上尝试了一个属性,但显然没有用。还尝试将 iframe 包装在 div 中,如下所示:

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

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

6个回答

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

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

非常适合我。

哇。我花了几个小时在这上面。认为这是THAT容易。非常感谢!
2021-04-16 15:45:37
这是一个很棒的,我相信是最好的解决方案。目前唯一的缺点是 IE 尚不支持指针事件属性。caniuse.com/#search=pointer-events
2021-04-29 15:45:37
唯一的问题是您无法在指针事件设置为无的情况下以任何方式与 iframe 交互,因此对于很多用例,这将不起作用
2021-04-30 15:45:37
有什么办法可以让 iframe 仍然可以交互吗?
2021-05-04 15:45:37

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

有关弃用和如何处理它的更多信息,请参阅我的最新答案
2021-05-14 15:45:37

解决此问题的另一种对我来说效果很好的方法是在 上禁用鼠标移动事件,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/

对我有用的非常简单的解决方案。值得尝试。
2021-04-23 15:45:37

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 );

    });

};

在我设置的位置clientXclientY您需要将内容窗口事件中的任何信息传递给我们将要调度的事件(即,如果您需要传递诸如screenX/ 之类的内容screenY,请在那里执行)。

@dieterh 很高兴听到
2021-04-19 15:45:37
一个好的开始,但不完整。并非所有相关数据都从 iframe 上捕获的事件复制到生成的克隆。缺少的一件事是 evt.buttons。看看 MouseEvent 有多少个键,我几乎可以肯定这不是唯一缺少的东西。通过将这个解决方案与 Jagi 的解决方案并排运行,人们应该能够一步一步地“填补空白”。
2021-04-20 15:45:37
IE 没有 CustomEvent,但有一个 polyfill,请参阅developer.mozilla.org/en-US/docs/Web/API/CustomEvent/...
2021-04-20 15:45:37
我正在使用此解决方案并添加了一行,即 evt.buttons = event.buttons,它适用于我正在做的事情。对于其他用例,您可能需要复制更多,正如我所说。
2021-05-05 15:45:37
也许使用 Object.keys 遍历所有键,并进行标准克隆,然后仅手动执行某些更改的键,例如解决方案中的 .clientX、.clientY。
2021-05-16 15:45:37

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

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

任何想法如何正确传递鼠标坐标?
2021-05-01 15:45:37