cla*_*oda 4 javascript safari iframe jquery
我遇到了一个困扰整个谷歌的问题,但提供的解决方案都没有正常工作。我假设这些解决方案中的大多数都没有考虑跨域。
我有一个网站,我想指导用户将(整页)IFrame 嵌入到他们的网站中。问题仅出现在某些版本的 Safari 上。IFrame 中的元素无法将自身滚动到视图中。
我注意到,如果我进行相同的域测试,IFrame 可以使用window.parent.scrollTo(0,element.top). 这有效,但不能跨域。另一个奇怪的事情是没有其他浏览器需要 window.parent 方法来滚动 IFrame,只有 Safari。所有其他浏览器都可以element.scrollIntoView()在 IFrame 中使用。请注意,我已经使用JavaScript 解决方法来取悦带有跨协议 IFrame 的 Safari。
我只在 IFrame 中的 Safari Mobile 上看到的另一个问题是,当向下滚动时,Bootstrap Modals 出现在 IFrame 的顶部。尽管如此,我确信如果我们可以正确设置滚动位置,我们也应该能够设置模态位置。
这是我尝试过的;
1. window.frames['IFrameName'].document.
getElementById("elmId").scrollIntoView();
Run Code Online (Sandbox Code Playgroud)
我最后的手段(我认为)是在我的 IFrame 中使用 postMessage 来通知父域设置框架的滚动位置。
在我看来,这个问题已经存在了很长时间。还有比这更好的方法吗?
这最终导致了比代码更多的研究。发生了什么 - 我有根据内容调整 IFrame 大小的代码。
在所有其他浏览器中,这可以正常工作并消除滚动条。事实证明,Safari 会自动调整 Iframe 的大小,留下它自己的滚动条。在我的应用程序中,静态页面为零。这给我留下了无法使用scrolling=no链接中描述的修复程序的问题。
在确切地发现发生了什么之后,我采取了不同的方法来修复elm.scrollIntoView(). 代码比其他任何东西都多,但重要的部分是;
RequiresIframeScrollFixelm.getBoundingClientRect().top从iframe内,让我们的滚动位置。window.parent.postMessagewindow.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.
Run Code Online (Sandbox Code Playgroud)
可选:使用elm.getBoundingClientRect().top.
$('#modalId').css('top', elm.getBoundingClientRect().top); // This fixes modal not in view on Safari Iframes.
Run Code Online (Sandbox Code Playgroud)
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 (/sf/answers/543760451/)
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 (/sf/ask/414183031/)
// 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);
}
}
// (/sf/ask/22824861/)
function inIframe() {
try {
return window.self !== window.top;
} catch (e) {
return true;
}
}
Run Code Online (Sandbox Code Playgroud)
父站点
我们的父站点包含由 Safari Mobile 自动调整大小的 IFrame。因此,父站点现在拥有自己的滚动条,而不是 IFrame。我们在父站点内设置我们的侦听器,当它从 IFramed 站点接收到消息时滚动自身。
// 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);
}
Run Code Online (Sandbox Code Playgroud)
希望这有助于其他人剖析移动设备上的 Safari Iframe 问题。另外,如果我忽略了更好的解决方案,请告诉我。
| 归档时间: |
|
| 查看次数: |
3104 次 |
| 最近记录: |