博客 - 标签:兼容性

补习:跨平台的javascript事件

2010-03-20 下午 - JS/Ajax/AS - -

javascript的事件模型有三种:netscape、IE、W3C/Safari。

事件流又分冒泡型事件和捕获型事件。主要的浏览器代表是netscape、IE7及以下版本。

DOM事件流:同时支持冒泡型事件和捕获型事件。火狐、Safari、IE8等支持DOM事件流的浏览器。

以下内容仅以IE和火狐作为代表进行对比及处理。

添加、移除事件:

IE

oTarget.attachEvent("on" + sEventType, fnHandler);

oTarget.detachEvent("on" + sEventType, fnHandler);

火狐:

oTarget.addEventListener(sEventType, fnHandler, false);

oTarget.removeEventListener(sEventType, fnHandler, false);

解决方法:

function addEventHandler(oTarget, sEventType, fnHandler){
    
if(oTarget.addEventListener){
        
oTarget.addEventListener(sEventType,fnHandler,false);
    
}else if(oTarget.attachEvent){
        
oTarget.attachEvent("on" + sEventType,fnHandler);
    
}else{
        
oTarget["on" + sEventType]=fnHandler;
    
}
}
function removeEventHandler(oTarget, sEventType, fnHandler){
    
if(oTarget.removeEventListener){
        
oTarget.removeEventListener(sEventType,fnHandler,false);
    
}else if(oTarget.detachEvent){
        
oTarget.detachEvent("on" + sEventType,fnHandler);
    
}else{
        
oTarget["on" + sEventType]=null;
    
}
}

获取事件对象:

IE

IE中,事件对象是window对象的一个属性event。

window.event

火狐:

DOM标准中,event对象必须作为唯一参数传给事件处理函数。

arguments[0] 或者 直接传入参数

解决方法:

function getEvent(){
    
if(window.event){
        
return window.event;
    
}else{
        
return getEvent.caller.arguments[0];
    
}
}

注:针对火狐的方法请参考 JavaScript 获取事件对象的一个注意点

获取事件属性:

相同处:

  1. 获取事件类型(名称):oEvent.type
  2. 获取按键代码(keydown/keyup事件):oEvent.keyCode
  3. 检测是否按下了Shift、Alt、Ctrl键:oEvent.shiftKey、oEvent.altKey、oEvent.ctrlKey
  4. 获取客户端鼠标事件坐标:oEvent.clientX、oEvent.clientY
  5. 获取鼠标距屏幕边沿坐标:oEvent.screenX、oEvent.screenY

不同处:

  1. 获取目标(事件源):

    IE:oEvent.srcElement

    火狐:oEvent.target

  2. 获取字符代码:

    IE:oEvent.keyCode

    火狐:oEvent.charCode

  3. 阻止事件发生:

    IE:oEvent.returnValue = false

    火狐:oEvent.preventDefault()

  4. 停止事件冒泡:

    IE:oEvent.cancelBubble = true

    火狐:oEvent.stopPropagation()

  5. 还有一些属性仅有火狐支持,比如eventPhase、isChar、pageX、pageY、

解决方法:

function formatEvent(oEvent){
    
if (isIE && isWin) {
        
oEvent.charCode = (oEvent.type == "keypress") ? oEvent.keyCode : 0;
        
oEvent.eventPhase = 2;
        
oEvent.isChar = (oEvent.charCode > 0);
        
oEvent.pageX = oEvent.clientX + document.body.scrollLeft;
        
oEvent.pageY = oEvent.clientY + document.body.scrollTop;
        
oEvent.preventDefault = function () {
            
this.returnValue = false;
        
};
        
if (oEvent.type == "mouseout") {
            
oEvent.relatedTarget = oEvent.toElement;
        
} else if (oEvent.type == "mouseover") {
            
oEvent.relatedTarget = oEvent.fromElement;
        
}
        
oEvent.stopPropagation = function () {
            
this.cancelBubble = true;
        
};
        
oEvent.target = oEvent.srcElement;
        
oEvent.time = (new Date).getTime();
    
}
    
return oEvent;
}

最后综合起来,EventUtil对象封装起来,就很好的解决了事件的跨平台兼容了。下载:eventutil.js

此文中涉及到的浏览器检测功能,超出了本文的范围,略过!detect.js 提供代码方便下载测试。

本文参考自《javascript高级程序设计》,详细可翻阅该书籍。

1 Comment »

也来说说inline-block

2009-05-7 下午 - html/css/xml/xsl - -

先看看demo,有了inline-block,就可以某种程度上代替了float啦!

支持的:FF3、IE8、Safari、Opera、Chrome

未支持的:IE6、IE7、FF2

下面我们就一一来解决它。

解决FF2:display: -moz-inline-stack 由于FF2未与display:inline-block“达成共识”!但有这一私有属性能顶顶也不错。

解决IE系列:display:inline 针对IE系列,切记需要触发layout,这里使用的是zoom:1。IE7下需要单独设置该值为inline,那么利用星号Hack干掉它!

至此这3个浏览器的兼容性得到解决,可惜的是,直接用于项目里是不放心的,等待着IE8的普及吧!不过及早的了解它未尝不是一桩妙事!

最后总结一下:

.box{
display: -moz-inline-stack; /* FF2 */
display:inline-block;
*display:inline; /* IE7 */
zoom:1; /* IE系列*/
vertical-aligntop;
width:auto的值;
height:auto的值;
}

推荐阅读:

模拟兼容性的 inline-block 属性

跨浏览器的inline-block

No Comments »

预留退路+分离javascript+向后兼容性

2008-12-15 下午 - JS/Ajax/AS - - - -

  谈谈这两天学到的一些新东西,就算是做个记录,自己也好随时来看看,增强记忆;同时也让喜欢js的朋友们也多了解一些有用的东西。

  1. 预留退路:确保网页在没有JavaScript的情况下也能正常工作。
  2. 分离JavaScript:把网页的结构和内容与JavaScript脚本的动作行为分开。
  3. 向后兼容性:确保老版本的浏览器不会因为你的JavaScript脚本而死机。

  其实这些东西说来说去也就是一条:养成良好的JavaScript编程习惯(事实上也并非一件简单的事)。

  预留退路,如果你正确地给JavaScript考虑了“退路”问题,就可以让用户在浏览器不支持或已关闭JavaScript的情况下也能够顺利浏览到原本该有的信息(虽然某些功能不可用,但至少保证内容是可见的)。

  分离javascript:顾名思义,就是将js脚本完完全全的迁移出html/xhtml文档,这样做是只有利而无弊的。可能在某些程度上会使得js脚本变得稍显复杂,但这些都是可以接受的。

  向后兼容性:现在,绝大多数的浏览器都能或多或少的支持JavaScript,同时对DOM的支持也都是很不错滴。但还是存在一些比较古老的浏览器,而正好它们却有可能无法理解DOM提供的方法和属性。解决方法比较容易实现,通过if语句,判断出结果从而选择该采取怎样的行动——这种检测叫做对象检测(object detection)。

  由于时间关系,该文章未提及解决方法的具体案例,网上有很多类似的例子可以查阅的,多多利用Google和百度吧!

1 Comment »