封裝事件處理



繼續 跨瀏覽器事件處理 的內容,如果想將事件處理的封裝與 封裝 DOM 操作 中的程式結合。可以如下:
(function(global) {
    var XD = function(selector, container) {
        return new XD.mth.init(selector, container);
    };
   
    var utils = {
        ...
    };
   
    XD.Event = function(original) {
        if(!this.stopPropagation) {
            return new XD.Event(original);
        }
        // 複製特性
        this.original = original;
        this.type = original.type;
        this.target = original.target || original.srcElement;
        // .. 標準化其它特性
    };
   
    XD.Event.prototype = {
        stopPropagation: function() {
            if(this.original.stopPropagation) {
                this.original.stopPropagation();
            }
            else {
                this.original.cancelBubble = true;
            }
        }
        // 標準化其它方法
    };
   
    // 建立bind與unbind公用函式
    if(document.addEventListener) {
        utils.bind = function(element, eventType, handler) {
            element.addEventListener(eventType, function(event) {
                var result = handler.call(event.currentTarget, XD.Event(event));
                if(result === false) {
                    event.preventDefault();
                }
                return result;
            }, false);
        };
        utils.unbind = function(element, eventType, handler) {
            element.removeEventListener(eventType, handler, false);
        };
    }
    else if(document.attachEvent) {
        utils.bind = function(element, eventType, handler) {
            element.attachEvent('on' + eventType, function() {
                var result = handler.call(element, XD.Event(window.event));
                if(result === false) {
                    window.event.returnValue = false;
                }
                return result;
            });
        };
        utils.unbind = function(element, eventType, handler) {
            element.detachEvent(eventType, handler);
        };
    }
   
   function extend(target, source) {
        utils.each(source, function(value, key) {
            target[key] = value;
        });
   }
   ...
  
   XD.mth = XD.prototype = {
       ...
       // 包裹器上的bind方法
       bind: function(eventType, handler) {
           return XD.each(this, function(element) {
               XD.bind(element, eventType, handler);
           });
       },
       // 包裹器上的unbind方法
       unbind: function(eventType, handler) {
           return XD.each(this, function(element) {
               XD.unbind(element, eventType, handler);
           });
       },
       // 註冊click事件時方便的click方法
      click: function(handler) {
          return this.bind('click', handler);
       }

       // 其它註冊xxx事件時方便的xxx方法
   };
  
   XD.mth.init.prototype = XD.mth;
   global.XD = XD;
})(this);

事件處理存在著許多跨瀏覽器的差異性,這邊僅示範基本的封裝概念,完成的程式庫如下:

利用以上的程式庫,可以改寫 封裝 DOM 操作 中第一個範例:
<html>
<head>
<meta content="text/html; charset=UTF-8" http-equiv="content-type">
<script type="text/javascript" src="js/gossip-0.3.js"></script>
<script type="text/javascript">
XD.bind(window, 'load', function() {
XD('#add').click(function() {
XD('<img>')
.attr('src', XD('#src').val())
.click(function(event) {
XD(this).remove();
})
.appendTo('#images');
});

});
</script>
</head>
<body>
<input id="src" type="text"><button id="add">新增圖片</button>
<div id="images"></div>
</body>
</html>

可以改寫 封裝 DOM 操作 中第二個範例:
<html>
<head>
<meta content="text/html; charset=UTF-8" http-equiv="content-type">
<script type="text/javascript" src="js/gossip-0.3.js"></script>
<script type="text/javascript">
XD.bind(window, 'load', function() {
var container1XD = XD('#container1');
var container2XD = XD('#container2');
XD('#image').click(function() {
if(this.parentNode === container1XD[0]) {
container2XD.append(this);
}
else {
container1XD.append(this);
}
});
});
</script>
</head>
<body>
容器一:<div id="container1">
<img id="image" src=
"https://openhome.cc/Gossip/images/caterpillar_small.jpg"/>
</div><br>
容器二:<div id="container2"></div>
</body>
</html>