admin管理员组

文章数量:1321259

I am trying to set up a search feature for a large table that has about 1000 rows. The problem with this is that the rendering eats up performance by a lot. This is because I am iterating through all the rows in the table and setting the style of the ones that do not contain the search query to 'none'.

For some reason, the browser renders all the elements again each time I make a change. I am getting the table data as a nodelist via document.quesrtySelectorAll('tbody tr'). My solution is to copy this to a new object, do the search and style changes on the new object, and then copy it back, causing the browser to only have to re-render the table once.

let items = document.querySelectorAll('tbody tr');
let itemsArr = [...items];

for (let ele of itemsArr) {
    . . .

    if (!lower_case_table_value.match(lower_case_search_value)) {
        ele.style.display = 'none';
    }
    else {
        ele.style.display = 'table-row';
    }
}

let list = document.querySelector('tbody');
for (let i = 0; i < items.length; i++) {
    list.appendChild(itemsArr[i]);
}

No matter what I do, though, any changes I make on the new object also makes the changes to the old. I removed the second for loop and it behaves like nothing happened. It is like it is not a copy, but a pointer.

Does anybody know who to copy a nodelist to a new object and make sure they are separate and not pointers to one another?

I am trying to set up a search feature for a large table that has about 1000 rows. The problem with this is that the rendering eats up performance by a lot. This is because I am iterating through all the rows in the table and setting the style of the ones that do not contain the search query to 'none'.

For some reason, the browser renders all the elements again each time I make a change. I am getting the table data as a nodelist via document.quesrtySelectorAll('tbody tr'). My solution is to copy this to a new object, do the search and style changes on the new object, and then copy it back, causing the browser to only have to re-render the table once.

let items = document.querySelectorAll('tbody tr');
let itemsArr = [...items];

for (let ele of itemsArr) {
    . . .

    if (!lower_case_table_value.match(lower_case_search_value)) {
        ele.style.display = 'none';
    }
    else {
        ele.style.display = 'table-row';
    }
}

let list = document.querySelector('tbody');
for (let i = 0; i < items.length; i++) {
    list.appendChild(itemsArr[i]);
}

No matter what I do, though, any changes I make on the new object also makes the changes to the old. I removed the second for loop and it behaves like nothing happened. It is like it is not a copy, but a pointer.

Does anybody know who to copy a nodelist to a new object and make sure they are separate and not pointers to one another?

Share Improve this question edited May 30, 2019 at 18:25 MARS asked May 30, 2019 at 18:04 MARSMARS 5871 gold badge10 silver badges28 bronze badges 8
  • Hi, maybe give us a small snippet of your table and how you're trying to copy the documents. – Yannick K Commented May 30, 2019 at 18:07
  • @Andreas Thanks I just made the edit. – MARS Commented May 30, 2019 at 18:14
  • 1 Isn't it easier to form required features of table on server side? If tr contains td with no data, then just append smth like style="display: none" – Banzay Commented May 30, 2019 at 18:14
  • Did you miss ... in let itemsArr = [items];? Otherwise this wouldn't work at all (because ele === items). – Andreas Commented May 30, 2019 at 18:21
  • 1 In the for...of... loop you're changing the display property of the elements. The second loop and the .appendChild() isn't necessary (and only adds more unnecessary work (reflow) for the browser). This would require some testing, but I would guess that cloning the DOM nodes, changing the clones, removing the old nodes and adding the clones, will take more time then just changing the style. – Andreas Commented May 30, 2019 at 18:30
 |  Show 3 more ments

3 Answers 3

Reset to default 5

just tumbled on the same problem today and found that you can copy a DOM node element with the method "node.cloneNode" e.g.:

let p = document.getElementById("para1")
let p_prime = p.cloneNode(true)

I took the snippet from the MDN documentation that you can find here: https://developer.mozilla/en-US/docs/Web/API/Node/cloneNode

most probably you already found the solution for this, but anyway, I leave this here for the record.

let items = document.querySelectorAll('tbody tr');
let itemsArr = [...items];

here items is a nodeList so itemsArray stores also a nodeList now if you try to iterate over itemsArray there is only one thing in there which is the nodeList you put in there insted if you add spread items into itemsArray you'll be storing elements not the entire odeList

if you want to get a new Array instead of a chilNode use Array.from(nodeToCopy) this returns a new Array instead of a child node

本文标签: javascriptHow to copy a nodelistStack Overflow