事件侦听器不从HTML导入中的JS脚本触发

时间:2018-06-15 00:27:28

标签: javascript-events html-imports

我使用以下函数将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"代码,并将其附加到head的{​​{1}}。链接完成加载后,index.html中的内容将附加到主体容器中。

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

form.html

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

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

我发现通过在<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> 函数之后动态加载我的代理脚本可以将其移动到主文档中,但我更喜欢保持表单的关联脚本已封装在导入。

思想?

由于

1 个答案:

答案 0 :(得分: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>元素中。