diff --git a/src/class/playground.js b/src/class/playground.js index 525d375a5a..ed3f147943 100644 --- a/src/class/playground.js +++ b/src/class/playground.js @@ -704,9 +704,11 @@ Entry.Playground = class Playground { updatePictureView() { if (this.pictureSortableListWidget) { - this.pictureSortableListWidget.setData({ items: [] }); - this.pictureSortableListWidget.setData({ - items: this._getSortablePictureList(), + Entry.Utils.runWithScrollPreserved(this.pictureListView_, () => { + this.pictureSortableListWidget.setData({ items: [] }); + this.pictureSortableListWidget.setData({ + items: this._getSortablePictureList(), + }); }); } this.reloadPlayground(); @@ -1102,8 +1104,10 @@ Entry.Playground = class Playground { updateSoundsView() { if (this.soundSortableListWidget) { - this.soundSortableListWidget.setData({ - items: this._getSortableSoundList(), + Entry.Utils.runWithScrollPreserved(this.soundListView_, () => { + this.soundSortableListWidget.setData({ + items: this._getSortableSoundList(), + }); }); } diff --git a/src/class/scene.js b/src/class/scene.js index e2ca9da4c9..b58c91f27a 100644 --- a/src/class/scene.js +++ b/src/class/scene.js @@ -172,7 +172,11 @@ Entry.Scene = class { updateSceneView() { const items = this._getSortableSceneList(); if (this.sceneSortableListWidget) { - setTimeout(() => this.sceneSortableListWidget.setData({ items }), 0); + setTimeout(() => { + Entry.Utils.runWithScrollPreserved(this.listView_, () => { + this.sceneSortableListWidget.setData({ items }); + }); + }, 0); } } diff --git a/src/util/utils.js b/src/util/utils.js index 4864044255..b2e6176d62 100644 --- a/src/util/utils.js +++ b/src/util/utils.js @@ -479,6 +479,27 @@ Entry.Utils.generateId = function () { return `0000${((Math.random() * Math.pow(36, 4)) << 0).toString(36)}`.substr(-4); }; +/** + * Sortable 위젯의 setData 등 리렌더 콜백 실행 중에도 + * 내부 스크롤 컨테이너(.rcs-inner-container)의 스크롤 위치를 유지한다. + * @param {HTMLElement} containerEl Sortable이 마운트된 컨테이너 + * @param {Function} callback 리스트를 갱신하는 동기 콜백 + */ +Entry.Utils.runWithScrollPreserved = function (containerEl, callback) { + const getScrollEl = () => containerEl && containerEl.querySelector('.rcs-inner-container'); + const before = getScrollEl(); + const top = before ? before.scrollTop : 0; + const left = before ? before.scrollLeft : 0; + + callback(); + + const after = getScrollEl(); + if (after) { + after.scrollTop = top; + after.scrollLeft = left; + } +}; + Entry.Utils.randomColor = function () { const letters = '0123456789ABCDEF'; let color = '#';