首页 文章

JS没有在加载.load的页面上执行

提问于
浏览
1

我正在开发一个单页应用程序网站 . 所有导航都发生在div内 . 我使用addEventListener单击查找链接,防止常规href并在div内打开它 .

使用此代码,我可以更改页面,保持页眉和页脚而不刷新整个页面 .

var spa_array = Array.from(document.getElementsByClassName('spa')); // Array with history (for the back button)

spa_array.forEach( function(b) {
    var id = b.id;
    b.addEventListener('click', function(e) {
        event.preventDefault(); // Prevent href
        history.pushState({id:id}, null, id); // Change url on browser
        openPage(id);
    });
});

window.addEventListener('popstate', function(e) {
    openPage(e.state.id);
});

function openPage(url) {
    var encodedUrl = encodeURI(url);
    $("#spa").load(encodedUrl); // open link inside the div
}

这就是问题发生的地方:我使用JS在div上加载一个新页面,例如index_2.html . index_2.html页面上的链接不会触发JS addEventListener,因此它将刷新页面并打开新链接 .

JS未应用于.load中打开的页面 . 有没有办法应用相同的脚本,而不再调用它(这会导致很多麻烦)?

2 回答

  • 3

    使用委托事件处理程序:

    $("#spa").on('click', '.spa', function(e){
        var anchor = this,
            id = anchor.id;
        e.preventDefault();
        history.pushState({id:id}, null, id);
        openPage(id);
    });
    

    您可以在未被删除的DOM节点上注册处理程序(在您的情况下,内容更改的容器,但元素本身保持不变),并将选择器作为第二个参数传入以检查是否发生了单击其中的一个元素与选择器匹配 .

    这是必要的,因为一旦你 .load() 其他内容,它将替换之前元素中的任何内容,包括你在第一次加载时附加的任何事件监听器 . 每次更改内容时都需要调用循环,但这是一个资源消耗较少的解决方案,可以帮助您省去麻烦 .

  • 1

    我将提取添加事件侦听器的逻辑,如下所示:

    function bindLinks() {
      var spa_array = Array.from(document.getElementsByClassName('spa'));
      spa_array.forEach( function(b) {
        var id = b.id;
        b.addEventListener('click', function(e) {
          event.preventDefault(); // Prevent href
          history.pushState({id:id}, null, id); // Change url on browser
          openPage(id);
        });
      });
    }
    

    这样你可以在html加载到你的div之后调用 bindLinks() . 您可以通过将其作为第二个参数传递给 .load() 来实现 .

    function openPage(url) {
      var encodedUrl = encodeURI(url);
      $("#spa").load(encodedUrl, bindLinks);
    }
    

相关问题