-
Notifications
You must be signed in to change notification settings - Fork 116
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Update: Change VirtualScroller.renderItems strategy #900
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -253,8 +253,8 @@ class VirtualScroller { | |
newEndOffset = this.totalItems - 1; | ||
} | ||
|
||
// Create a new list element to be swapped out for the existing one | ||
const newListEl = this.createListElement(); | ||
// Creates a document fragment for the new list items to be appended into the list | ||
const fragment = document.createDocumentFragment(); | ||
|
||
if (curStartOffset <= offset && offset <= curEndOffset) { | ||
// Scenario #1: New start offset falls within the current range of items rendered | ||
|
@@ -263,77 +263,70 @@ class VirtualScroller { | |
// |--------------------| | ||
// newStartOffset newEndOffset | ||
newStartOffset = curEndOffset + 1; | ||
// clone elements from newStartOffset to curEndOffset | ||
this.cloneItems(newListEl, this.listEl, offset - curStartOffset, curEndOffset - curStartOffset); | ||
// then create elements from curEnd + 1 to newEndOffset | ||
this.createItems(newListEl, newStartOffset, newEndOffset); | ||
// Create elements from curEnd + 1 to newEndOffset | ||
this.createItems(fragment, newStartOffset, newEndOffset); | ||
// Delete the elements from curStartOffset to newStartOffset | ||
this.deleteItems(this.listEl, curStartOffset - curStartOffset, offset - curStartOffset); | ||
// Append the document fragment to the listEl | ||
this.listEl.appendChild(fragment); | ||
} else if (curStartOffset <= newEndOffset && newEndOffset <= curEndOffset) { | ||
// Scenario #2: New end offset falls within the current range of items rendered | ||
// |--------------------| | ||
// curStartOffset curEndOffset | ||
// |--------------------| | ||
// newStartOffset newEndOffset | ||
|
||
// create elements from newStartOffset to curStart - 1 | ||
this.createItems(newListEl, offset, curStartOffset - 1); | ||
// then clone elements from curStartOffset to newEndOffset | ||
this.cloneItems(newListEl, this.listEl, 0, newEndOffset - curStartOffset); | ||
// Create elements from newStartOffset to curStart - 1 | ||
this.createItems(fragment, offset, curStartOffset - 1); | ||
// Delete the elements from newEndOffset to the end | ||
this.deleteItems(this.listEl, newEndOffset - curStartOffset + 1); | ||
// Insert before the firstElementChild of the listEl | ||
this.listEl.insertBefore(fragment, this.listEl.firstElementChild); | ||
} else { | ||
// Scenario #3: New range has no overlap with current range of items | ||
// |--------------------| | ||
// curStartOffset curEndOffset | ||
// |--------------------| | ||
// newStartOffset newEndOffset | ||
this.createItems(newListEl, newStartOffset, newEndOffset); | ||
this.createItems(fragment, newStartOffset, newEndOffset); | ||
this.listEl.appendChild(fragment); | ||
} | ||
|
||
this.scrollingEl.replaceChild(newListEl, this.listEl); | ||
this.listEl = newListEl; | ||
} | ||
|
||
/** | ||
* Clones a subset of the HTMLElements from the oldList to the newList. | ||
* The newList element is modified. | ||
* Creates new HTMLElements appended to the newList | ||
* | ||
* @param {HTMLElement} newListEl - the new `ol` element | ||
* @param {HTMLElement} oldListEl - the old `ol` element | ||
* @param {number} start - start index | ||
* @param {number} end - end index | ||
* @return {void} | ||
*/ | ||
cloneItems(newListEl, oldListEl, start, end) { | ||
if (!newListEl || !oldListEl || start < 0 || end < 0) { | ||
return; | ||
} | ||
|
||
const { children } = oldListEl; | ||
|
||
if (!children || start >= children.length || end >= children.length) { | ||
createItems(newListEl, start, end) { | ||
if (!newListEl || start < 0 || end < 0) { | ||
return; | ||
} | ||
|
||
for (let i = start; i <= end; i++) { | ||
newListEl.appendChild(children[i].cloneNode(true)); | ||
const newEl = this.renderItem(i); | ||
newListEl.appendChild(newEl); | ||
} | ||
} | ||
|
||
/** | ||
* Creates new HTMLElements appended to the newList | ||
* Deletes elements of the 'ol' | ||
* | ||
* @param {HTMLElement} newListEl - the new `li` element | ||
* @param {HTMLElement} listEl - the `ol` element | ||
* @param {number} start - start index | ||
* @param {number} end - end index | ||
* @param {number} [end] - end index | ||
* @return {void} | ||
*/ | ||
createItems(newListEl, start, end) { | ||
if (!newListEl || start < 0 || end < 0) { | ||
deleteItems(listEl, start, end) { | ||
if (!listEl || start < 0 || end < 0) { | ||
return; | ||
} | ||
|
||
for (let i = start; i <= end; i++) { | ||
const newEl = this.renderItem(i); | ||
newListEl.appendChild(newEl); | ||
} | ||
const listItems = Array.prototype.slice.call(listEl.children, start, end); | ||
listItems.forEach((listItem) => listEl.removeChild(listItem)); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Do we incur a performance penalty here, since There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I don't think so because all the |
||
} | ||
|
||
/** | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should
[end]
be in brackets?There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I wanted to because if not provided (which is how I call it https://github.com/box/box-content-preview/pull/900/files#diff-ae1d3917492ce0b7a65c4b31408eb5deR282) it will just delete to the end of the
listEl
's children