在谷歌浏览器(37.0.2062.122,OSX / Windows)上,带有包含片段的URL的iframe会导致父元素向上滚动。
这只发生在Chrome中(在Safari和Firefox中测试过)。
这是一个显示问题的小提琴:http://jsfiddle.net/wmz5cu1y/1/(您必须点击Run
两次。)
如您所见,包含iframe的整个<body>
已向上滚动。标题是隐藏的,因为它现在位于窗口上方,并且页面底部有一个意外的空白区域。
如何避免这种情况?
Bounty提供了非js变通方法或更简单的html文档来重现这个问题。
答案 0 :(得分:16)
正如其他答案已经提到的,这里的问题是JSFiddle特有的。我可以通过在此问题的StackOverflow片段中简单地包含相同的代码来轻松地向您展示:
iframe {
position: absolute;
top: 0;
right: 0;
bottom: 0;
left: 0;
width: 100%;
height: 100%;
}
&#13;
<iframe src="https://news02ycombinator02com2.mentionusercontent.net/item?id=8357207#up_8360397" width="100%" height="100%"></iframe>
&#13;
在JSFiddle上传递给iframe
的每个片段URL都会出现此问题。因此,我们可以复制此问题,只需创建一个单独的JSFiddle演示并链接到我们iframe
中的演示。
我在这里创建了这个新的JSFiddle演示:http://fiddle.jshell.net/JamesD/k5vk2u9h/1/show/light/#test。
如您所见,此处的片段为#test
。现在可以使用以下标记在新的JSFiddle演示中复制此问题:
<iframe src="http://fiddle.jshell.net/JamesD/k5vk2u9h/1/show/light/#test"></iframe>
height
和width
属性无关紧要,因为如果没有它们,问题仍会出现。
这里的另一个答案表明修复是修改JSFiddle自己的HTML,以便正确地重新呈现页面。这不是一个很好的解决方案,因为在现实世界的情况下(即将某人链接到JSFiddle演示时),他们可能没有专业知识来实现这一点。
我们可以使用JavaScript解决这个问题。由于我创建的新HTML文档位于同一个域(http://jshell.net),因此我们可以在iframe
内执行JavaScript。手动设置location.hash
属性也会触发此问题,因此我们可以做的是将iframe
直接滚动到我们希望关注的元素。
首先,从src
的{{1}}属性中删除网址中的片段:
iframe
如上所述,我使用的片段是<iframe src="http://fiddle.jshell.net/JamesD/k5vk2u9h/1/show/light/"></iframe>
是&#34; test&#34;的元素。这意味着获取元素的最简单方法是通过id
属性选择它:
id
此处,var frame = frames[0],
elem = frame.document.querySelector('#test'),
是我们自己的文档中对frame
的引用,iframe
是我们的elem
元素。我们可以使用#test
:
getBoundingClientRect()
这将为我们提供如下的ClientRect对象:
有了这个,我们现在知道我们的 position = elem.getBoundingClientRect();
元素位于距#test
顶部3034px处。使用此功能,我们现在可以使用iframe
将页面滚动到此位置(在这种情况下window.scrollTo()
的{{1}}保存在我们的window
变量中):< / p>
iframe
请注意,此解决方案仅在frame
指向同一域上托管的网址或在frame.scrollTo(0, position.top);
嵌入的网页上启用了CORS时才有效。
完成所有这些之后,最好的办法是简单地通知JSFiddle的开发人员这是一个错误。我已在此处将其作为GitHub存储库中的问题提出:https://github.com/jsfiddle/jsfiddle-issues/issues/547。
答案 1 :(得分:7)
此处显示两个错误。
运行此窗口时,窗口将滚动,以便窗口中的片段位于页面顶部:
<iframe src="https://news02ycombinator02com2.mentionusercontent.net/item?id=8357207#up_8360397" width="100%" height="100%"></iframe>
&#13;
您可以想象,这会导致某些固定高度网站(例如jsfiddle)出现问题。它也是Chrome独有的(我只在FF上测试,而不是IE),Firefox没有滚动父窗口。有人讨论它不在FF here。
将onload事件添加到调用以下函数的iframe中。并且不要使用原始片段:
<script>
function loadorder() {
document.getElementById("iframename").src= "https://news02ycombinator02com2.mentionusercontent.net/item?id=8357207#up_8360397";
window.scrollTo(0,0);
}
</script>
<iframe width="830" src="https://news02ycombinator02com2.mentionusercontent.net/item?id=8357207" height="500" id="iframename" onLoad="loadorder();"></iframe>
&#13;
正如您在小提琴和上面的片段中看到的那样,父窗口不再滚动,现在FF和Chrome的行为相同。
<强> Source for fix. 强>
好的,所以我做了一些测试:
因此,作为临时解决方法,请使用其中一个或注入此方法 进入jsfiddle&#39; html:
margin-top: 30px; into the header bar like: <div id="header" style="margin-top: 30px;">
虽然每次加载都需要完成,但有点痛苦 jsfiddle(但不是每次你操作小提琴)。
要解决问题,应该在jsfiddle github上报告 页面:https://github.com/jsfiddle/jsfiddle-issues/issues
修改强>
这是一种在Chrome上自动化它的方法:下载stylebot 扩展,并将此样式添加到jsfiddle.com(或具体 小提琴):
#header { margin-top: 30px; }
效果很好。
答案 2 :(得分:3)
问题不是在iframe网址中包含#,如果您尝试使用示例中的下一个网址,则会看到没有滚动: http://www.w3.org/TR/scxml/#scxml
所以,我查看了您正在展示的页面,看看是否有奇怪的东西: https://news02ycombinator02com2.mentionusercontent.net/item?id=8357207#up_8360397
如果你检查JS它有类似下一个:
var e = window,
g = document,
h = "documentElement",
k = "CriticalImages",
l = "scrollTop",
n = "prototype",
p = "body",
q = "getAttribute",
有一个名为“scrollTop”的功能,我认为这是一个很好的调查对象。
如果你再检查一下代码,你会发现JS在某些时候获得了offsetTop和offsetParent:
u = function(a, b) {
var c = b[q]("pagespeed_lazy_position");
if (c) return parseInt(c, 0);
var c = b.offsetTop,
d = b.offsetParent;
d && (c += u(a, d));
c = Math.max(c, 0);
b.setAttribute("pagespeed_lazy_position", c);
return c
},
结论:问题在于您尝试在iframe中显示的页面,而不是网页中的小提琴,Chrome或#。
我希望这有帮助。
在查看wiki示例后,我看到小提琴中有一些js(所以第一个答案是对的)。
要使用js避免这种情况,您只需将其包括在内:
$( window.parent ).scroll(function(event) {
// debugger;
console.log('SCROLL',event);
var scrollTop=$(this).scrollTop();
if(scrollTop>0){
console.log('fix scroll');
$(this).scrollTop(0);
}
});
例:
http://fiddle.jshell.net/xbnt3Lu6/21/
我会尝试检查哪些j导致问题。
答案 3 :(得分:1)
好吧它不仅是Chrome,所有浏览器都会遇到同样的问题,看起来该网站有大量的js脚本,不知道它如何影响你放置iframe的网站,解决它的最简单方法是删除<强大的>#up_8360397 来自链接。 第二种方法是在iframe中禁用javascript。但是你不能自动将其向下滚动到你想要的帖子,你必须手动设置滚动位置。
答案 4 :(得分:0)
找到了重现错误的最小方法:http://jsfiddle.net/4oytgwon/1/embedded/result/(您可以在点击&#34后看到错误发生;加载iframe&#34;)。
它也发生在jsfiddle之外,使用以下代码:
<!doctype html>
<html>
<head>
<style>
body, html {
padding: 0;
border: 0;
margin: 0;
height: 100%;
overflow: hidden;
}
#header {
height: 50px;
background: blue;
}
#content {
position: absolute;
top: 50px;
right: 0;
bottom: 0;
left: 0;
}
#overflow {
position: absolute;
height: 50px;
bottom: -50px;
}
</style>
<script>
function loadIframe() {
var ifr = document.createElement('iframe');
ifr.src = 'https://en.wikipedia.org/wiki/Stack_overflow#See_also';
var content = document.getElementById('content');
while (content.firstChild) {
content.removeChild(content.firstChild);
}
content.appendChild(ifr);
}
window.onload = function () {
document.getElementById('btn').onclick = loadIframe;
};
</script>
</head>
<body>
<div id=header>
<button id=btn>load iframe</button>
</div>
<div id=content>
</div>
<div id=overflow>
overflow
</div>
</body>
</html>