跨域的IFrame element.scrollIntoView()Safari浏览器问题

问题描述 投票:1回答:1

我已经跑进是困扰各地谷歌,但没有提供解决方案的正常工作的问题。我认为大多数这些解决方案中没有考虑跨域。

我有一个网站,我想指示用户嵌入到他们与一个(整版)IFrame的网站。问题是,只有Safari的某些版本。在iframe中的元素不能滚动自己进入视野。

enter image description here

我注意到,如果我做了同样的测试域该IFrame可以使用window.parent.scrollTo(0,element.top)滚动本身。这工作,但不能跨域。另一个奇怪的是,没有其他的浏览器需要window.parent方法滚动IFRAME,只有Safari浏览器。所有其他浏览器可以在iframe中使用element.scrollIntoView()。请注意,我已经使用了JavaScript workaround请与Safari浏览器跨协议的IFrame。

我只看到里面IFrame的移动Safari浏览器的另一个问题是,引导情态动词在iframe的顶部显现出视图时向下滚动。虽然,我敢肯定,如果我们能正确地设置滚动条的位置,我们应该能够设置模式立场。

以下是我已经试过;

 1. window.frames['IFrameName'].document.
    getElementById("elmId").scrollIntoView();
  1. Offset trick
  2. Velocity.js

我在这里的最后一招(我认为)是使用的postMessage从我的iframe中,通知父域设置框的滚动位置。

在我看来,这个问题已经存在了一个可怕的很长一段时间。难道还有比这更好的办法?

javascript jquery iframe safari
1个回答
2
投票

这最终是比代码多了很多研究。发生了什么事情是 - 我有这样的调整基于内容的IFrame的代码。

在所有其他的浏览器能正常工作,并消除了滚动条。原来,Safari浏览器automatically sizes the Iframe留下它自己的滚动。在我的应用程序有零个静态页面。这让我不能够使用的链接描述的scrolling=no修复的问题。

正是发现了事情的原委后,我采取了不同的方法来固定elm.scrollIntoView()。该代码是更多的评论则什么,但重要的部分是;

  1. 当检测到与RequiresIframeScrollFix应用的iFrame修复
  2. 使用elm.getBoundingClientRect().top从iframe内,让我们的滚动位置。
  3. 沟通父与window.parent.postMessage滚动
  4. window.addEventListener('message',...)父收到消息

这里是什么样子。

网站的iFrame

iFrame的网站目前滚动它的元素融入到视图这样elm.scrollIntoView();我们已经改变了以下内容。

if (RequiresIframeScrollFix())
     window.parent.postMessage(elm.getBoundingClientRect().top, "*"); // Tell IFrame parent to do the scrolling. If this is not a test environment, replace "*" with the parent domain.
 else
     elm.scrollIntoView(); // If not scroll into view as usual.

可选:修复了使用elm.getBoundingClientRect().top IOS的​​IFrame引导模式定位。

$('#modalId').css('top', elm.getBoundingClientRect().top); // This fixes modal not in view on Safari Iframes.

RequiresIframeScrollFix()主要是由一些良好的文档代码周围铺设SO来确定,如果我们在对iPad或IPhone的iframe。

// Used to help identify problematic userAgents.
var debugNavigator = false;

// Detects an issue on mobile where the Parent is an iframe which cannot have it's scroll bars removed.
// Presumably not a bug as safari will autosize it's iframes: https://salomvary.com/iframe-resize-ios-safari.html
// Can use "scrolling=no" fix instead if the parent knows the initial size of your iframe.
function RequiresIframeScrollFix() {
    try {
        // Debug navigator Agent
        if (debugNavigator)
            alert(navigator.userAgent);

        // We know this issue happens inside an IFrame on;
        // Safari iPhone
        // Safari iPad
        // Safari Desktop Works fine.

        // Check for safari
        var is_safari = navigator.userAgent.indexOf("Safari") > -1;
        // Chrome has Safari in the user agent so we need to filter (https://stackoverflow.com/a/7768006/1502448)
        var is_chrome = navigator.userAgent.indexOf('Chrome') > -1;
        if ((is_chrome) && (is_safari)) { is_safari = false; }

        // If we need to narrow this down even further we can use a more robust browser detection (https://stackoverflow.com/questions/5916900)
        // Problematic browsers can be adjusted here.
        if (is_safari && inIframe() && (
                navigator.userAgent.match(/iPad/i) ||
                navigator.userAgent.match(/iPhone/i)
                ))
            return true;
        else
            return false;

    } catch (e) {
        alert(e.message);
    }
}

// (https://stackoverflow.com/questions/326069/)
function inIframe() {
    try {
        return window.self !== window.top;
    } catch (e) {
        return true;
    }
}

父站点

我们的父网站认为是自动移动Safari浏览器大小的iframe中。因此父网站现在有它自己的滚动条,而不是iframe中。我们建立我们的听众了父站点内,当它从IFrame的网站收到一条消息滚动本身。

// Safari Mobile Iframe Cross Domain Scroll Fix.
window.onload = function () {
     // Calback function to process our postMessages.
     function receiveMessage(e) {
          try {
               // Set the scroll position from our postMessage data.
               // Non-Test pages should uncomment the line below.
               //if (e.origin.includes("your-iframe-domain.com"))
               window.scrollTo(0, e.data);
           }
           catch (err) {
           }
      }

      // Setup and event to receives messages form our iframe (or window)
      window.addEventListener('message', receiveMessage);
}

希望这可以帮助其他人解剖上Safari移动的Iframe问题。另外,让我知道,如果我忽略了一个更好的解决方案。

© www.soinside.com 2019 - 2024. All rights reserved.