我已经跑进是困扰各地谷歌,但没有提供解决方案的正常工作的问题。我认为大多数这些解决方案中没有考虑跨域。
我有一个网站,我想指示用户嵌入到他们与一个(整版)IFrame的网站。问题是,只有Safari的某些版本。在iframe中的元素不能滚动自己进入视野。
我注意到,如果我做了同样的测试域该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();
我在这里的最后一招(我认为)是使用的postMessage从我的iframe中,通知父域设置框的滚动位置。
在我看来,这个问题已经存在了一个可怕的很长一段时间。难道还有比这更好的办法?
这最终是比代码多了很多研究。发生了什么事情是 - 我有这样的调整基于内容的IFrame的代码。
在所有其他的浏览器能正常工作,并消除了滚动条。原来,Safari浏览器automatically sizes the Iframe留下它自己的滚动。在我的应用程序有零个静态页面。这让我不能够使用的链接描述的scrolling=no
修复的问题。
正是发现了事情的原委后,我采取了不同的方法来固定elm.scrollIntoView()
。该代码是更多的评论则什么,但重要的部分是;
RequiresIframeScrollFix
应用的iFrame修复elm.getBoundingClientRect().top
从iframe内,让我们的滚动位置。window.parent.postMessage
滚动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问题。另外,让我知道,如果我忽略了一个更好的解决方案。