Why Firefox doesn't follow fragment identifiers in iframe?

65 views Asked by At

Go to https://colnect.com/en/forum/app!/help/faq with Firefox, click any link and nothing happen. Do the same in Chrome and you will be moved somewhere. Is it Firefox issue or something else? Code is:

<a href="#f1r2">The times are not correct!</a>

<dl class="faq">
    <dt id="f1r2"><strong>The times are not correct!</strong></dt>
    <dd>It is possible the time displayed is from a ...</dd>
</dl>

UPD: simplified sample, there are 2 pages, page with iframe:

<!-- firefox-in-iframe.html -->
<!DOCTYPE html>
<html lang="en">
<head>
    <title>Firefox in iframe</title>
</head>
<body>
    <h1>Test TOC in Firefox</h1>
    <iframe id="demo" src="firefox-in-iframe-w3.html" frameborder="1" style="width:100%; height:100%"></iframe>
</body>
</html>

and page with HMTL content from https://www.w3.org/TR/html401/struct/links.html with JavaScript added to align pages heights:

<script>
  parent.document.getElementById('demo').addEventListener('load', (e) => {
    e.target.style.height = Math.max(document.body.offsetHeight, document.body.scrollHeight) + 'px';
  });
</script>
1

There are 1 answers

0
Yuri On

Here is old enough bug, its discussion and demo page mentioned there. Also one of the possible solutions are mentioned ibid. Сode could be like:

parent.document.getElementById('demo').addEventListener('load', (e) => {
    // Align iframe and page heights. Iframe scrollbar can be hidden with CSS
    e.target.style.height = Math.max(document.body.offsetHeight, document.body.scrollHeight) + 'px';

    if (!(typeof InstallTrigger !== 'undefined')) return; // Not Firefox, do nothing

    const iFrameOffset = e.target.offsetTop;
    document.querySelectorAll('a[href^="#"]').forEach(el => {
        const targetId = el.href.substring(el.href.indexOf('#') + 1);
        el.addEventListener('click', () => {
            const target = document.getElementById(targetId) || document.querySelector(`[name='${targetId}']`);
            window.parent.scrollTo(0, iFrameOffset + target.offsetTop)
        })
    })
});