over onmouse img eventos event div javascript iframe javascript-events onmousemove

javascript - onmouse - Detectar mousemove cuando sobre un iframe?



on over javascript (11)

Tengo un iframe que ocupa toda la ventana (100% de ancho, 100% de alto) y necesito que la ventana principal pueda detectar cuándo se ha movido el mouse.

Ya probé un atributo onMouseMove en el iframe y obviamente no funcionó. También intenté envolver el iframe en un div así:

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

.. y no funcionó. ¿Alguna sugerencia?


En su marco "primario", seleccione su iframe "secundario" y detecte el evento que le interesa, en su caso, mousemove

Este es un ejemplo de código que se utilizará en su marco "padre"

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


Encontré una solución relativamente simple a esto para un problema similar que estaba teniendo donde quería cambiar el tamaño del iframe y un largo con un div sentado al lado. Una vez que el mouse repasó el iframe jquery dejaría de detectar el mouse.

Para solucionar esto tuve un div sentado con el iframe, ambos rellenando la misma área con los mismos estilos, excepto el índice z del div (establecido en 0) y el iframe (establecido en 1). Esto permitió que el iframe se usara normalmente cuando no se cambia el tamaño.

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

Al redimensionar, el índice z de div se establece en 2 y luego vuelve a 0. Esto significaba que el iframe todavía estaba visible, pero la superposición lo estaba bloqueando, permitiendo que se detectara el mouse.


Este código parece funcionar, aunque no muy bien:

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

El evento hace que se activen los movimientos de cada ratón, pero solo en algunos de ellos. No sé si hay algún tipo de búfer interno de eventos dentro de ese evento ...


Iframes captura los eventos del mouse, pero puede transferir los eventos al ámbito principal si se cumple la política entre dominios. Así es cómo:

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

Ahora puede escuchar mousemove en el elemento iframe o cualquiera de sus elementos principales: el evento se disparará como esperaría.

Esto es compatible con los navegadores modernos. Si necesita que funcione con IE8 y createEvent , initMouseEvent usar los reemplazos específicos de createEvent de createEvent , initMouseEvent y dispatchEvent .


La página dentro de su iframe es un documento completo. Consumirá todos los eventos y no tendrá conexión inmediata con su documento principal.

Deberá capturar los eventos del mouse desde javascript dentro del documento hijo y luego pasarlo de alguna manera al padre.


Me he enfrentado a un problema similar, donde tuve divs que quería arrastrar sobre un iFrame. El problema era que si el puntero del mouse se movía fuera del div, en el iFrame, los eventos mousemove se perdían y el div dejaba de arrastrar. Si este es el tipo de cosas que quieres hacer (en lugar de solo detectar al usuario moviendo el mouse sobre el iFrame), encontré una sugerencia en otro hilo de preguntas que parece funcionar bien cuando lo probé.

En la página que contiene las y las cosas que quieres arrastrar, también incluye una como esta:

<div class="dragSurface" id="dragSurface"> <!-- to capture mouse-moves over the iframe--> </div>

Establecer su estilo inicial para ser algo como esto:

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

El índice z de ''98'' se debe a que configuro los div que quiero arrastrar para que sean z-index: 99, y el iFrame en z-index: 0.

Cuando detectes la supresión del ratón en el objeto a ser arrastrado (no en el div dragSurface), llama a la siguiente función como parte de tu controlador de eventos:

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"; }

Nota: ¡Recopilé la mayor parte de eso con el código de otra persona que encontré en Internet! La mayoría de la lógica está ahí para establecer el tamaño de la superficie de arrastre para llenar el marco.

Entonces, por ejemplo, mi controlador onmousedown se ve así:

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. } }

Cuando se detiene el arrastre, su controlador onmouseup debe incluir una llamada a este código:

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

Finalmente, crea la imagen de fondo (AlmostTransparent.png en mi ejemplo anterior) y la convierte en algo que no sea completamente transparente. Hice una imagen de 8x8 con alfa = 2.

Sólo he probado esto en Chrome hasta ahora . ¡Necesito que funcione también en IE, e intentaré actualizar esta respuesta con lo que descubro allí!


Otra forma de resolver este problema que me funciona bien es deshabilitar los eventos de movimiento del mouse en los iframe(s) con algo parecido al mouse down :

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

y luego, vuelva a habilitar los eventos de movimiento del mouse en los iframe(s) en el mouse up :

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

Probé algunos de los otros enfoques anteriores y funcionan, pero este parece ser el enfoque más simple.

Crédito a: https://www.gyrocode.com/articles/how-to-detect-mousemove-event-over-iframe-element/


Si su objetivo no es Opera 9 o inferior e IE 9 o inferior, puede usar pointer-events: none atributo css pointer-events: none .

Encontré la mejor manera de ignorar el iframe. Agrego clase con este atributo a iframe en el evento onMouseDown y onMouseUp en el evento onMouseUp .

Funciona perfecto para mi.


puede agregar una superposición encima de iframe cuando comienza el arrastre (evento onmousedown), y eliminarlo cuando el final del arrastre (en el evento mouserup). el plugin jquery UI.layout usa este método para resolver este problema.


MouseEvent.initMouseEvent() ahora está en desuso, por lo que la respuesta de @ Ozan es un poco anticuada. Como alternativa a lo que se proporciona en su respuesta, ahora lo hago así:

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

Donde establezca clientX & clientY , querrá pasar cualquier información del evento de la ventana de contenido al evento que enviaremos (es decir, si necesita pasar algo como screenX / screenY , hágalo allí).


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