Node webkit-catch iframe mouse events из родительского окна

Я пытаюсь создать перетаскиваемый iframe в моем приложении. Когда iframe сфокусирован, все события мыши запускаются внутри объекта внутреннего окна.

  • Я не могу слушать эти события внутри iframe и запускать их сам, потому что он может быть заблокирован содержимым iframe js
  • Я не могу создать невидимый слой над iframe, который поймает все события и переместит их в iframe, потому что события bultin не могут быть вызваны script (например, css hover)
  • Могу ли я поймать эти события в слое Node, не используя webkit DOM?

Ответ 1

Одна из моих идей - разместить прозрачный элемент (например, div) перед iframe, а затем перехватить события перемещения щелчка и мыши, чтобы сделать iframe перемещается.

Я сделал это здесь в plunker.

Код, как вы видите ниже, достаточно, чтобы понять эту идею и какие шаги необходимы, чтобы заставить iframe перемещаться. У него есть некоторые недостатки (быстро двигайте мышью), но вы можете сделать что-то для решения этих проблем.

<!DOCTYPE html>
<html>

  <head>
    <style>
      iframe, div {
        position: absolute;
        left: 20px;
        top: 20px;
        width: 200px;
        height: 200px;
      }
    </style>
  </head>

  <body>
    <iframe id="iframe" src="if.html"></iframe>
    <div id="div" onmousedown="startDrag(event)" onmouseup="stopDrag()" onmousemove="moveDrag(event)"></div>
  </body>


  <script>
    var objDiv = document.getElementById("div");
    var objDivCoordinates = {left: 20, top: 20};
    var objIframe = document.getElementById("iframe");
    var mouseX = null;
    var mouseY = null;
    var dragging = false;

    function startDrag(e) {
      mouseX = e.clientX;
      mouseY = e.clientY;
      dragging = true;
      objIframe.contentWindow.document.writeln("Starting Drag...<br>");
    }
    function moveDrag(e) {
      if(!dragging) return;

      var changeX = mouseX - e.clientX;
      var changeY = mouseY - e.clientY;

      objDivCoordinates.left -= changeX;
      objDivCoordinates.top -= changeY;
      objDiv.style.left = objDivCoordinates.left+"px";
      objDiv.style.top = objDivCoordinates.top+"px";
      objIframe.style.left = objDiv.style.left;
      objIframe.style.top = objDiv.style.top;

      mouseX = e.clientX;
      mouseY = e.clientY;
    }
    function stopDrag(e) {
      dragging = false;
    }
  </script>
</html>

Ответ 2

Вы можете попробовать создать простой EventEmitter и сохранить его на объекте node global. Поскольку global доступен во всех контекстах node -webkit, iframe может использовать его для emit вещей, о которых он хочет знать родительское окно, и родитель может также использовать его для событий emit, которые iframe может знать о.

Это решение, которое может сработать для вас?

Ответ 3

Из того, что я вижу, вы больше всего обеспокоены ситуацией, когда какой-то другой script отменяет выполнение вашего слушателя (вызывая stopPropagation), но вы можете вообще предотвратить эту ситуацию.

addEventListener(type, listener [, useCapture]) позволяет передать аргумент useCapture, который по умолчанию равен false. Если вы установите его на true, тогда вы будете в безопасности:

После запуска захвата все события указанного типа будут отправляется зарегистрированному слушателю до отправки на любой EventTarget под ним в дереве DOM.