iframe与srcdoc:相同页面链接会在框架中加载父页面

7
同页链接通过引用同一页上具有id="sec-id"的另一个元素来工作,使用
<a href="#sec-id"></a>

例如,像这样的链接是相对的。但是,如果我在LaTeX.js游乐场的iframe中使用完全相同的语法,它不仅会滚动到目标元素,而且会重新加载整个游乐场页面。 (请注意,我使用iframe.srcdoc = html以编程方式设置iframe的内容)例如:LaTeX.js playground,在第一节的末尾,在右侧的iframe中单击“另请参见第11节中的链接”。可能的原因是什么? 更新:我现在理解了问题的根源:浏览器使用文档的基本URL将所有相对URL变成绝对URL(参见<base>)。问题始于一个iframe,它的内容是用srcdoc设置的:没有指定唯一的基本URL,在这种情况下,父框架/文档的基本URL被使用——在我的情况中是playground(请参见HTML标准)。
因此,问题变成了:是否有办法在基本URL中引用srcdoc iframe?或者是否可能使浏览器不添加基本URL?或者制作一个不改变相对#sec-id URL的基本URL?
3个回答

2

我不确定如何解决这个问题,我认为可能是因为 srcdoc 的原因,由于字符限制,你不能使用带 content-type 的 src,但你可以将其转换为一个 Blob,有点可行,但是样式会丢失。也许你可以以此作为起点,根据你的页面进行调整:

// Get the document content
const doc = document.querySelector('iframe').srcdoc;
// Convert it to blob
const blob = new Blob([doc], {type : 'text/html'});
// Load the blob on the src attr
document.querySelector('iframe').src = URL.createObjectURL(blob);
// Remove srcdoc to allow src
document.querySelector('iframe').removeAttribute('srcdoc');

这可能通过规避“srcdoc”问题而成为一个不错的解决方法。但我首先必须弄清楚如何修复破损的样式... - MiB
是的,这是一个棘手的问题,我会尝试在使用JavaScript加载内容后分配样式,但我不知道是否可行。祝你好运。 - Ander
此解决方案还有一个缺点:只使用绝对路径来修复样式非常容易,但如果我在本地测试时使用游乐场,则这些路径是“file:///…”路径,并且不允许使用Blobs或iframe.src。因此,我将采用另一种解决方法。 - MiB

1
抓取事件并滚动到所需的锚点怎么样?
$("a").click(function(e) {
    $('.iframe').animate({
       scrollTop: $(e.target.attr('href')).offset().top
    }, 2000);
    return false;
});

好主意!不过我认为你的代码不正确,它应该在 iframe 内运行,对吧?那么为什么要使用 $('.iframe') - MiB
另外,还有一个小问题;-) 并不是每个<a>都应该被选择,只有那些以#开头的href才应该被选择 - 但我可以很容易地解决这个问题,重要的是思路。 - MiB
很高兴听到,$('.iframe')是要滚动的元素,所以它被选中了。 - antasp

0
记录一下,似乎我的问题是不可能的,即在使用srcdoc设置其内容的iframe中无法使用相对同页链接。必须使用解决方法,请参见其他答案。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接