Устранение дребезга обработчиков событий в директиве AlpineJS x-init

Я пытаюсь добавить прослушиватели событий прокрутки в x-refs (я не хочу добавлять их в DOM с помощью @scroll.debounce, потому что я хочу, чтобы он был максимально переносимым).

Введите код здесь: https://codepen.io/skttl/pen/vYXowBY?editors=1111

<div x-data="xOverflow()" x-init="init()" style="width:50%;border:1px solid red;position:relative;overflow:hidden;">
  <div x-ref="wrapper" style="overflow-x:auto;">
  <div x-ref="content" style="width:1000px;border:1px solid blue; height:500px;">
    
    <div>wrapper.clientWidth: <span x-text="$refs.wrapper.clientWidth"></span></div>
    <div>content.clientWidth: <span x-text="$refs.content.clientWidth"></span></div>
    <div>overflow: <span x-text="overflow"></span>
  </div>
    </div>
  <div x-show="overflow" style="position:absolute;top:0;left:90%;right:0;bottom:0;background:rgba(0,0,0,.15);"></div>
</div>
function xOverflow() {
    return {
        overflow:false,

        // methods
        setFromResize() {
            this.overflow = this.$refs?.wrapper?.clientWidth < this.$refs?.content?.clientWidth
            console.log(`resize: overflow is ${this.overflow}`);
        },
        setFromScroll(e) {
            this.overflow = !(e.target.scrollLeft == this.$refs?.content?.clientWidth - this.$refs?.wrapper?.clientWidth);
            console.log(`scroll: overflow is ${this.overflow}`);
        },

        init() {
            window.addEventListener("resize", event => _.debounce(this.setFromResize(), 250));
            this.$refs?.wrapper.addEventListener("scroll", event => _.debounce(this.setFromScroll(event)));
        }
    }
}

Что я пытаюсь определить, если clientWidth $refs.content больше, чем $refs.wrapper. Когда размер окна изменяется, это должно быть обнаружено снова.

В дополнение к этому я хочу показать наложение (если содержимое переполняется), которое должно быть удалено при прокрутке до конца.

Я мог бы сделать это, просто применив @resize.window.debounce к корневому элементу и @scroll.debounce к элементу-оболочке. Но я хочу, чтобы этот компонент был переносимым, просто добавляя x-data, x-init и x-refs, не беспокоясь о подключении прослушивателей событий.

Я попытался добавить lodash debounce в список событий, но функции вызываются для каждого события, а не отменяются. Проверьте console.log для подтверждения.

Может ли кто-нибудь помочь мне понять это правильно?


person Søren Kottal    schedule 27.01.2021    source источник


Ответы (1)


Получается, я идиот, и мне просто нужно было немного передвинуть вещи :)

Из

window.addEventListener("resize", event => _.debounce(this.setFromResize(), 250));
this.$refs?.wrapper.addEventListener("scroll", event => _.debounce(this.setFromScroll(event)));

to

window.addEventListener("resize", _.debounce(event => this.setFromResize(), 250));
this.$refs?.wrapper.addEventListener("scroll", _.debounce(event => this.setFromScroll(event)));
person Søren Kottal    schedule 27.01.2021