element.addEvent の順で書く その2
addEventListenerとattachEventを両立するよくある話。
前回書いたのがいまいちに思えるので
理想
- なるべくaddEventListenerと同じ順で書きたい(けどaddEventListenerってそもそも長い!)
- 複数の要素相手にforループもいちいち面倒なので省略したい
- 複数のイベントも楽につけたい
ということで書いてみたが…パターンがいろいろ考えられるのでどれがよいのやら。一番単純なパターンはこうなりました。考えられるパターンは下記に。
コード
// IE8+ QQ.doc = document QQ.sup = QQ.doc.addEventListener QQ.add = QQ.sup ? 'addEventListener' : 'attachEvent' QQ.pre = QQ.sup ? '' : 'on' function QQ(sel) { this.eles = typeof sel === "string" ? // string QQ.doc.querySelectorAll(sel) : sel === null ? // getElementById(no-such-element) [] : sel.nodeName || sel === window ? // array, NodeList, HTMLCollection [sel] : sel // single:element, window, document } QQ.prototype.addEvent = function(type, listener, useCapture) { for(var i=0; i<this.eles.length; i++){ this.eles[i][QQ.add](QQ.pre + type, listener, useCapture || false) } var _this = this return function(t, l, u){ return _this.addEvent(t, l ,u) } } function qq(sel){ return new QQ(sel) }
usage
qq("div").addEvent("click", fn, false) qq(window).addEvent("click", fn, false) qq([window, document]).addEvent("click", fn, false) qq(document.getElementById("test")).addEvent("mouseover", mouseFn, false)("mousemove", mouseFn, false)("mouseout", mouseFn, false)
考えられるパターン
- ノーマル。これだとtype,listenerは一つだけしか渡せない
[elements].addEvent(type, fn, false)
- jQueryみたいな?
[elements].addEvent([types], fn, false)
- 2の逆パターン
[elements].addEvent(type, [fns], false)
- type,fnをオブジェクトで渡す
[elements].addEvent({type:fn, type:fn, ....}, false)
- 今回の。
[elements].addEvent(type, fn, false)(type, fn, false)(....
4を用いれば2,3は両立できる。しかしusecaptureを個別に設定できない。
個別に設定できる5は配列を何度もループすることになるので効率が良くはない...と思ったら大して変わらなかった。
書きやすさなら4, usecaptureも設定したなら5でしょうか。
ほとんどfalseにしますけどね。