使用JQuery和JavaScript将事件绑定到单页应用程序的DOM

使用JQuery和JavaScript将事件绑定到单页应用程序的DOM,javascript,jquery,events,single-page-application,Javascript,Jquery,Events,Single Page Application,我正在用JavaScript和JQuery设计一个新的单页应用程序。然而,我最担心的是通过选择器将事件(如单击等)绑定到DOM元素,一旦加载了新的“视图”(通过AJAX调用创建了新页面),这些元素就会被删除 通过使用新内容替换主视图DIV,实现SPA而不造成内存泄漏和页面速度减慢的最干净的方法是什么?我知道这是一个老问题,但我认为它值得回答,所以现在开始: 有两种方法可以解决这个问题(这是一个有点宽泛的问题,所以这里有一个有点宽泛的答案): 第一种方式: // This is in plain

我正在用JavaScript和JQuery设计一个新的单页应用程序。然而,我最担心的是通过选择器将事件(如单击等)绑定到DOM元素,一旦加载了新的“视图”(通过AJAX调用创建了新页面),这些元素就会被删除


通过使用新内容替换主视图DIV,实现SPA而不造成内存泄漏和页面速度减慢的最干净的方法是什么?

我知道这是一个老问题,但我认为它值得回答,所以现在开始:

有两种方法可以解决这个问题(这是一个有点宽泛的问题,所以这里有一个有点宽泛的答案):

第一种方式:

// This is in plain JS, but the jQuery equivalent is:
// document.on('click', '#my-id, function(e) { /* Function stuff */ });
document.addEventListener('click' function(e) {
  if (e.target.id === 'my-id') {
    // Function stuff
  }
});
这样做的好处是,您永远不必删除事件侦听器,因为始终会有一个文档。你甚至可以通过使用类来建立一个“阶段”系统(我称之为阶段,我不知道是否有更好的词来形容它们),也就是说,你的导航链接都有class
nav项,在你的事件侦听器中,你可以有以下代码:

// jQuery equivalent of if statement is: if ($(this).is('nav-item')) {}
if (e.target.className.match(/nav-item/)) { // You could also use .include(), etc.
  switch(e.target.id) {
    case 'item1':
      loadPageOneFunction(); // Or whatever
      break;
    case 'item2':
      loadPageTwoFunction(); // Or whatever
      break;
  }
}

第二种方式

// Note how I named the function
document.getElementById('my-id').addEventListener('click', function clickFunction(e) {
  myAjaxFunction(e.target); // Or whatever
});
// Later...
if (pageToLoad === 'page2') {
  // You are required to name the function you are removing.
  document.getElementById('my-id').removeEventListener('click', clickFunction);
  document.getElementById('my-page2-id').addEventListener('click', clickFunction);
}
老实说,我更喜欢第一种方法,因为它的代码更少,我可以使用无名函数(匿名函数)-我知道,这很重要,但仍然


还有第三种方法,就是不用担心删除事件侦听器。你可以读一下


同样,这是一个非常宽泛的回答,因为这是一个宽泛的问题。

我知道这是一个老问题,但我认为它值得回答,所以给你:

有两种方法可以解决这个问题(这是一个有点宽泛的问题,所以这里有一个有点宽泛的答案):

第一种方式:

// This is in plain JS, but the jQuery equivalent is:
// document.on('click', '#my-id, function(e) { /* Function stuff */ });
document.addEventListener('click' function(e) {
  if (e.target.id === 'my-id') {
    // Function stuff
  }
});
这样做的好处是,您永远不必删除事件侦听器,因为始终会有一个文档。你甚至可以通过使用类来建立一个“阶段”系统(我称之为阶段,我不知道是否有更好的词来形容它们),也就是说,你的导航链接都有class
nav项,在你的事件侦听器中,你可以有以下代码:

// jQuery equivalent of if statement is: if ($(this).is('nav-item')) {}
if (e.target.className.match(/nav-item/)) { // You could also use .include(), etc.
  switch(e.target.id) {
    case 'item1':
      loadPageOneFunction(); // Or whatever
      break;
    case 'item2':
      loadPageTwoFunction(); // Or whatever
      break;
  }
}

第二种方式

// Note how I named the function
document.getElementById('my-id').addEventListener('click', function clickFunction(e) {
  myAjaxFunction(e.target); // Or whatever
});
// Later...
if (pageToLoad === 'page2') {
  // You are required to name the function you are removing.
  document.getElementById('my-id').removeEventListener('click', clickFunction);
  document.getElementById('my-page2-id').addEventListener('click', clickFunction);
}
老实说,我更喜欢第一种方法,因为它的代码更少,我可以使用无名函数(匿名函数)-我知道,这很重要,但仍然


还有第三种方法,就是不用担心删除事件侦听器。你可以读一下


同样,这是一个非常宽泛的答案,因为这是一个宽泛的问题。

只要您一直使用jQuery,就不会有问题。也就是说,如果要删除并替换某个节,请确保使用jQuery方法(如
.remove()
.replaceWith()
),因为它们会清理jQuery存储的内容。当人们决定用jQuery添加事件处理程序,然后用
.innerHTML=“whatever”删除元素时,就会遇到麻烦
或使用类似于
parentElement.removeChild(el)的东西因为它没有给jQuery一个清理的机会,所以您可能会想使用委派事件:同时同意:使用“on”和“remove”。但不知怎的,我觉得还有更多。我的意思是人们为SPA创建整个框架!或者这都是小题大做?只要您一直使用jQuery,就不会有问题。也就是说,如果要删除并替换某个节,请确保使用jQuery方法(如
.remove()
.replaceWith()
),因为它们会清理jQuery存储的内容。当人们决定用jQuery添加事件处理程序,然后用
.innerHTML=“whatever”删除元素时,就会遇到麻烦
或使用类似于
parentElement.removeChild(el)的东西因为它没有给jQuery一个清理的机会,所以您可能会想使用委派事件:同时同意:使用“on”和“remove”。但不知怎的,我觉得还有更多。我的意思是人们为SPA创建整个框架!还是一切都是大惊小怪?