表格中第二列传值为什么无效?

只有第一列有效,第二列没有传值。
如果两个表格就没问题。
但是只能用户一张表格,请问怎么修改呢,谢谢。

<table>
<tbody>
<tr>
<td><input type="checkbox"> </td>
<td>第一列</td>
<td><input type="checkbox"> </td>
<td>第二列</td>
</tr>
 </tbody>
</table>

<button onclick="next()">下一步</button>
<script>
function next() {
    sessionStorage.setItem('names',
    JSON.stringify([...document.querySelectorAll('tbody>tr')]
    .filter(tr => tr.querySelector('input').checked)
    .map(tr => tr.children[1].innerText)))

    location = 'next.html'
}
</script>


**next.html**
<div></div>
<script>
    document.querySelector('div').innerText = JSON.parse(sessionStorage.getItem('names')).join('\n')
</script>
阅读 1.6k
3 个回答

querySelectorAll是查找所有符合条件的元素,你只有一个tr
querySelector是查找符合条件的第一个元素,只会找到要第一个td

新手上路,请多包涵

试试这个是否满足要求

<table>
<tbody>
<tr>
<td><input type="checkbox"> </td>
<td>1第一列</td>
<td><input type="checkbox"> </td>
<td>1第二列</td>
</tr>
<tr>
<td><input type="checkbox"> </td>
<td>2第一列</td>
<td><input type="checkbox"> </td>
<td>2第二列</td>
</tr>
 </tbody>
</table>

<button onclick="next()">下一步</button>
<script>
function next() {
    const arr = [];
    [...document.querySelectorAll('tbody>tr')].forEach((tr, idx) => {
        const rowArr = [...tr.querySelectorAll('input')].filter(ipt => ipt.checked).map(ipt => {
            return ipt.parentNode.nextElementSibling.childNodes[0]?.data;
        });
        arr[idx] = rowArr;
    })
    sessionStorage.setItem('names', JSON.stringify(arr));
}
</script>

来说为什么只能取第一列。

[...document.querySelectorAll("tbody>tr")]              // 找到了 TR,而且目前来看是唯一的一个
    .filter(tr => tr.querySelector("input").checked)    // 如果有选中,不管是哪个,返回当前 tr,否则是空集
    .map(tr => tr.children[1].innerText)                // 如果有 tr,它的第 2(index 1) 个子元素就是 <td>第一列</td>

看注释,你会发现,如果没勾选,取到的是 [],但是如果勾选了,不过你钩选哪个(或者两个),取到的都是 ["第一列"]。根本原因是,应该过滤的不是 tr,而是 td。只有 td 才能将两个 input 区分开。


要先找 tr 再来找 input 也是可以的。但在你的代码里,只有一个 tr 包含了两个 input,按照原来的 filter(),不管选中那个,都会返回当前 tr。

但是原本的目的,应该是找到被勾选的 input 及其父 TD,然后再找它的兄弟 TD 来取值(看 Table 结构)。所以 filter 的不应该是 tr,而是 td

[...document.querySelectorAll("tbody > tr > td")]
    .filter(td => td.querySelector("input")?.checked)

注意,如果某个 td 里没有 input(确实存在),那 querySelector("input") 会得到 null,所以需要使用 Optional Chain 来判断 checked。

接下来,过滤出来的是包含了选中 input 的 td,只需要找它的下一个兄弟就能取值,所以

    ...
    .map(td => td.nextElementSibling)
    .map(td => td.innerText)

完整的写出来就是

const value = [...document.querySelectorAll("tbody > tr > td")]
    .filter(td => td.querySelector("input")?.checked)
    .map(td => td.nextElementSibling)
    .map(td => td.innerText);

换个思路,也可以直接找 input 来判断,然后对过滤出来的 input 取父级 td,再去找兄弟:

const value = [...document.querySelectorAll("tbody > tr input")]
    .filter(input => input.checked)
    .map(input => input.parentElement.nextElementSibling)
    .map(td => td.innerText);
撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题