javascript / jquery为每个列表项切换一个元素

时间:2022-05-22 14:31:32

I do a for loop in javascript to get the title and description for each item in my json file.

我在javascript中执行for循环以获取我的json文件中每个项目的标题和描述。

for (var i = 0, len = mydata.texts.length; i < len; i++) {
    list +="<li>"+"<div class='circle'></div>" + 
         "<span onclick='toggleDesc()'>"+ mydata.texts[i]["keyword"] +
         "</span>"+
        +"</li>"+
        "<div id='descr'>"+mydata.texts[i]["description"]+"</div>";    
}


function toggleDesc() {
    var x = document.getElementById('descr');
    if (x.style.display === 'none') {
        x.style.display = 'block';
    } else {
        x.style.display = 'none';
    }
}

The result is like:

结果如下:

1. Title1
   description1
2. title2
   description2
3. Title3
   Description3
...

Currently:
it is only toggling the first list item.

目前:它只切换第一个列表项。

question

How can I fix it to show each list item's description on click?

如何修复它以显示每个列表项的点击描述?

3 个解决方案

#1


2  

Currently: it is only toggling the first list item.

目前:它只切换第一个列表项。

Because you can't use the same id with multiple elements in a page as it must be unique, and if you use it only the first one will be parsed with document.getElementById() so that's why only the first one is toggled.

因为你不能在页面中使用与页面中的多个元素相同的id,因为它必须是唯一的,并且如果你使用它只有第一个将使用document.getElementById()进行解析,这就是为什么只有第一个被切换的原因。

Solution:

Use a class instead of an id so you can attach the event to all the elements having this class.

使用类而不是id,以便可以将事件附加到具有此类的所有元素。

And in your HTML code pass a reference to the clicked span with this to your toggleDescription() function and use it to find the relevant description inside it.

并在您的HTML代码中将对单击的跨度的引用传递给您的toggleDescription()函数,并使用它来查找其中的相关描述。

This is how should be your code:

这是你的代码应该如何:

for (var i = 0, len = mydata.texts.length; i < len; i++) {
    list +="<li>"+"<div class='circle'></div>" + 
         "<span onclick='toggleDesc(this)'>"+ mydata.texts[i]["keyword"] +
         "</span>"+
         "<div class='descr'>"+mydata.texts[i]["description"]+"</div>"; 
        +"</li>"
}


function toggleDesc(item) {
    $(item).next('.descr').toggle();
}

And make sure you place the description div inside the li elemnt, because a list can contain only li as direct children.

并确保将描述div放在li elemnt中,因为列表只能包含li作为直接子项。

edit:

it needs a css specification to hide by default:

它默认需要隐藏css规范:

.descr{
    display:none;
}

#2


3  

Identifiers in HTML must be unique. However you can use CSS class with multiple time which can be targeted by using Class Selector .class.

HTML中的标识符必须是唯一的。但是,您可以使用具有多个时间的CSS类,可以使用类选择器.class来定位。

for (var i = 0, len = mydata.texts.length; i < len; i++) {
    list +="<li>"+"<div class='circle'></div>" + 
         "<span class='toggleDesc'>"+ mydata.texts[i]["keyword"] +
         "</span>"+
         "<div class='descr'>"+mydata.texts[i]["description"]+"</div>" +   
         "</li>";           
}

Note: I have placed descr as sibling of SPAN as <ul>/<ol> can only have LI as child

注意:我已将descr作为SPAN的兄弟,因为

    /
    只能将LI作为子级

Also I would recommend, unobtrusive event handlers instead of using ugly inline event handlers.

另外,我建议使用不显眼的事件处理程序,而不是使用丑陋的内联事件处理程序。

$(document).on('click', '.toggleDesc', function(){
    $(this).next('.descr').toggle();
});

References .next() and use .on() method with Event Delegation approach for dynamically generated elements. And In place of document you should use closest static container for better performance.

引用.next()并使用带有事件委派方法的.on()方法来动态生成元素。并且代替文档,您应该使用最接近的静态容器以获得更好的性能。

#3


3  

You have multiple elements with id descr. ids should be unique. Consider doing something this:

你有多个id为descr的元素。 ID应该是唯一的。考虑做一些事情:

for (var i = 0, len = mydata.texts.length; i < len; i++) {
    list +="<li>"+"<div class='circle'></div>" + 
         "<span onclick='toggleDesc(" + i + ")'>"+ mydata.texts[i]["keyword"] +
         "</span>"+
        "<div id='descr" + i + "'>"+mydata.texts[i]["description"]+"</div>"
        +"</li>";

;
}

function toggleDesc(i) {
    var x = document.getElementById('descr' + i);
    if (x.style.display === 'none') {
        x.style.display = 'block';
    } else {
        x.style.display = 'none';
    }
}

#1


2  

Currently: it is only toggling the first list item.

目前:它只切换第一个列表项。

Because you can't use the same id with multiple elements in a page as it must be unique, and if you use it only the first one will be parsed with document.getElementById() so that's why only the first one is toggled.

因为你不能在页面中使用与页面中的多个元素相同的id,因为它必须是唯一的,并且如果你使用它只有第一个将使用document.getElementById()进行解析,这就是为什么只有第一个被切换的原因。

Solution:

Use a class instead of an id so you can attach the event to all the elements having this class.

使用类而不是id,以便可以将事件附加到具有此类的所有元素。

And in your HTML code pass a reference to the clicked span with this to your toggleDescription() function and use it to find the relevant description inside it.

并在您的HTML代码中将对单击的跨度的引用传递给您的toggleDescription()函数,并使用它来查找其中的相关描述。

This is how should be your code:

这是你的代码应该如何:

for (var i = 0, len = mydata.texts.length; i < len; i++) {
    list +="<li>"+"<div class='circle'></div>" + 
         "<span onclick='toggleDesc(this)'>"+ mydata.texts[i]["keyword"] +
         "</span>"+
         "<div class='descr'>"+mydata.texts[i]["description"]+"</div>"; 
        +"</li>"
}


function toggleDesc(item) {
    $(item).next('.descr').toggle();
}

And make sure you place the description div inside the li elemnt, because a list can contain only li as direct children.

并确保将描述div放在li elemnt中,因为列表只能包含li作为直接子项。

edit:

it needs a css specification to hide by default:

它默认需要隐藏css规范:

.descr{
    display:none;
}

#2


3  

Identifiers in HTML must be unique. However you can use CSS class with multiple time which can be targeted by using Class Selector .class.

HTML中的标识符必须是唯一的。但是,您可以使用具有多个时间的CSS类,可以使用类选择器.class来定位。

for (var i = 0, len = mydata.texts.length; i < len; i++) {
    list +="<li>"+"<div class='circle'></div>" + 
         "<span class='toggleDesc'>"+ mydata.texts[i]["keyword"] +
         "</span>"+
         "<div class='descr'>"+mydata.texts[i]["description"]+"</div>" +   
         "</li>";           
}

Note: I have placed descr as sibling of SPAN as <ul>/<ol> can only have LI as child

注意:我已将descr作为SPAN的兄弟,因为

    /
    只能将LI作为子级

Also I would recommend, unobtrusive event handlers instead of using ugly inline event handlers.

另外,我建议使用不显眼的事件处理程序,而不是使用丑陋的内联事件处理程序。

$(document).on('click', '.toggleDesc', function(){
    $(this).next('.descr').toggle();
});

References .next() and use .on() method with Event Delegation approach for dynamically generated elements. And In place of document you should use closest static container for better performance.

引用.next()并使用带有事件委派方法的.on()方法来动态生成元素。并且代替文档,您应该使用最接近的静态容器以获得更好的性能。

#3


3  

You have multiple elements with id descr. ids should be unique. Consider doing something this:

你有多个id为descr的元素。 ID应该是唯一的。考虑做一些事情:

for (var i = 0, len = mydata.texts.length; i < len; i++) {
    list +="<li>"+"<div class='circle'></div>" + 
         "<span onclick='toggleDesc(" + i + ")'>"+ mydata.texts[i]["keyword"] +
         "</span>"+
        "<div id='descr" + i + "'>"+mydata.texts[i]["description"]+"</div>"
        +"</li>";

;
}

function toggleDesc(i) {
    var x = document.getElementById('descr' + i);
    if (x.style.display === 'none') {
        x.style.display = 'block';
    } else {
        x.style.display = 'none';
    }
}