我有一组<span>
元素,它们是在JavaScript函数中动态创建的。我想创建的每个<span>
都是可单击的,并调用一个将参数作为单击对象的函数。
我的问题是,当我传递对象时,我得到undefined
的错误objAddQuestion
。如何将对象传递给函数?
for (var j = 0; j < lstQuestions.length; j++) {
var objAddQuestion = new Object();
objAddQuestion = lstQuestions[j];
html += ' <span onclick="addQuestion(objAddQuestion)" class="badge addQ">' +
' Add</span>';
}
和功能:
function addQuestion(obj) {
//I got error when click
}
lstQuestions
是对象列表。
答案 0 :(得分:4)
要实现此目的,您可以将对象存储在您创建的每个data
上的jQuery的span
缓存中。然后,您可以使用不引人注目的委托事件处理程序来在单击元素时再次将它们读回。试试这个:
var lstQuestions = [
{ label: 'foo' },
{ label: 'bar' },
{ label: 'fizz' },
{ label: 'buzz' }
];
var spans = lstQuestions.map(function(o) {
return $('<span />', {
'class': 'badge',
'text': o.label
}).data('question', o);
})
$('#questions').on('click', '.badge', function() {
var obj = $(this).data('question');
console.log(obj);
}).append(spans);
span {
padding: 5px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div id="questions"></div>
另一种选择是将数组相关对象的索引存储在data属性中,然后在单击元素时使用该索引从数组中检索项目。两者都有优点,这取决于您的用例,哪个更合适。
答案 1 :(得分:4)
您已经说过lstQuestions
是对象的列表。这意味着您可能不想将问题嵌入onclick
属性处理程序中。
相反,我建议使用现代事件处理,而不要使用onclick
属性。例如,我可能会通过在span
上包含一个问题标识符,然后使用事件委托来处理事件来实现此目的。
注意:您已经标记了问题jquery,但是您的问题中没有jQuery,因此在第一个解决方案中我没有使用它。但是,您当然可以,并且代表团会更简单。参见下面的水平线。
var lstQuestions = [
{
id: 1,
text: "Question 1",
details: "Details for question 1"
},
{
id: 2,
text: "Question 2",
details: "Details for question 2"
},
{
id: 3,
text: "Question 3",
details: "Details for question 3"
}
];
var html = "";
for (var j = 0; j < lstQuestions.length; j++)
{
// Include the question ID (or if the list never changes, just use `j`) as a data-* attribute
var question = lstQuestions[j];
html += ' <span data-question="' + lstQuestions[j].id + '" class="badge addQ">' +
question.text +
' Add</span>';
}
document.getElementById("questions").innerHTML = html;
// Handle clicks on the container
document.getElementById("questions").addEventListener("click", function(e) {
// Did the click pass through a span.addQ?
var span = e.target.closest("span.addQ");
if (span && this.contains(span)) {
// Yes, get its ID
var id = +span.getAttribute("data-question");
// Find the question
var question = lstQuestions.find(function(q) { return q.id === id; });
if (question) {
console.log("Question details: " + question.details);
}
}
});
<div id="questions"></div>
使用jQuery,您可以使用jQuery的元素数据缓存来使用Rory's approach。但是,以下是使用jQuery而不是直接使用DOM的情况:
var lstQuestions = [
{
id: 1,
text: "Question 1",
details: "Details for question 1"
},
{
id: 2,
text: "Question 2",
details: "Details for question 2"
},
{
id: 3,
text: "Question 3",
details: "Details for question 3"
}
];
var html = "";
for (var j = 0; j < lstQuestions.length; j++)
{
// Include the question ID (or if the list never changes, just use `j`) as a data-* attribute
var question = lstQuestions[j];
html += ' <span data-question="' + lstQuestions[j].id + '" class="badge addQ">' +
question.text +
' Add</span>';
}
$("#questions")
.html(html)
.on("click", "span.addQ", function() {
// Yes, get its ID
var id = +this.getAttribute("data-question");
// Find the question
var question = lstQuestions.find(function(q) { return q.id === id; });
if (question) {
console.log("Question details: " + question.details);
}
});
<div id="questions"></div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
答案 2 :(得分:3)
您可能想一一生成span
元素,然后将其附加到您的容器中
var container = document.getElementById( 'container' );
var lstQuestions = [
'Question A'
, 'Question B'
, 'Question C'
];
for (var j = 0; j < lstQuestions.length; j++)
{
var objAddQuestion = lstQuestions[j];
var span = document.createElement( 'span' );
span.onclick = generateClickMethod( objAddQuestion );
span.classList.add( 'badge', 'addQ' );
span.innerText = ' Add ';
container.appendChild( span );
}
function generateClickMethod( obj ){
return function(){
addQuestion( obj );
};
}
function addQuestion( obj ){
alert( obj );
}
<div id="container"></div>
答案 3 :(得分:0)
如果对象是全局对象,请尝试:
function addQuestion(obj) {
window[obj];
}
对于本地对象,请尝试例如:
function addQuestion(obj) {
lstQuestions[obj];
}
和:
for (var j = 0; j < lstQuestions.length; j++) {
var objAddQuestion = new Object();
objAddQuestion = lstQuestions[j];
html += ' <span onclick="addQuestion('+j+')" class="badge addQ">' +
' Add</span>';
}