jQuery 或 JavaScript - 一旦它位于跨域 iframe 中,将焦点重新设置到 body 元素

Posted

技术标签:

【中文标题】jQuery 或 JavaScript - 一旦它位于跨域 iframe 中,将焦点重新设置到 body 元素【英文标题】:jQuery or JavaScript - set back the focus to a body element once it is in a cross domain iframe 【发布时间】:2017-07-19 13:27:30 【问题描述】:

我正面临一个问题,这个问题已经被问过了,但并不完全像我要做的那样(或者我还没有找到),即知道何时有人点击了我无法控制的跨域 iframe。 我已经看到有一些技巧可以得到它:我这样做了,它可以在 FF、IE 11 和 Chrome 上运行,监听一个 focusout() 事件;无论如何,它仅在有人第一次点击 iframe 时才有效。 现在,要知道用户是否再次单击,当此事件发生时,我已尝试将焦点重新放在文档正文中的元素上,但这不起作用。这是代码我写过:

<!DOCTYPE html>
<html lang="en">

    <head>

        <title>Focus() test</title>

        <!-- JQuery libraries -->
        <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.1.1/jquery.min.js"></script>

    </head>

    <body>

        <input type="text" id="myInput" value=""> <br />

        <div id="iframeContainer" style="height: 400px; width: 280px">
            <iframe id="theIframe"   src="https://docs.google.com/viewer?srcid=0B3R3uQMMhRrxUFJyYllhd0hVSkk&pid=explorer&efh=false&a=v&chrome=false&embedded=true"> </iframe>
        </div>

        <script>

            var clickNum = 0;

            $(document).ready(function()
                $("#myInput").focus();
                $("body").focusout(function() 
                    clickNum++;
                    alert("click num:" + clickNum);
                    $("#myInput").focus();
                );
            );

        </script>

    </body>

</html>

我也尝试替换 jQuery 代码的最后一行,即

$("#myInput").focus();

有几个实例:

$(this).next().focus();

正在尝试模拟 Tab 键。 事实上,当有人点击 iframe(在我的代码中的 Google Drive 预览的缩放控件之一上)时,焦点会被主体丢失并触发警报,但是我无法取回例如,专注于输入字段。 但是,如果有人按 Tab 键一定次数(这取决于之前单击的缩放控件和顺序),焦点将重新回到输入字段上,或者显然,如果有人在其中单击,则直接返回。 然后,如果有人再次单击某个缩放控件,则会再次触发警报,您​​可以跟踪单击次数。 所以我的最后一个问题是:一旦焦点转移到跨域 iframe 上,或者当您无法将跨域中的两个文档控制为在我的情况下,你没有任何希望找回它? 我知道这些事情可能已经被问过了,但我只是找到了整个问题的一部分,并不总是具有完全相同的上下文。 提前谢谢你, 费德里科

【问题讨论】:

【参考方案1】:

编辑(查看历史以获取上一个答案)

根据您的最后一条评论,表明您真正打算使用 iframe... 你可以这样使用我之前建议的“iframe mask”:

$(document).ready(function()

  // Onload input focus.
  $("#myInput").focus();

  // iframe mask creation
  var iframe = $("#iframeContainer");
  var maskCSS = 
    height:iframe.height(),
    width: iframe.width(),
    top: iframe.offset().top,
    left: iframe.offset().left,
    "z-index":999999,
    position:"absolute",
    "background-color":"red", // You may remove color and opacity. ;)
    "opacity":0.4
  ;

  var mask = $("<div>").css(maskCSS).attr("id","iframeMask");
  $("body").append(mask);
  //console.log(maskCSS);

  //
  // --------- Click handlers in/out the iframe
  //

  // Detect a click in the iframe (specifically: on the mask!)
  $("#iframeMask").on("click",function()
    console.log("Click detected on the iframe mask. => Remove the mask and resize the iframe.");

    $(this).css("z-index":-1);
    $("#iframeContainer, #theIframe").css("width":560,"height":800);
  );


  // Detect a click out the iframe
  $("body").not("#iframeMask").on("click",function(e)

    if( $(e.target).attr("id") != "iframeMask" )
      console.log("Click detected on the main document. => Reset iframe original size.");

      $("#iframeMask").css("z-index":999999);
      $("#iframeContainer, #theIframe").css("width":280,"height":400);
    
  );

);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

<input type="text" id="myInput" value=""> <br />

<div id="iframeContainer" style="height: 400px; width: 280px">
  <iframe id="theIframe"   src="https://docs.google.com/viewer?srcid=0B3R3uQMMhRrxUFJyYllhd0hVSkk&pid=explorer&efh=false&a=v&chrome=false&embedded=true"> </iframe>
</div>

因此,如果您运行上面的 sn-p(最好在全页模式下),您会看到 iframe 可以调整大小并重置回初始大小...

无法访问iframe 内部元素... 据我所知,这是不可能的。 但是您的意图只是控制容器大小,所以这是可能的,这就是我所做的:

    iframe 上方创建一个遮罩以检测用户焦点。

用户点击掩码:

    立即将此掩码移到iframe 下方,以便用户在其中单击。 顺便说一句,随意更改iframe 容器属性。 您甚至可以使用动画来提高流畅度!

用户在iframe之外点击:

    iframe 重置为其原始大小(如果您愿意,这不是强制性的)。 替换 iframe 上方的掩码,以便将来检测点击。

上面 sn-p 中的蒙版是红色的,不透明度为 40%... 但如果它是隐形的,它看起来就像魔法一样! ;)

【讨论】:

@Louys 谢谢,但是当用户单击 iframe 内 Google pdf 预览的缩放控件时,我试图触发一个动作。我希望在这些操作上调整 div 容器和 iframe 的大小。一切皆有可能,但我无法跟踪 iframe 上的点击事件(第一个除外)。我知道存在与安全原因相关的问题,但我希望有人知道是否有办法重新关注焦点,或者绝对不可能做到这一点。还是谢谢你 我明白了!我改进了我的答案。看一看! ;) 嗨 Louys,感谢您的努力,但这次您的代码并没有像我想的那样做。我希望焦点可以通过代码返回到输入字段,因此不依赖于用户操作(单击或其他操作)。我试图捕捉用户在跨域 iframe 内连续单击的时间。无论如何,目前我已经放弃了这种方式,因为我认为这是不可能的,而且我还注意到 Google 预览的其他问题。我已经开始关注 Pdf.js 项目,即使那样也不顺利:-(。我已经为此打开了一个新的帮助请求。Tx

以上是关于jQuery 或 JavaScript - 一旦它位于跨域 iframe 中,将焦点重新设置到 body 元素的主要内容,如果未能解决你的问题,请参考以下文章

jQuery淡入网站/内容一旦加载?

jquery中的事件

jQuery——事件和AJAX

在javascript或jQuery中检测iframe的负载(不是同一个域,动态添加)?

Jquery 或 Javascript mvc

如何通过 javascript 或 jquery 读取巨大的文本文件?