如何将无序列表项放入数组中

4

我的代码是...

如何使用本地Javascript将每个列表项中的文本获取到一个数组中?

<ul id="list">
    <li>List Item 1</li>
    <li>List Item 2</li>
    <li>List Item 3</li>
    <li>List Item 4</li>
</ul>

<script type="text/javascript">
var list = document.getElementById('list').childNodes.TextNode;
for(var i=0;i < list.length; i++) {
    var arrValue = list[i];
    alert(arrValue);
}
</script>

非常感谢。
5个回答

4

如果您不需要每个<li>之间的文本节点,则不建议使用childNodes。那么,getElementsByTagName('li')有什么问题呢?

var listItems = document.getElementById('list').getElementsByTagName('li'),

    myArray = map(listItems, getText);

function map(arrayLike, fn) {
    var ret = [], i = -1, len = arrayLike.length;
    while (++i < len) ret[i] = fn(arrayLike[i]);
    return ret;
}

function getText(node) {
    if (node.nodeType === 3) return node.data;
    var txt = '';
    if (node = node.firstChild) do {
        txt += getText(node);
    } while (node = node.nextSibling);
    return txt;
}

目前为止最好的方法,但如果存在嵌套列表,则会出现问题,因为getElementsByTagName是分层的。不过,为什么不直接使用map(listItems, getText)呢? - bobince
@bibince,改为map(listItems, getText)。谢谢! - James

1

试试这个:

var list = document.getElementById('list').childNodes;
var theArray = [];
for(var i=0;i < list.length; i++) {
    var arrValue = list[i].innerHTML;
    alert(arrValue);
    theArray.push(arrValue);
}

“childNodes” 包含空格文本节点,对于这些节点,“innerHTML” 是未定义的。对于某些文本,“innerHTML” 将返回转义字符。 - bobince

1
var LIs = document.getElementById('list').childNodes;
var list = [];
for( var i = 0; i < LIs.length; ++i )
{
    var LI = LIs[i];
    list.push(LI.innerText || LI.textContent);
}

而且像往常一样,使用jQuery更简单:

var list = $('#list li').map(function(){ return $(this).text(); });

“childNodes” 包含不需要的空格文本节点(对于这些节点,“innerText”未定义)。 空字符串 “innerText” 的测试失败,导致 IE 将 “undefined” 放入数组中。 - bobince
1
使用jQuery更加简单:var list = $('#list li').map(function(){return $.text([this])}); - James

1

几乎任何 JavaScript 库 (Prototype, jQuery, Closure,...) 都可以使这个过程更加简单,但如果你想自己做:

你已经接近成功了,你的 JavaScript 代码应该看起来像这样:

window.onload = onPageLoad; // Or any of several other similar mechanisms
                            // (you could just run it at the bottom of the page)
function onPageLoad() {
    var node, list, arrValue;

    list = [];
    for (node = document.getElementById('list').firstChild;
        node;
        node = node.nextSibling) {
        if (node.nodeType == 1 && node.tagName == 'LI') {
            list.push(node.innerHTML);
        }
    }

    // `list` now contains the HTML of each LI element under the `ul#list` element
}

解释:

  • 在使用 document.getElementById 之前,您需要确保 DOM 已经准备好了。它肯定会在 onload 时间准备好,并且如果您喜欢的话,还有各种机制可以在稍早的时间触发您的代码(包括将脚本放在最后面)。
  • 循环从获取 ul#list 元素的第一个子元素开始,然后继续直到没有更多的兄弟节点为止。
  • 在循环中,我们检查每个节点是否是 Element(nodeType == 1),并且其标签名称为 "LI"。
  • 如果是,则检索其 HTML 并将其推送到数组上。

我使用 innerHTML 来检索 LIs 的内容,因为它得到了广泛的支持。或者,您可以在 IE(和其他一些浏览器)上使用 innerText,在 Firefox 上使用 textContent,但请注意它们不完全相同(例如,在 Firefox 上的 textContent 将包括 script 标记的内容,这可能不是您想要的)。


@J-P:这肯定是一个选项;无论哪种方式,它都是一个循环,使用 getElementsByTagName 需要第二个函数调用和 NodeList 的创建,如果你打算循环的话,这似乎是不必要的。(这是你的反对票吗?如果是的话,仅仅因为走了一条不同的路就这么严厉似乎有点过分了...) - T.J. Crowder

0

var list = document.getElementsByTagName('ul')[0].getElementsByTagName('li');

变量列表=文档.获取元素按标签名取得('ul')[0].获取元素按标签名取得('li');

var theArray = [];

for (var i = 0; i < list.length; i++) {
    var arrValue = list[i].innerHTML;
    console.log(arrValue);
    theArray.push(arrValue);
}

使用getElementsByTagName而不是使用childnodes,基本上与nickf的答案相同。 - pixel 67

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接