我有一個 AJAX 腳本,它向資料庫添加一個條目,然后更新頁面上顯示的表以包含新行。
用于將行添加到表中的確切代碼(一旦資料庫內容已成功完成并為下面要使用的變數回傳資料)是:
var tableis = document.getElementById("fields-table-append");
var last=(-1);
var Tr = tableis.insertRow(last);
var Td1 = Tr.insertCell(0);
Td1.innerHTML=newrecordname2;
Td1.className = 'cellStyle fields-table-row';
Tr.appendChild(Td1);
var Td2 = Tr.insertCell(1);
Td2.innerHTML="<span class='field-type-style-email'>" newcontenttype2 "</span>";
Td2.className = 'cellStyle fields-table-row';
Tr.appendChild(Td2);
var Td3 = Tr.insertCell(2);
Td3.innerHTML="<span class='field-type-required-no'>" newisrequired2 "</span>";
Td3.className = 'cellStyle fields-table-row';
Tr.appendChild(Td3);
var Td4 = Tr.insertCell(3);
Td4.innerHTML="<a onclick='javascript:deleteRow(" newrowid2 ")';><img class='fields-table-icon' alt='Delete' src='img/zef-delete.png' onm ouseover='' style='cursor: pointer;' /></a>";
Td4.className = 'cellStyle fields-table-row fields-table-column-4';
Tr.appendChild(Td4);
如您所見,每一行的末尾都有一個洗掉圖示,它成功地洗掉了該行,再次使用后臺 AJAX 查詢資料庫內容,然后使用以下代碼在 UI 中洗掉相應的行:
Javascript:
function deleteRow(field_id)
{
if (confirm("Are you sure you want to delete that? It can't be undone."))
{
$.ajax({
data:{todelete : field_id},
type:'POST',
url: 'background-delete.php',
success: function (output) {
var row = document.getElementById(field_id);
row.parentNode.removeChild(row);
}
}
}
這對于首次加載頁面時存在的內容非常有效,但不適用于在該頁面加載期間動態添加的任何額外行。要使洗掉對這些行起作用,我必須首先重繪 頁面,以便正確地從資料庫中提取新行,而不是動態顯示。
我認為這是因為動態行并不真正存在于頁面 HTML 中(例如,它們不顯示在視圖源中)所以沒有正確識別/注冊?
有沒有辦法讓這些動態行的行為與頁面加載時創建的行相同,從而允許我顯示一個有效的洗掉按鈕而無需重繪 ?
根據要求編輯更多資訊:
在頁面加載時,我只是通過回圈遍歷 MySQL 結果并像這樣輸出來創建表:
<?php
$sqlresultloop = "SELECT * FROM contacts_fields WHERE owner_id = '$user_id'";
$resultloop = $mysqli->query($sqlresultloop);
if(mysqli_num_rows($resultloop) > 0) // checking if there is any row in the resultset
{
while($row = mysqli_fetch_assoc($resultloop)) // Loop thru rows
{
?>
<tr class="field-type-table-border" id=<?php echo($row['unique_id']); ?>>
<td class="fields-table-row"><?php echo($row['field_label']); ?></td>
<td class="fields-table-row"><span class="field-type-style-email"><?php echo($row['date_type']); ?></span></td>
<td class="fields-table-row"><?php if(($row['is_required']) == 0) { ?><span class="field-type-required-no"><?php print("Not required"); } else { ?><span class="field-type-required-yes"><?php print("Required"); }; ?></span></td>
<td class="fields-table-row fields-table-column-4"><a onclick="javascript:deleteRow(<?php print(($row['unique_id'])); ?>)";><img class="fields-table-icon" alt="Delete" id="fields-table-icon" src="img/zef-delete.png" onmouseover="" style="cursor: pointer;" /></a></td>
</tr>
然后我在頁面上有一個按鈕,它觸發一個模式來添加一個新條目。我處理它并執行 Ajax 請求以將資料添加到資料庫中。我取回 JSON,并在“成功”代碼中處理它,如下所示:
$('form').on('submit', function (e) {
var $theform = $(this);
var theformid = $theform.attr('id');
e.preventDefault(); //stops page refresh and weird URL shenanigans
if(theformid === 'ex1')
{
document.getElementById("myLoader").style.display = "block";
$.ajax({
type: 'post',
url: 'background-contact-fields.php',
data: $('form').serialize(),
success: function (output) {
//do stuff here when successful
let str = output;
str = str.substring(1);
str = str.slice(0, -1);
const myObj = JSON.parse(str);
newrecordname2 = myObj["fieldlabel"];
newcontenttype2 = myObj["datatype"];
newisrequired2 = myObj["isrequired"];
newrowid2 = myObj["newrowid"];
一切正常,我得到了我期望的資訊。然后,我使用我在這個問題中顯示的第一個代碼塊,使用上面設定的值將其附加到現有表中。它緊隨其后newrowid2 = myObj["newrowid"];。而已。
一切都按我的意愿作業,除了使洗掉按鈕在新行上作業而無需重繪 頁面。這不是世界末日,我不能在頁面重繪 之前顯示它。但如果它有效,那就太好了。
uj5u.com熱心網友回復:
事件委托的基本原理是 DOM 事件“冒泡”DOM。您可以向父元素添加一個偵聽器,而不是為每個元素添加偵聽器,以“捕獲”或偵聽來自其子元素的事件。例如:不是在您添加的每一行上都有偵聽器,而是在表主體中添加一個偵聽器,以便在其子元素事件被觸發時偵聽它們,然后呼叫一個函式。
這是一個相當人為的示例,可以幫助您了解它的作業原理。該示例使用了許多相對較新的 JS 技術,但不必太擔心——這確實是我將要經歷的事件委托程序,我將在答案底部添加指向所有內容的檔案鏈接。一切都可以換成你更習慣的代碼。
// We have a table in our markup already so we need to
// select the `tbody` element, and then assign one listener
// to it. The listener will catch events from its children
// (here: the buttons in the rows), and then call the
// `handleClick` function
const tbody = document.querySelector('tbody');
tbody.addEventListener('click', handleClick);
// Set up some data - this would be your data from your
// endpoint...
const data = [
{ id: 1, name: 'Rita', age: 18, location: 'Bradford' },
{ id: 2, name: 'Sue', age: 19, location: 'Bradford' },
{ id: 3, name: 'Bob', age: 35, location: 'Bradford' }
];
// ...but in this example we're using a "mock" API
// request to deliver a stringified version of that
// data to the app - when the function is called it waits
// for two seconds to mimic the latency of the request
function mockApi() {
return new Promise(res => {
setTimeout(() => {
const json = JSON.stringify(data);
res(json);
}, 2000);
});
}
// A function that creates some row HTML from
// the data (an array). It `map`s over the data
// and returns a string of row information (using a
// template string to add in the object values)
// The last cell includes the delete
// button. Because `map` itself returns a (transformed)
// array we need to join it up into a string at the end.
function createRows(data) {
return data.map(obj => {
return `
<tr>
<td>${obj.name}</td>
<td>${obj.age}</td>
<td>${obj.location}</td>
<td>
<img
data-id="${obj.id}"
src="https://dummyimage.com/100x25/bfa6bf/000000&text=Delete" />
</td>
</tr>
`;
}).join('');
}
// The function that is called when the `tbody`
// listener "catches" an event from one of its children.
// First it checks to see if the element that fired the event
// is a button. If it is a button we find the closest parent row
// to that button, and remove it from the DOM
function handleClick(e) {
if (e.target.matches('img.delete')) {
e.target.closest('tr').remove();
console.log(`Deleting: ${e.target.dataset.id}`);
}
}
// The main function that calls the mock API
// parses the JSON into an object, and then calls
// `createRows` with that data which returns the HTML.
// We then attach all the HTML to the `tbody` element.
async function main() {
const response = await mockApi();
const data = await JSON.parse(response);
const html = createRows(data);
tbody.insertAdjacentHTML('beforeend', html);
}
main();
table { border-collapse: collapse; width: 100%; }
thead { background-color: #efefef; text-transform: uppercase; }
td { padding: 0.25em; border: 1px solid #efefef; }
img.delete:hover { cursor: pointer; }
<table>
<thead>
<tr>
<td>Name</td>
<td>Age</td>
<td>Location</td>
<td></td>
</tr>
</thead>
<tbody>
</tbody>
</table>
附加檔案
querySelectoraddEventListener如何使用承諾
setTimeoutmap模板/字串文字
joininsertAdjacentHTMLasync/await
轉載請註明出處,本文鏈接:https://www.uj5u.com/caozuo/528312.html
上一篇:修改遵循簡單模式的屬性和文本
