OpenLayers事件处理Event.js(七)

主要用来向HTML元素绑定事件处理函数,并触发运行事件处理函数。

代码

OpenLayers.Event 
= {

    
//事件cache
    observers: false,
    
    
//空格
    KEY_BACKSPACE: 8,

    
//TAB
    KEY_TAB: 9,

    
//回车
    KEY_RETURN: 13,
    
    
//ESC
    KEY_ESC: 27,

    
//左方向键
    KEY_LEFT: 37,

    
//向上方向键
    KEY_UP: 38,

    
//向右方向键
    KEY_RIGHT: 39,

    
//向下方向键
    KEY_DOWN: 40,

    
//删除键
    KEY_DELETE: 46,


    
//返回事件触发元素
    element: function(event) {
        
return event.target || event.srcElement;
    },

    
//鼠标左键
    isLeftClick: function(event) {
        
return (((event.which) && (event.which == 1)) ||
                ((event.button) 
&& (event.button == 1)));
    },

    
//鼠标右键
     isRightClick: function(event) {
        
return (((event.which) && (event.which == 3)) ||
                ((event.button) 
&& (event.button == 2)));
    },
     
    
//取消事件冒泡、及浏览器事件默认行为
    stop: function(event, allowDefault) {
        
//浏览器事件默认行为
        if (!allowDefault) { 
            
if (event.preventDefault) {
                event.preventDefault();
            } 
else {
                event.returnValue 
= false;
            }
        }
        
//取消事件冒泡        
        if (event.stopPropagation) {
            event.stopPropagation();
        } 
else {
            event.cancelBubble 
= true;
        }
    },

    
//查找一个元素,从事件触发的元素,向上遍历,直到tagName
    findElement: function(event, tagName) {
        
//触发事件的元素
        var element = OpenLayers.Event.element(event);
        
while (element.parentNode && (!element.tagName ||
              (element.tagName.toUpperCase() 
!= tagName.toUpperCase()))){
            element 
= element.parentNode;
        }
        
return element;
    },

    
//将observer函数绑定elementParam的name事件上
    observe: function(elementParam, name, observer, useCapture) {
        
var element = OpenLayers.Util.getElement(elementParam);
        useCapture 
= useCapture || false;
        
        
//浏览器兼容
        if (name == 'keypress' &&
           (navigator.appVersion.match(
/Konqueror|Safari|KHTML/)
           
|| element.attachEvent)) {
            name 
= 'keydown';
        }

        
//创建元素事件数组
        if (!this.observers) {
            
this.observers = {};
        }

        
//创建标识事件ID
        if (!element._eventCacheID) {
            
var idPrefix = "eventCacheID_";
            
if (element.id) {
                idPrefix 
= element.id + "_" + idPrefix;
            }
            element._eventCacheID 
= OpenLayers.Util.createUniqueID(idPrefix);
        }

        
var cacheID = element._eventCacheID;

        
//if there is not yet a hash entry for this element, add one
        if (!this.observers[cacheID]) {
            
this.observers[cacheID] = [];
        }

        
//存入元素事件数组
        this.observers[cacheID].push({
            
'element': element,
            
'name': name,
            
'observer': observer,
            
'useCapture': useCapture
        });

        
//将observer函数绑定到浏览器事件上
        if (element.addEventListener) {
            element.addEventListener(name, observer, useCapture);
        } 
else if (element.attachEvent) {
            element.attachEvent(
'on' + name, observer);
        }
    },

    
//去除绑定在elementParam元素上的事件处理程序observer
    stopObservingElement: function(elementParam) {
        
var element = OpenLayers.Util.getElement(elementParam);
        
var cacheID = element._eventCacheID;
        
//移除
        this._removeElementObservers(OpenLayers.Event.observers[cacheID]);
    },

  
    _removeElementObservers: 
function(elementObservers) {
        
if (elementObservers) {
            
for(var i = elementObservers.length-1; i >= 0; i--) {
                
var entry = elementObservers[i];
                
var args = new Array(entry.element,
                                     entry.name,
                                     entry.observer,
                                     entry.useCapture);
                
var removed = OpenLayers.Event.stopObserving.apply(this, args);
            }
        }
    },

    
//移除绑定在elementParame元素的name事件上的observer函数
    stopObserving: function(elementParam, name, observer, useCapture) {
        useCapture 
= useCapture || false;
    
        
var element = OpenLayers.Util.getElement(elementParam);
        
var cacheID = element._eventCacheID;

        
if (name == 'keypress') {
            
if ( navigator.appVersion.match(/Konqueror|Safari|KHTML/|| 
                 element.detachEvent) {
              name 
= 'keydown';
            }
        }

        
//循环遍历查找事件为name的事件Entry
        var foundEntry = false;
        
var elementObservers = OpenLayers.Event.observers[cacheID];
        
if (elementObservers) {
    
            
// find the specific event type in the element's list
            var i=0;
            
while(!foundEntry && i < elementObservers.length) {
                
var cacheEntry = elementObservers[i];
    
                
if ((cacheEntry.name == name) &&
                    (cacheEntry.observer 
== observer) &&
                    (cacheEntry.useCapture 
== useCapture)) {
    
                    elementObservers.splice(i, 
1);
                    
if (elementObservers.length == 0) {
                        
delete OpenLayers.Event.observers[cacheID];
                    }
                    foundEntry 
= true;
                    
break
                }
                i
++;           
            }
        }
    
        
//从元素上移除事件绑定
        if (foundEntry) {
            
if (element.removeEventListener) {
                element.removeEventListener(name, observer, useCapture);
            } 
else if (element && element.detachEvent) {
                element.detachEvent(
'on' + name, observer);
            }
        }
        
return foundEntry;
    },
    
    
//清除所有已绑定事件元素的上函数observer
    unloadCache: function() {
        
// check for OpenLayers.Event before checking for observers, because
        // OpenLayers.Event may be undefined in IE if no map instance was
        // created
        if (OpenLayers.Event && OpenLayers.Event.observers) {
            
for (var cacheID in OpenLayers.Event.observers) {
                
var elementObservers = OpenLayers.Event.observers[cacheID];
                OpenLayers.Event._removeElementObservers.apply(
this
                                                           [elementObservers]);
            }
            OpenLayers.Event.observers 
= false;
        }
    },

    CLASS_NAME: 
"OpenLayers.Event"
};

//清除内存,防止泄露
OpenLayers.Event.observe(window, 'unload', OpenLayers.Event.unloadCache, false);

// FIXME: Remove this in 3.0. In 3.0, Event.stop will no longer be provided
//
 by OpenLayers.
if (window.Event) {
    OpenLayers.Util.applyDefaults(window.Event, OpenLayers.Event);
else {
    
var Event = OpenLayers.Event;
}

/**
 * Class: OpenLayers.Events
 
*/
OpenLayers.Events 
= OpenLayers.Class({

   
//浏览器事件常量
    BROWSER_EVENTS: [
        
"mouseover""mouseout",
        
"mousedown""mouseup""mousemove"
        
"click""dblclick""rightclick""dblrightclick",
        
"resize""focus""blur"
    ],

    
//事件监听函数数组
    listeners: null,

    
/*
     * Property: object 
     * {Object}  the code object issuing application events 
     
*/
    object: 
null,

    
//DOM元素
    element: null,

    
//事件类型
    eventTypes: null,

    
//绑定到元素上的事件处理程序
    eventHandler: null,

    
//是否阻止浏览器事件默认行为
    fallThrough: null,

   
//事件对象是否包含.xy属性
    includeXY: false,      

    
//清除鼠标事件处理程序
    clearMouseListener: null,

    
//初始化事件对象
    initialize: function (object, element, eventTypes, fallThrough, options) {
        OpenLayers.Util.extend(
this, options);
        
this.object     = object;
        
this.fallThrough = fallThrough;
        
this.listeners  = {};

        
// keep a bound copy of handleBrowserEvent() so that we can
        // pass the same function to both Event.observe() and .stopObserving()
        this.eventHandler = OpenLayers.Function.bindAsEventListener(
            
this.handleBrowserEvent, this
        );
        
        
// to be used with observe and stopObserving
        this.clearMouseListener = OpenLayers.Function.bind(
            
this.clearMouseCache, this
        );

        
// if eventTypes is specified, create a listeners list for each 
        // custom application event.
        this.eventTypes = [];
        
if (eventTypes != null) {
            
for (var i=0, len=eventTypes.length; i<len; i++) {
                
this.addEventType(eventTypes[i]);
            }
        }
        
        
// if a dom element is specified, add a listeners list 
        // for browser events on the element and register them
        if (element != null) {
            
this.attachToElement(element);
        }
    },

    
//销毁全部事件,并清除内存
    destroy: function () {
        
if (this.element) {
            OpenLayers.Event.stopObservingElement(
this.element);
            
if(this.element.hasScrollEvent) {
                OpenLayers.Event.stopObserving(
                    window, 
"scroll"this.clearMouseListener
                );
            }
        }
        
this.element = null;

        
this.listeners = null;
        
this.object = null;
        
this.eventTypes = null;
        
this.fallThrough = null;
        
this.eventHandler = null;
    },

    
//增加一个事件对象
    addEventType: function(eventName) {
        
if (!this.listeners[eventName]) {
            
this.eventTypes.push(eventName);
            
this.listeners[eventName] = [];
        }
    },

    
//将事件绑定到元素element
    attachToElement: function (element) {
        
if(this.element) {
            OpenLayers.Event.stopObservingElement(
this.element);
        }
        
this.element = element;
        
for (var i=0, len=this.BROWSER_EVENTS.length; i<len; i++) {
            
var eventType = this.BROWSER_EVENTS[i];

            
// every browser event has a corresponding application event 
            // (whether it's listened for or not).
            this.addEventType(eventType);
            
            
// use Prototype to register the event cross-browser
            OpenLayers.Event.observe(element, eventType, this.eventHandler);
        }
        
// disable dragstart in IE so that mousedown/move/up works normally
        OpenLayers.Event.observe(element, "dragstart", OpenLayers.Event.stop);
    },
    
    
//等同register
    on: function(object) {
        
for(var type in object) {
            
if(type != "scope") {
                
this.register(type, object.scope, object[type]);
            }
        }
    },

    
     
//注册一个事件对象
    register: function (type, obj, func) {
        
//判断事件openLayer是否支持事件type
        if ( (func != null&& 
             (OpenLayers.Util.indexOf(
this.eventTypes, type) != -1) ) {
            
//默认为事件对象属性object
            if (obj == null)  {
                obj 
= this.object;
            }
            
var listeners = this.listeners[type];
            listeners.push( {obj: obj, func: func} );
        }
    },

    
//注册一个事件对象,并排在事件队列头部
    registerPriority: function (type, obj, func) {

        
if (func != null) {
            
if (obj == null)  {
                obj 
= this.object;
            }
            
var listeners = this.listeners[type];
            
if (listeners != null) {
                listeners.unshift( {obj: obj, func: func} );
            }
        }
    },
    
    
//等同unregister
    un: function(object) {
        
for(var type in object) {
            
if(type != "scope") {
                
this.unregister(type, object.scope, object[type]);
            }
        }
    },

    
//称除事件对象
    unregister: function (type, obj, func) {
        
if (obj == null)  {
            obj 
= this.object;
        }
        
var listeners = this.listeners[type];
        
if (listeners != null) {
            
for (var i=0, len=listeners.length; i<len; i++) {
                
if (listeners[i].obj == obj && listeners[i].func == func) {
                    listeners.splice(i, 
1);
                    
break;
                }
            }
        }
    },

    
//移除一个事件
    remove: function(type) {
        
if (this.listeners[type] != null) {
            
this.listeners[type] = [];
        }
    },

    
//触发事件
    triggerEvent: function (type, evt) {
        
var listeners = this.listeners[type];

        
// fast path
        if(!listeners || listeners.length == 0) {
            
return;
        }

        
// prep evt object with object & div references
        if (evt == null) {
            evt 
= {};
        }
        evt.object 
= this.object;
        evt.element 
= this.element;
        
if(!evt.type) {
            evt.type 
= type;
        }
    
        
// execute all callbacks registered for specified type
        // get a clone of the listeners array to
        // allow for splicing during callbacks
        var listeners = listeners.slice(), continueChain;
        
for (var i=0, len=listeners.length; i<len; i++) {
            
var callback = listeners[i];
            
// bind the context to callback.obj
            continueChain = callback.func.apply(callback.obj, [evt]);

            
if ((continueChain != undefined) && (continueChain == false)) {
                
// if callback returns false, execute no more callbacks.
                break;
            }
        }
        
// don't fall through to other DOM elements
        if (!this.fallThrough) {           
            OpenLayers.Event.stop(evt, 
true);
        }
        
return continueChain;
    },

    
//事件触发时,获取鼠标位置信息
    handleBrowserEvent: function (evt) {
        
if (this.includeXY) {
            evt.xy 
= this.getMousePosition(evt);
        } 
        
this.triggerEvent(evt.type, evt);
    },

    
     
//清除保留的元素位置信息
    clearMouseCache: function() { 
        
this.element.scrolls = null;
        
this.element.lefttop = null;
        
this.element.offsets = null;
    },      

   
     
//获取鼠标当前位置
    getMousePosition: function (evt) {
        
if (!this.includeXY) {
            
this.clearMouseCache();
        } 
else if (!this.element.hasScrollEvent) {
            OpenLayers.Event.observe(window, 
"scroll"this.clearMouseListener);
            
this.element.hasScrollEvent = true;
        }
        
        
if (!this.element.scrolls) {
            
this.element.scrolls = [
                (document.documentElement.scrollLeft
                         
|| document.body.scrollLeft),
                (document.documentElement.scrollTop
                         
|| document.body.scrollTop)
            ];
        }

        
if (!this.element.lefttop) {
            
this.element.lefttop = [
                (document.documentElement.clientLeft 
|| 0),
                (document.documentElement.clientTop  
|| 0)
            ];
        }
        
        
if (!this.element.offsets) {
            
this.element.offsets = OpenLayers.Util.pagePosition(this.element);
            
this.element.offsets[0+= this.element.scrolls[0];
            
this.element.offsets[1+= this.element.scrolls[1];
        }
        
return new OpenLayers.Pixel(
            (evt.clientX 
+ this.element.scrolls[0]) - this.element.offsets[0]
                         
- this.element.lefttop[0], 
            (evt.clientY 
+ this.element.scrolls[1]) - this.element.offsets[1]
                         
- this.element.lefttop[1]
        ); 
    },

    CLASS_NAME: 
"OpenLayers.Events"
});
原文地址:https://www.cnblogs.com/jenry/p/1755971.html