通过iframe检测mousemove?

Cha*_*ink 23 javascript iframe onmousemove javascript-events

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

已经onMouseMove在iframe上尝试了一个属性,它显然不起作用.还尝试将iframe包装在div中,如下所示:

<div onmousemove="alert('justfortesting');"><iframe src="foo.bar"></iframe></div>
Run Code Online (Sandbox Code Playgroud)

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

Jag*_*agi 25

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

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

适合我的作品.

  • 这是一个伟大的,我相信最好的解决方案.目前唯一的缺点是IE还不支持指针事件属性.http://caniuse.com/#search=pointer-events (3认同)
  • 除了iframe仍然可以交互之外,是否有其他方法可以工作? (2认同)
  • 唯一的问题是,在指针事件设置为none的情况下,您无法以任何方式与iframe进行交互,因此在很多用例中,这将无法正常工作 (2认同)

小智 23

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);
Run Code Online (Sandbox Code Playgroud)

您现在可以在iframe元素或其任何父元素上侦听mousemove - 事件将像您期望的那样冒泡.

这与现代浏览器兼容.如果您需要将其与IE8及以下工作,你需要使用的IE特有的替代品createEvent,initMouseEventdispatchEvent.


Ian*_*ton 7

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

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

  • 任何想法如何正确传递鼠标坐标? (3认同)

jer*_*emy 7

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

    });

};
Run Code Online (Sandbox Code Playgroud)

在我设置的地方clientX,clientY您要将内容窗口事件中的任何信息传递给我们将要发送的事件(即,如果您需要传递类似screenX/的内容screenY,请执行此操作).


Loo*_*ole 6

我遇到过类似的问题,我有一个 div,我想在 iFrame 上拖动它。问题是,如果鼠标指针移到 div 之外,移到 iFrame 上,则 mousemove 事件丢失并且 div 停止拖动。如果这是您想要做的事情(而不是仅仅检测用户在 iFrame 上挥动鼠标),我在另一个问题线程中找到了一个建议,当我尝试它时似乎效果很好。

在包含和要拖拽的东西的页面中,还包括这样的:

<div class="dragSurface" id="dragSurface">
<!-- to capture mouse-moves over the iframe-->
</div>
Run Code Online (Sandbox Code Playgroud)

将其初始样式设置为如下所示:

.dragSurface
{
  background-image: url('../Images/AlmostTransparent.png');
  position: absolute;
  z-index: 98;
  width: 100%;
  visibility: hidden;
}
Run Code Online (Sandbox Code Playgroud)

'98' 的 z-index 是因为我将要拖动的 div 设置为 z-index:99,并将 iFrame 设置为 z-index:0。

当您在要拖动的对象(不是 dragSurface div)中检测到 mousedown 时,调用以下函数作为事件处理程序的一部分:

function activateDragSurface ( surfaceId )
{
  var surface = document.getElementById( surfaceId );
  if ( surface == null ) return;

  if ( typeof window.innerWidth != 'undefined' )
  { viewportheight = window.innerHeight; } 
  else
  { viewportheight = document.documentElement.clientHeight; }

  if ( ( viewportheight > document.body.parentNode.scrollHeight ) && ( viewportheight > document.body.parentNode.clientHeight ) )
  { surface_height = viewportheight; }
  else
  {
    if ( document.body.parentNode.clientHeight > document.body.parentNode.scrollHeight )
    { surface_height = document.body.parentNode.clientHeight; }
    else
    { surface_height = document.body.parentNode.scrollHeight; }
  }

  var surface = document.getElementById( surfaceId );
  surface.style.height = surface_height + 'px';
  surface.style.visibility = "visible";
}
Run Code Online (Sandbox Code Playgroud)

注意:我从网上找到的其他人的代码中抄袭了大部分内容! 大多数逻辑只是设置dragSurface 的大小以填充框架。

因此,例如,我的 onmousedown 处理程序如下所示:

function dragBegin(elt)
{
  if ( document.body.onmousemove == null )
  {
    dragOffX = ( event.pageX - elt.offsetLeft );
    dragOffY = ( event.pageY - elt.offsetTop );
    document.body.onmousemove = function () { dragTrack( elt ) };
    activateDragSurface( "dragSurface" ); // capture mousemoves over the iframe.
  }
}
Run Code Online (Sandbox Code Playgroud)

当拖动停止时,您的 onmouseup 处理程序应包括对以下代码的调用:

function deactivateDragSurface( surfaceId )
{
  var surface = document.getElementById( surfaceId );
  if ( surface != null ) surface.style.visibility = "hidden";
}
Run Code Online (Sandbox Code Playgroud)

最后,您创建背景图像(在我上面的示例中为 AlmostTransparent.png),并将其设置为完全透明以外的任何内容。我制作了一个 alpha=2 的 8x8 图像。

到目前为止,我只在 Chrome 中对此进行了测试。我也需要让它在 IE 中工作,并将尝试用我在那里发现的内容更新这个答案!


小智 5

对于一个类似的问题,我找到了一个相对简单的解决方案,我想调整 iframe 的大小,并且旁边有一个 div。一旦鼠标越过 iframe jquery 将停止检测鼠标。

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

<div id="frameOverlay"></div>  
<iframe></iframe>
Run Code Online (Sandbox Code Playgroud)

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


Gib*_*boK 5

在您的“父”框架上,选择“子” iframe并检测您感兴趣的事件 mousemove

这是在“父”框架中使用的代码示例

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


小智 5

解决此问题的另一种方法对我来说很好,是通过禁用鼠标移动事件,iframe(s)例如mouse down

$('iframe').css('pointer-events', 'none');
Run Code Online (Sandbox Code Playgroud)

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

$('iframe').css('pointer-events', 'auto');
Run Code Online (Sandbox Code Playgroud)

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

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