Git Product home page Git Product logo

Comments (13)

errorrik avatar errorrik commented on June 24, 2024

我觉得可以有,需要考虑如何设计和组织更好。

假设addDOMEvent(control, element, eventType, listener),那么,control上就需要一个private的属性保存这些个listener,这些listener需要和element对应,那你可能要为没有id的element生成id。

from esui.

otakustay avatar otakustay commented on June 24, 2024

addDOMEvent(control, type, listener),只管main上的,控件设计也同样追求只用delegate不在具体元素上注册事件,这样如何?

from esui.

errorrik avatar errorrik commented on June 24, 2024

控件设计也同样追求只用delegate不在具体元素上注册事件

这个,基本上,很难。。。delegate只在click时算比较好用。我觉得,如果要搞,就搞addDOMEvent,不能只搞addMainEvent

并且,如果只搞main,现在的直接onclick=是好用的。而且在mousemove时性能更高

from esui.

otakustay avatar otakustay commented on June 24, 2024

onclick=的问题是只能挂一个,你看如果我是控件作者,没看仔细你的helper中有把onmouseup给用了(我也不该知道我的基类竟然有用过这东西),我在我的某个控件里又来个onmouseup=xxx,这就出问题了

我原本的设想是,要给某个子元素注册事件的话,先在子元素上挂个data-ui-role属性,然后提供的注册事件的方法是addDOMEvent(control, type, role, listener),有个自动根据role过滤的功能,当然这种约束对控件开发者来说并不是那么爽快的事,缺点确实如 @errorrik 所说,像mouseenter这种人家压根不冒泡你怎么玩

要搞addDOMEvent也没问题,无非是jQuery那一套,在DOM上直接挂个属性就行,不需要一定有id的。我们不像jQuery还有namespace event之类的,只搞精简的一套也就几十行代码,挺方便的,如果就这么定了的话,明天我搞定之

from esui.

errorrik avatar errorrik commented on June 24, 2024

现有实现为main直接onclick=的原因其实是:不希望开发者继续往main上挂这几个事件。不过要改成addListener也行。

role确实是不太容易玩,理解难度有点大。

要搞addDOMEvent也没问题,无非是jQuery那一套,在DOM上直接挂个属性就行,不需要一定有id的

这种搞法坏处有两个:

  1. 卸载时的性能
  2. 卸载时我猜会从main开始找,但是如果元素不在main下(比如现在Table的表头跟随),就卸不掉了

from esui.

otakustay avatar otakustay commented on June 24, 2024

每个元素上的事件都会丢在控件的一个私有属性里面保存着,卸载的时候把这个属性跑一遍就能全部搞定。每个事件注册时,在这个属性里都会保存elementtypefn等,卸载的时候拿出来直接removeEventListener就行了,最后再把这个属性里的element弄掉防内存泄露,所以我觉得不会产生(无法接受的)性能问题,也不会卸不掉

function triggerDOMEvent(e) {
    var queue = this.domEvents[e.target['__ui_event_identity__']][e.type];
    for (var i = 0; i < queue.length; i++) {
        queue[i].call(this, e);
    }
}

function Control() {
    this.domEvents = {};
}

Control.prototype.addDOMEvent = function (element, type, handler) {
    var id = element['__ui_event_identity__'];
    if (!id) {
        element['__ui_event_identity__'] = helper.getGUID();
    }

    if (!domEvents[id]) {
        domEvents[id] = { element: element }; // 没有事件名字叫element的
    }
    var events = domEvents[id];

    var queue = events[type];
    if (!queue) {
        queue = events[type] = [];
        var trigger = lib.bind(triggerDOMEvent, this);
        queue.handler = trigger;
        element.addEventListener(type, trigger, false);
    }

    queue.push(handler);
};

Control.prototype.clearDOMEvents = function () {
    for (var id in this.domEvents) {
        // 没加hasOwnProperty
        var events = this.domEvents[id].element;
        var element = events.element;
        delete events.element; // 防内存泄露外加让下面的for正常工作
        for (var type in events) {
            // 没加hasOwnProperty
            element.removeEventListener(type, events[type].handler, false);
        }
    }

    // 所有东西丢光
    this.domEvents = {};
};

from esui.

otakustay avatar otakustay commented on June 24, 2024

上面这个方案的很大一个缺陷是,在控件还活着的时候如果有移除子元素,内存回收不掉(一直在domEvents中被存着),除非我们的clearDOMEvents接受一个HTMLElement作为可选参数,单独移掉这一个元素相关的事件。

from esui.

errorrik avatar errorrik commented on June 24, 2024

上面这个方案,看起来在控件dispose时还是能移除掉的。只不过重复render的过程如果不断重新构建子元素则老的移除不掉。

还有,这货貌似应该弄helper里

所以为什么我有时候喜欢生成onclick=“”,因为不用处理释放

from esui.

otakustay avatar otakustay commented on June 24, 2024

还有,这货貌似应该弄helper里

放helper里是必须的,昨天那时间脑子没这么好使一急就随便写在Control上了。

如果OK的话,我以这个方案实现一下吧?另外会提供可以针对单个HTMLElement移除事件的方法,控件开发者注意调用

from esui.

errorrik avatar errorrik commented on June 24, 2024

你在数组上挂handler属性,真狠。。。

我觉得没问题哈

from esui.

otakustay avatar otakustay commented on June 24, 2024

已经在 b1756fb 中加上了,还没测试,测试稍后补上

from esui.

otakustay avatar otakustay commented on June 24, 2024

@errorrik 有空把基类中的一些事件迁移到这上面吧

from esui.

otakustay avatar otakustay commented on June 24, 2024

测试在 e1b0324 补上了,不全面但能保证基本的正确性,未来有遇上问题再补相应测试用例。

另外各位如果有遇到比较纠结怕出错的地方,或者要改某一处的代码,建议先把测试补了

from esui.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.