ADS4.5 响应用户操作和事件——跨浏览器的事件属性和方法

前端技术 everyinch 2571℃ 0评论

DOM2级事件对象的继承关系如下图所示:
blog_dom2Event
下面看一看Event和MouseEvent对象的属性,并介绍通过这些属性可以获得哪些信息。

1. DOM2事件规范中的Event对象

事件对象中包含着用于控制事件流和目标对象的方法和属性。包括:
□ bubbles:布尔值,表示是否是冒泡阶段
□ cancelable:布尔值,表示事件是否具有可以取消的默认动作
□ currentTarget:当前正在处理的DOM元素
□ target:最早调用事件序列的对象(EventTarget对象的实例)
□ timestamp:DOMTimeStamp对象,用来确定创建事件后的毫秒数
□ type:包含事件名称(例如click)的字符串
□ eventPhase:表示处于事件流的阶段,使用1-3的整数来表示,也可以使用Event常量CAPTURE_PHASE、AT_TARGET和BUBBLING_PHASE。如下所示:

function eventListener(W3CEvent) {
    switch(W3CEvent.eventPhase) {
        case Event.CAPTURING_PHASE:
            //code to run if in the capturing phase
            break;
        case Event.AT_TARGET:
            //code to run if this is the target
            break;
        case Event.BUBBLING_PHASE:
            //code to run if in the bubbling phase
            break;
    }
}

还可以根据事件的阶段使用target或currentTarget属性:

function eventListener(W3CEvent) {
    window.open(W3CEvent.currentTarget.href);
    W3CEvent.preventDefault();
}
var anchor = document.getElementById('example');
anchor.addEventListener('click',eventListener,false);

W3C也定义了下列Event对象的方法:
□ initEvent(eventType,canBubble,cancelable):初始化通过document.createEvent(‘Event’)方法创建的事件对象
□ preventDefalt():取消对象的默认动作
□ stopPropagation():停止事件流的进一步执行

2. DOM2事件规范定义的MouseEvent对象

对于所有的W3C DOM鼠标事件而言,传递到事件侦听器中的事件对象都是MouseEvent对象的实例。MouseEvent对象的属性如下:
□ altKey、ctrlKey和shiftKey:布尔值,表示是否按住Alt、Ctrl或Shift键
□ button:表示鼠标键的整数值。0表示鼠标左键,1表示鼠标中键(如果有),2表示鼠标右键。例如:

if(W3CEvent.button==0) {
    // 单击左键的代码
}

或者使用常量:

if(W3CEvent.button==MouseEvent.BUTTON_LEFT) {
    // 单击左键的代码
}

□ clientX和clientY:表示事件发生位置相对于浏览器窗口的水平和垂直坐标。例如:

document.addEventListener('click',function(W3CEvent) {
    alert('client: (' + W3CEvent.clientX + ',' + W3CEvent.clientY + ')');
},false);

下图展示了滚动网页前后clientX和clientY表示的位置:
blog_clientXY
□ screenX和screenY:表示事件发生位置相对于屏幕的水平和垂直坐标。下图展示了screenX和screenY表示的位置:
blog_screenXY
□ relatedTarget:引用与事件相关的“次要目标”。在多数情况下,这个属性值是null,但在mouseover事件中,它引用的是鼠标离开的前一个对象;同样,在mouseout事件中,它引用的是鼠标之前进入的那个对象。

3. 处理诸多浏览器不兼容问题

访问事件的目标元素:IE没有提供target和currentTarget属性,但却提供了srcElement属性。对于Safari而言,文本节点会代替包含它的元素节点变成事件的目标对象。要解决这些问题,添加自定义的ADS.getTarget()方法:

/**
 * 访问事件的目标元素
 */
function getTarget(eventObject) {
    eventObject = eventObject || getEventObject(eventObject);
    // 如果是W3C或MSIE模型
    var target = eventObject.target || eventObject.scrElement;
    // 如果是Safari,则将目标对象指定为文本节点的父元素
    if(target.nodeType == ADS.node.TEXT_NODE) {
        target = node.parentNode;
    }
    return target;

}
window['ADS']['getTarget'] = getTarget;

通过这个方法可以取得给定事件的目标:

ADS.addEvent(window, 'load', function() { 
    function eventListener(W3CEvent) {
        //取得目标
        var target = ADS.getTarget(W3CEvent);
        window.open(target.href);
    }
    var anchor = document.getElementById('example');
    addEvent(anchor, 'click', eventListener);
});

确定单击了鼠标哪个键:W3C规定:
□ 0表示按下了左键
□ 1表示按下了中键
□ 2表示按下了右键
Microsoft的规定如下:
□ 0表示没有按下任何键
□ 1表示按下左键
□ 2表示按下右键
□ 3表示同时按下了左右键
□ 4表示按下了中键
□ 5表示同时按下了左中键
□ 6表示同时按下了右中键
□ 7表示同时按下了所有三个键
解决这个不兼容问题的方法是:检测事件具有toString()方法并且返回的是MouseEvent,那么考虑使用W3C的方式;否则如果仍然存在button属性,那就可以假设是IE了。现在添加自定义的ADS.getMouseButton()方法:

/**
 * 确定按下了鼠标哪个键
 */
function getMouseButton(eventObject) {
    eventObject = eventObject || getEventObject(eventObject);
    // 初始化一个对象变量
    var buttons = {
        'left':false,
        'middle':false,
        'right':false
    };
    // 检查eventObject对象的toString()方法的值
    // W3C DOM对象有toString方法而且返回值为MouseEvent
    if(eventObject.toString && eventObject.toString().indexOf('MouseEvent') != -1) {
        // W3C方法
        switch(eventObject.button) {
            case 0: buttons.left = true; break;
            case 1: buttons.middle = true; break;
            case 2: buttons.right = true; break;
            default: break;
        }
    } else if(eventObject.button) {
        // MSIE方法
        switch(eventObject.button) {
            case 1: buttons.left = true; break;
            case 2: buttons.right = true; break;
            case 3:
                buttons.left = true;
                buttons.right = true;
            break;
            case 4: buttons.middle = true; break;
            case 5:
                buttons.left = true;
                buttons.middle = true;
            break;
            case 6:
                buttons.middle = true;
                buttons.right = true;
            break;
            case 7:
                buttons.left = true;
                buttons.middle = true;
                buttons.right = true;
            break;
            default: break;
        }
    } else {
        return false;
    }
    return buttons;

}
window['ADS']['getMouseButton'] = getMouseButton;

处理鼠标的位置:虽然W3C和IE都定义了clientX和clientY鼠标,但它们在确定滚动后的位移属性时却不相同。W3C使用document.documentElement.scrollTop,而IE则使用document.body.scrollTop。对于Safari而言,它把位置信息放在了事件的pageX和pageY属性中。下面的ADS.getPointerPositionInDocument()方法一并处理了这些情况:

/**
 * 取得鼠标指针在文档中的位置
 */
function getPointerPositionInDocument(eventObject) {
    eventObject = eventObject || getEventObject(eventObject);
    var x = eventObject.pageX || (eventObject.clientX +
        (document.documentElement.scrollLeft || document.body.scrollLeft));
    var y= eventObject.pageY || (eventObject.clientY +
        (document.documentElement.scrollTop || document.body.scrollTop));
    //相对于文档原点的坐标
    return {'x':x,'y':y};
}
window['ADS']['getPointerPositionInDocument'] = getPointerPositionInDocument;

有了ADS.getPointerPositionInDocument()方法,就可以通过mousemove事件让一个元素跟随鼠标指针移动:

ADS.addEvent(window,'load',function() {

    // 取得要移动的对象
    var object = document.getElementById('follow');
    
    // 绝对定位
    object.style.position = 'absolute';
    
    // 事件侦听器
    function eventListener(W3CEvent) {
        var pointer = ADS.getPointerPositionInDocument(W3CEvent);
    
        // 相对于鼠标指针来定位对象
        object.style.left = pointer.x + 'px';
        object.style.top = pointer.y + 'px';
    
    }
    // 在document上注册事件侦听器
    ADS.addEvent(document,'mousemove',eventListener);    
});

效果演示

4. 访问键盘命令

可以通过事件对象的keyCode属性取得按键的Unicode值。添加到ADS库中的ADS.getKeyPressed()方法,可以通过它取得按键代码及相关的ASCII值:

/**
 * 从事件对象中取得按键值
 */
function getKeyPressed(eventObject) {
    eventObject = eventObject || getEventObject(eventObject);
    var code = eventObject.keyCode;
    var value = String.fromCharCode(code);
    return {'code':code,'value':value};
}
window['ADS']['getKeyPressed'] = getKeyPressed;

通过这个方法就可以确定在键盘事件中按下的键了。例如:

ADS.addEvent(document, 'keydown', function(W3CEvent) {
    var key = ADS.getKeyPressed(W3CEvent);
    ADS.log.write(key.code + ':' + key.value);
});


转载请注明:陈童的博客 » ADS4.5 响应用户操作和事件——跨浏览器的事件属性和方法

喜欢 (0)
发表我的评论
取消评论

表情

Hi,您需要填写昵称和邮箱!

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址

无觅相关文章插件,快速提升流量