1

我正在使用以下功能form.html导入:index.html

function importHTML() {
    let link = document.createElement('link');
    link.rel = 'import';
    link.href = 'form.html';
    link.onload = (e) => {
        console.log('Successfully loaded import: ' + e.target.href);
        importContent();
    }
    link.onerror = (e) => {
        console.log('Error loading import: ' + e.target.href);
    }
    document.head.appendChild(link);

    let importContent = () => {
        let importContent = document.querySelector('link[rel="import"]').import;
        if (importContent != null) {
            let el = importContent.querySelector('#formContainer');
            let container = document.body.querySelector('main');
            container.appendChild(el.cloneNode(true));
        }
    }
}

这可以创建一个新link rel="import"标签,并将其附加到headof index.html。当链接完成加载后,来自的内容form.html将附加到主体容器中。

在里面form.html我有一个脚本,它获取一个分页元素的句柄来附加一个事件处理程序:

<section id="formContainer">

    <form>
        ...
    </form>

    <!-- NOTE: pagination controls -->
    <div class="pagination">
        <span id="pageBack"><i>&lt;</i></span>
        <span id="pageForward"><i>&gt;</i></span>
    </div>

    <script>

        let importDoc = document.currentScript.ownerDocument;
        let pageForward = importDoc.querySelector('#pageForward');
        let pageBack = importDoc.querySelector('#pageBack');

        // these elements are present in the console at runtime
        console.log(pageForward, pageBack);

        pageForward.addEventListener('click', (e) => {
            console.log('click event heard on pageBack');
        });

        pageBack.addEventListener('click', (e) => {
            console.log('click event heard on pageBack');
        });

    </script>

</section>

我遇到的问题是,尽管控制台没有显示错误,但事件侦听器没有触发。

我认为这可能与加载顺序有关,并对此进行了一些试验,确保在解析脚本之前加载导入,尽管我不是 100% 知道这是否按预期工作。

我发现通过在importContent()函数之后动态加载它可以将我的代理脚本移动到主文档中,但我更愿意将表单的关联脚本封装在 Import 中。

想法?

4

1 回答 1

1

事件侦听器附加到错误的元素。在您的示例中,它们是<span>在导入文档中的元素上设置的。

但是这些元素是克隆的<span>,被点击的元素是没有设置事件监听器的克隆元素。

要使代码正常工作,您应该查询表单中的元素,<body>而不是查询导入的文档。

form.html 中

<script>
let importDoc = document.currentScript.ownerDocument
let el = importDoc.querySelector( '#formContainer' )
let container = document.body.querySelector( 'main ' )
container.appendChild( el.cloneNode( true ) )

let pageForward = container.querySelector( '#pageForward' )
let pageBack = container.querySelector( '#pageBack')

// these elements are present in the console at runtime
console.log(pageForward, pageBack);
pageForward.addEventListener('click', e => 
    console.log( 'click event heard on pageBack' )
)

pageBack.addEventListener('click', e => 
    console.log( 'click event heard on pageBack' )
)
</script>

注意:导入文档中的 将在文档导入后立即执行。无需等待onload事件并从主文档调用回调。

如果你想推迟脚本的执行,你需要把它放在一个<template>元素中。

于 2018-06-18T11:53:23.290 回答