Я не уверен на 100%, почему ваш метод 3 начал работать, но я предполагаю, что это потому, что обработчик onIonScroll
обновляет состояние scrollOffset
, которое затем вызывает метод @Watch()
.
Здесь вы перепутали несколько вещей, поэтому сначала я попытаюсь немного это прояснить: если элемент генерирует событие <EventName>
, вы можете привязать слушателя к этому элементу, добавив * Свойство 1008 *, например:
<my-button onclick={console.log} />
связывает функцию console.log
с событием click
. Эквивалент выполнения той же вещи в JavaScript будет:
document.querySelector('my-button').addEventListener('click', console.log);
Если вы сделали addEventListener('onclick')
, это не сработает, потому что имя события click
, а не onclick
. Вы добавляете префикс on
только в том случае, если хотите добавить обработчик событий к элементу в HTML (см. Обработчики DOM onevent ). Кроме того, это также будет работать в JavaScript:
document.querySelector('my-button').onclick = console.log;
(разница в том, что вы можете установить только одно свойство onclick
, но вы можете подключить несколько click
прослушивателей событий, если вы используете addEventListener
)
Обратите внимание, что регистр имеет значение в JavaScript, но не в HTML, поэтому
<my-button onClick={console.log} />
эквивалентно первому примеру.
В идеале я хотел прослушать событие прокрутки родительского компонента в дочернем элементе, и до сих пор не могу заставить его работать.
Это невозможно, потому что события могут только всплывать в DOM-дереве, но не вниз. Концепция "события вверх, подпорки". Для вашего случая самое чистое решение, которое я могу придумать, похоже на то, что вы уже пробовали: прослушайте событие у родителя, а затем передайте необходимую информацию ребенку в качестве опоры:
import { h, Component, State } from '@stencil/core';
import { ScrollDetail } from '@ionic/core';
@Component({ tag: 'my-parent' })
export class Parent {
@State() scrollTop = 0;
setScrollTop = (e: CustomEvent<ScrollDetail>) => {
this.scrollTop = e.detail.scrollTop;
}
render() {
return (
<ion-content scrollEvents onIonScroll={this.setScrollTop}>
<child-component scrollTop={this.scrollTop} />
</ion-content>
);
}
}
Вместо используя onIonScroll
в качестве свойства <ion-content>
, вы также можете использовать декоратор @Listen()
следующим образом:
@Listen('ionScroll')
setScrollTop(e: CustomEvent<ScrollDetail>) {
this.scrollTop = e.detail.scrollTop;
}
Здесь ваша ошибка заключалась в использовании 'onscroll'
в качестве имени события.
Я видел, что вы также пытались передать ссылку на элемент прокрутки дочернему элементу. Элемент ion-content
не тот, который фактически прокручивается, поэтому он предоставляет метод getScrollElement
, который дает вам правильный элемент, если вы хотите сделать «нативную» вещь, например, доступ к базовому событию scroll
или вручную получить доступ к scrollTop
этого элемента (я полагаю, это то, что вы пытались сделать от своего ребенка).
customElements.whenDefined('ion-content').then(() => {
document.querySelector('ion-content').getScrollElement().then(el => {
el.addEventListener('scroll', () => console.log(el.scrollTop));
});
});