diff --git a/injection-order/injection-order.js b/injection-order/injection-order.js index 5d447b7c..8a5d8f67 100644 --- a/injection-order/injection-order.js +++ b/injection-order/injection-order.js @@ -43,7 +43,7 @@ async function InjectionOrder(show = true) { function makeList([type, styles]) { const ids = groups[type] = styles.map(s => s._id); - const ol = ols[type] = $create('ol'); + const ol = ols[type] = $create('ol.scroller'); let maxTranslateY; ol.append(...styles.map(makeEntry)); ol.on('d:dragstart', ({detail: d}) => { diff --git a/js/dom.js b/js/dom.js index bc434dae..241c8b12 100644 --- a/js/dom.js +++ b/js/dom.js @@ -278,16 +278,22 @@ function onDOMready() { : new Promise(resolve => document.on('DOMContentLoaded', resolve, {once: true})); } +/** + * Scrolls `window` or the closest parent with `class="scroller"` if the element is not visible, + * centering the element in the view + * @param {HTMLElement} element + * @param {number} [invalidMarginRatio] - for example, 0.10 will center the element if it's in the top/bottom 10% of the scroller + */ function scrollElementIntoView(element, {invalidMarginRatio = 0} = {}) { // align to the top/bottom of the visible area if wasn't visible - const parent = element.parentNode; - if (!parent) return; + if (!element.parentNode) return; const {top, height} = element.getBoundingClientRect(); - const {top: parentTop, bottom: parentBottom} = parent.getBoundingClientRect(); + const {top: parentTop, bottom: parentBottom} = element.parentNode.getBoundingClientRect(); const windowHeight = window.innerHeight; if (top < Math.max(parentTop, windowHeight * invalidMarginRatio) || top > Math.min(parentBottom, windowHeight) - height - windowHeight * invalidMarginRatio) { - parent.scrollBy(0, top - windowHeight / 2 + height); + const scroller = element.closest('.scroller'); + scroller.scrollBy(0, top - (scroller ? scroller.clientHeight : windowHeight) / 2 + height); } }