事件委托 - 检索 class 的实例,其中 DOM 元素是 属性 的

Event delegate - Retrieve instance of class that a DOM element is a property of

我正在学习范围界定和继承的方法,并且在检索 class 的实例时遇到了一些困难,其中 DOM 元素是 属性。有一个 Parent,假设可以有无限个 Child(ren)。有没有办法通过事件委托获取实例?希望以下内容有助于解释:

class Parent {
    constructor() {
        this.element = document.createElement('div');
        this.element.setAttribute('class', 'parent');

        // add elements from instances
        this.element.appendChild(new Child(1, this).element);
        this.element.appendChild(new Child(2, this).element);
        this.element.appendChild(new Child(3, this).element);

        // event delegate
        this.element.addEventListener('click', (e) => {
            // would like to get the particular instance of the class "Child" that was clicked
        });
    }

    something(id) {
        console.log('something', id);
    }
}

class Child  {
    constructor(id, parentReference) {
        this.id = id;
        this.element = document.createElement('div');
        this.element.setAttribute('class', 'child');

        // would like to avoid adding a click event for each and use the parent as delegate
        this.element.addEventListener('click', () => {
            parentReference.something(this.id)
        });
    }
}

希望这是有道理的,欢迎任何和所有反馈。

另外请注意,由于我没有将实例存储在任何地方,只是创建一个元素并将其附加到 DOM,只要 [=],Child 实例是否会保持不变25=] 元素保持渲染,其他属性被使用然后被垃圾收集?是否应该将它们存储在其他地方,如数组以确保安全?

提前致谢!

看起来您正在尝试做的实际上是 Web 组件:您可以让 class 扩展 HTMLElement 并受益于 custom elements 自带的整个生命周期。

例如,您可以有一个 Parent 组件,其中包含一些 Child 组件。由于 ParentChild classes 将是真正的 HTMLElements,如果您在 Parent 对象中注册一个点击事件侦听器,您将收到在子元素上触发的点击事件。并且单击的子实例将在单击事件的目标 属性 中可用。

class ParentElement extends HTMLElement {
    constructor() {
        super();
        this.classList.add('parent');

        // add elements from instances
        this.innerHTML = `
            <child-element data-sequence="1"></Child>
            <child-element data-sequence="2"></Child>
            <child-element data-sequence="3"></Child>
        `;

        // event delegate
        this.addEventListener('click', (e) => {
            // Child instance is available in the event itself
            const child = e.target;
            this.something(child.id);
        });
    }

    something(id) {
        console.log('something', id);
    }
}
window.customElements.define('parent-element', Parent);

class ChildElement extends HTMLElement {
    constructor() {
        super()
        this.id = this.dataset.sequence;
        this.classList.add('child');
    }
}
window.customElements.define('child-element', ChildElement);

然后你可以将父元素附加到 dom :

document.body.appendChild(new ParentElement());

(小心,我没有测试前面的例子,这只是给你一个想法)

但也许我理解错了。在这种情况下,我建议避免将对 dom 元素的引用保留到自定义对象中,因为这可能很容易导致内存泄漏(如果您重新呈现页面的某些部分但保留对 ParentChild 个实例,那么您还将保留对相应 dom 节点的引用)。难道你不能反过来将自定义对象附加到 dom 节点(有点像控制器?)

希望对您有所帮助,