【发布时间】:2018-01-26 19:30:43
【问题描述】:
我在<form> 中有一个<textarea> 和一个<button>。提交后,我致电e.preventDefault() 并通过AJAX 提交表单。从那里我返回查询和 PREPEND 在此列表顶部的 <div> 内的信息。
另外,我赋予了每个项目被删除的能力,这在客户端是即时的,但也通过AJAX 提交表单以被完全删除。这有点工作。
我能够:
- 有一个空白屏幕(没有添加任何项目),创建一个并删除它没有问题
- 有空白屏幕,添加两个项目,删除最新的项目没有问题,但删除第二个项目(这是第一个或最旧的项目)会返回错误。它试图删除自己和最新的项目。所以如果我有三个,它会删除自己和最新的,只留下第 2 项。添加的项目越多,情况就越糟糕。
我需要做什么
- 让新的 Prepended 元素继承事件处理程序
- 仅删除选中的项目
代码说明
当用户加载页面时,存储在数据库中的项目会立即被查询并添加到屏幕上。
继续在第一个代码示例中找到const delPostFunc。这是一个立即调用的匿名函数,以确保为最初添加到屏幕的任何项目分配click 事件处理程序。
当用户通过submitPostBtn.addEventListener('click', e => { 提交新项目时,在第一个示例的底部,会进行两次调用。在第二个示例中为const submitPost、AJAX,在第二个示例中为const returnNewestPost、AJAX。这个returnNewestPost调用从数据库返回一些DATA,恰好是最新插入的项目,然后它PREPENDS这个项目到列表的顶部,displayPostWrapper.prepend(newPostDiv);最后调用delPostFunc();函数试图将事件处理程序重新分配给新插入的项目。这是因为innerHTML 删除了任何应该在元素上的事件处理程序,或者这就是我所相信的。
JavaScript
// DELETE POST VARIABLES
let deletePostBtn = document.querySelectorAll('button[name="delete_post"]');
const displayPostWrapper = document.querySelector('.col-8.pt-4');
let displayPostSection = document.querySelectorAll('.col-8.pt-4 .row');
let postID = document.querySelectorAll('#delete-post-id');
// SUBMIT POST VARIABLES
const submitPostBtn = document.querySelector('#submit-post-button');
const submitPostID = document.querySelector('#submit-post-id');
const submitPostContent = document.querySelector('#submit-post-content');
const submitPostName = document.querySelector('#submit-post-name');
// MAKING THE CALL TO DELETE THE POST
const delPostFunc = () => {
console.log(deletePostBtn);
deletePostBtn = document.querySelectorAll('button[name="delete_post"]');
console.log(deletePostBtn);
if (deletePostBtn) {
for (let i = 0; i < deletePostBtn.length; i++) {
deletePostBtn[i].addEventListener('click', e => {
e.preventDefault();
postID = document.querySelectorAll('#delete-post-id');
displayPostSection = document.querySelectorAll('.col-8.pt-4 .row');
console.log(postID[i].value);
// ${postID[i]} comes from `const postID` at the top
deletePostPromise('http://localhost/mouthblog/ajax/delete_post.ajax.php', `id=${postID[i].value}`);
console.log(deletePostBtn);
displayPostSection[i].remove();
console.log(deletePostBtn);
});
}
}
}
// CALL `delPostFunc()` FOR THE INITIAL `deletePostBtn` ON SCREEN
delPostFunc();
// MAKING CALL TO SUBMIT NEW POST
if (submitPostBtn) {
submitPostBtn.addEventListener('click', e => {
e.preventDefault();
// SUBMIT POST
submitPost('http://localhost/mouthblog/ajax/submit_post.ajax.php',
`id=${submitPostID.value}&name=${submitPostName.value}&content=${submitPostContent.value}`)
.then(() => {
// RETURN THAT SAME POST
returnNewestPost('http://localhost/mouthblog/api/newest_post.php')
.then(data => {
// INSERT POST INTO DOM
const newPostDiv = document.createElement('div');
newPostDiv.setAttribute('class', 'row');
newPostDiv.innerHTML = `
<article class="col-10 offset-1">
<h2 class="h2">${data.user_name}</h2>
<small>${data.date_created}</small>
<form action="//localhost/mouthblog/blog.php" method="POST">
<button class="btn btn-danger" name="delete_post" type="submit">DELETE</button>
<input id="delete-post-id" name="post_id" type="hidden" value="${data.id}">
</form>
<hr>
<p class="lead">${data.content}</p>
</article>
`;
console.log(`INSERTING ${data.id}`);
displayPostWrapper.prepend(newPostDiv);
console.log(`INSERT ${data.id} COMPLETE`);
// GIVE THE `newPostDiv`'s `delete button` THE CLICK EVENT HANDLER
console.log(`RUNNING delPostFunc()`);
delPostFunc(); // BOOM!
console.log(`delPostFunc() COMPLETE`);
});
});
});
}
这些只是 AJAX 的承诺
// GET REQUEST TO RETRIEVE EVERY POST
const get = (url) => {
return new Promise((resolve, reject) => {
const xhttp = new XMLHttpRequest();
xhttp.open('GET', url, true);
xhttp.onload = () => {
if (xhttp.status == 200) {
resolve(JSON.parse(xhttp.response));
} else {
reject(xhttp.statusText);
}
};
xhttp.onerror = () => {
reject(xhttp.statusText);
};
xhttp.send();
});
}
// DELETE SPECIFIC POST
const deletePostPromise = (url, postID) => {
return new Promise((resolve, reject) => {
const xhr = new XMLHttpRequest();
xhr.open('POST', url, true);
xhr.onload = () => {
if (xhr.status == 200) {
console.log('if (xhr.status == 200)');
resolve();
} else {
reject(xhr.statusText);
}
};
xhr.onerror = () => {
reject(xhr.statusText);
};
xhr.setRequestHeader('Content-type', 'application/x-www-form-urlencoded');
xhr.send(postID);
});
}
// SUBMIT A NEW POST
const submitPost = (url, user_id, user_name, content) => {
return new Promise((resolve, reject) => {
const xhr = new XMLHttpRequest();
xhr.open('POST', url, true);
xhr.onload = () => {
if (xhr.status == 200) {
console.log('resolving');
resolve();
} else {
reject(xhr.statusText);
}
};
xhr.onerror = () => {
reject(xhr.statusText);
};
xhr.setRequestHeader('Content-type', 'application/x-www-form-urlencoded');
xhr.send(user_id, user_name, content);
});
};
// RETURN THE NEWEST BLOG POST
const returnNewestPost = (url) => {
return new Promise((resolve, reject) => {
const xhr = new XMLHttpRequest();
xhr.open('GET', url, true);
xhr.onload = () => {
if (xhr.status == 200) {
console.log('resolving');
resolve(JSON.parse(xhr.response));
} else {
reject(xhr.statusText);
}
};
xhr.onerror = () => {
reject(xhr.statusText);
};
xhr.send();
});
}
【问题讨论】:
标签: javascript arrays ajax event-handling dom-events