英文:
how to add dynamic JavaScript to dynamically generated Html elements?
问题
以下是代码的翻译部分:
function getWidgets(){
var listUrl = base_url + widgetsPath + url_auth;
console.log("发送GET请求至:" + listUrl);
function getSuccess(obj){
var dataWidget = obj.data;
for (let i=0; i<dataWidget.length; i++){
var id = dataWidget[i].id;
var description = dataWidget[i].description;
var price = dataWidget[i].pence_price;
var url = dataWidget[i].url;
var index = i;
console.log("索引: ", i);
console.log(dataWidget[i].id);
console.log(dataWidget[i].description);
console.log(dataWidget[i].pence_price);
console.log(dataWidget[i].url);
console.log(" ");
var template = `<div class="container" class="product" id="productId_${index}">
<form action="" class="product">
<img src="${url}"></img>
<p class="product_Description">${description}</p>
<input type="hidden" class="productId" value="${id}">
<input type="hidden" class="price" value="0.${price}">
<label for="quantity">Quantity:</label>
<input type="number" class="quantity" value="1" min="1">
<button class="submit">Add to cart</button>
</form>
</div>
<script>
document.addEventListener("DOMContentLoaded", () => {
const product${index} = document.querySelector("#productId_${index}");
product${index}.addEventListener("submit", e => {
e.preventDefault();
var formId = "productId_${index}";
productList(formId);
});
});
</script>`;
$("#widgetContainer").append(template);
}
console.log("成功");
console.log(dataWidget);
};
$.ajax(listUrl, {type: "GET", data: {}, success: getSuccess });
};
getWidgets();
英文:
I have an HTML page that gathers data from a database and uses that data to produce dynamic HTML elements. The problem is that these elements have to create a button that submits data without refreshing the page and then call a function productList(formId);
.
This is the current function:
function getWidgets(){
var listUrl = base_url + widgetsPath + url_auth;
console.log("Sending GET to " + listUrl);
function getSuccess(obj){
var dataWidget = obj.data;
for (let i=0; i< dataWidget.length; i++){
var id = dataWidget[i].id;
var description = dataWidget[i].description;
var price = dataWidget[i].pence_price;
var url = dataWidget[i].url;
var index = i;
console.log("index: ",i);
console.log(dataWidget[i].id);
console.log(dataWidget[i].description);
console.log(dataWidget[i].pence_price);
console.log(dataWidget[i].url);
console.log(" ");
var template =`<!-- product -->
<div class="container" class="product" id="productId_${index}">
<form action="" class="product">
<img src="${url}"></img>
<p class="product_Description">${description}</p>
<input type="hidden" class="productId" value=${id}>
<input type="hidden" class="price" value="0.${price}">
<label for="quantity">Quantity:</label>
<input type="number" class="quantity" value="1" min="1">
<button class="submit">Add to cart</button>
</form>
</div>
<script>
document.addEventListener("DOMContentLoaded",() =>{
const product${index} = document.querySelector("#productId_${index}")
product1.addEventListener("submit",e=>{
e.preventDefault();
var formId = "productId_${index}";
productList(formId);
});
});
</script>
<!-- END product -->`
$("#widgetContainer").append(template);
}
console.log("success");
console.log(dataWidget);
};
$.ajax(listUrl, {type: "GET", data: {},success: getSuccess });
};
getWidgets();
答案1
得分: 1
不需要为每个附加到页面的小部件动态添加<script>
块。相反,您可以添加一个单独的submit
事件处理程序,它将能够处理您动态添加的所有<form>
元素的submit
事件。代码将如下所示:
$('#widgetContainer').on('submit', 'form.product', function (e) {
e.preventDefault();
const formId = $(this).parent().attr('id');
productList(formId);
});
上面的代码使用事件委托来处理任何带有类名“product”的<form>
元素的submit
事件。在处理程序中,我们获取了<form>
元素父元素的id
属性。
这里提供了一个示例用于参考。
英文:
You do not need to dynamically add a <script>
block for each widget you append to your page. Instead, you can add a single submit
event handler that will be able to handle the submit
event for all of the <form>
elements you add dynamically. The code would look like the following:
$('#widgetContainer').on('submit', 'form.product', function (e) {
e.preventDefault();
const formId = $(this).parent().attr('id');
productList(formId);
});
The above code is using Event Delegation to handle the submit
event for any <form>
element with a class of "product". In the handler, we get the id
attribute of the <form>
element's parent.
Here is a fiddle for reference.
答案2
得分: 0
在底层,jQuery的append()
方法使用Element.innerHTML
解析HTML字符串。
如在MDN关于innerHTML
的“安全注意事项”部分中提到:
> ... HTML规定使用innerHTML
插入的<script>
标签不应该执行。
所以,不要通过追加<script>
标签来执行代码,而是直接执行它:
var template = /*没有<script>标签的模板*/;
$("#widgetContainer").append(template);
// <script>标签的代码
document.addEventListener("DOMContentLoaded", () => {
const product = document.querySelector("#productId_${index}")
product.addEventListener("submit", e => {
e.preventDefault();
var formId = "productId_${index}";
productList(formId);
});
});
或者更好的做法是,如76484的回答所示,使用事件委托。这样,您就不必添加单独的事件监听器。
英文:
Under the hood, jQuery's append()
parses the HTML-string by using Element.innerHTML
.
As mentioned in MDN's section Security considerations for innerHTML
:
> ... HTML specifies that a <script>
tag inserted with innerHTML
should not execute.
So instead of executing the code by appending a <script>
tag, simply execute it:
var template = /*without script tag*/;
$("#widgetContainer").append(template);
// Script tag's code
document.addEventListener("DOMContentLoaded",() => {
const product = document.querySelector("#productId_${index}")
product.addEventListener("submit", e => {
e.preventDefault();
var formId = "productId_${index}";
productList(formId);
});
});
Or better, use event delegation as 76484's answer shows. That way you wouldn't have to add individual listeners.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论