首先,我知道有很多关于这种现象的问题,但到目前为止给出的解决方法都不会对我在这里的情况有所帮助。
环境: 我的代码位于我无法控制的页面内的外部iFrame中。它的大小适合我的所有内容,因此我的iFrame中不会发生滚动。相反,外部页面可以向上和向下滚动以查看其内容。
问题: 我有一个内部iFrame,持有我无法控制的第三方广告。如果内部iFrame运行以下任何Javascript命令,则外部页面会向下滚动所有内容以使内部iFrame进入视图:
window.location.href或document.location.hash到其中的锚点。
内部元素的scrollIntoView
Here is a demo a colleague put together(等待5秒钟开始)
无法解决的解决方案
答案 0 :(得分:3)
也许有其他一些方法可以解决这个问题,但一个非常直接的解决方案是通过将它们定位为fixed
,从网站的自然布局中取出麻烦的iframe。 / p>
然后唯一剩下的挑战可能是强制他们表现得好像他们是自然布局的一部分。但与原始问题相比,这项任务似乎具有平庸的复杂性。
此外,在您的特定情况下,上述方法开箱即用。由于外部iframe不可滚动且其高度与其内容高度匹配:您只需为每个iframe插入一个与其对应大小匹配的占位符...
答案 1 :(得分:1)
如果您可以删除IE10及以下支持且iframes
是同一个域,则可以使用解决方案编号2(重写方法)和mutation
事件的组合。
您需要首先遍历DOM中已有的所有iFrames
并删除不需要的功能,并且还可能清除不需要的间隔。在每个document
上添加一个mutation
observer
,如果它们是added nodes
,则会在iFrames
上运行相同的脚本。所以你在开始时有一个遍历所有iframe的递归函数,以及一个删除方法,清除间隔和在每个iFrame
上添加观察者的函数。一旦添加了iFrame
,你就会在它上面运行相同的东西。这样的事情:
递归函数:
var to_cancel = ["scrollIntoView","blur","focus"];
window.onload = function(){iterate_window_object(window)};
function iterate_window_object(cur_win){
remove_methods(cur_win);
for(var i=0;i<cur_win.frames.length;i++){
remove_methods(cur_win.frames[i])
if(cur_win.frames[i].length>0){
iterate_window_object(cur_win.frames[i])
}
}
}
清洁功能:
function remove_methods(cur_win){
for(var j=0;j<to_cancel.length;j++){
cur_win.Element.prototype[to_cancel[j]] = {}
}
for (var k = 0; k < 999;k++){
cur_win.clearInterval(k);
}
cur_win.setInterval = {};
cur_win.observer = new MutationObserver(function(mutations) {
mutations.forEach(function(mutation) {
for(var k=0;k<mutation.addedNodes.length;k++){
var added_node = mutation.addedNodes[k]
if(added_node.tagName == "IFRAME"){
remove_methods(added_node.contentWindow);
added_node.contentWindow.onload = function(){iterate_window_object(added_node.contentWindow)};
}
};
});
});
cur_win.config = { childList: true };
cur_win.observer.observe(cur_win.document.getElementsByTagName('body')[0], cur_win.config);
}
可能有一种方法可以让它看起来更好,最难的部分是能够在调用之前修改方法。而且这里有点矫枉过正,因为它会遍历新的iFrames
,这样如果添加了iframe并添加了iFrames
,那么它们也会被带到。{可能没有必要。
所以它可能是一个解决方案,但IE10及以下版本不支持mutation
个事件。