DOM兼容性及其他小知识乱炖

旧文一篇,2014年发布于前端乱炖中,是当时学习的整理,现在拿过来备份凑个篇数;

文中还有一些兼容性处理,现在已基本用不到了;

DOM

1、DOM操作:大部份兼容,小部份不兼容,可以写兼容;

2、操作DOM元素的属性,如:oBtn.className 等价于 oBtn[“className”] ; 
.后只能放W3C认证或者是在 JS 中动态添加(绑定)过的属性,不能放变量,不能放参数,不能放字符串 
[] 主要用于在属性是变量的情况;

3、关于取样式:

3.1、obj.style.width — 取的是行间样式,所以行间必须要有这个值; 
3.2、obj.offsetWidth — 取的是计算后的宽度,包括边框、padding和去除margin的值; 
同类属性有 offsetHeight / offsetWidth / offsetTop / offsetLeft 
当对象隐藏的时候,用此类属性获取出来为零;用下面的方式则没有此问题:

//取所有样式--行间的/样式表中的,包括系统样式
function getAttrValue(obj, attr){
    if(obj.currentStyle)
    {
        return obj.currentStyle[attr];     //IE支持 currentStyle
    }
    return getComputedStyle(obj,false)[attr];    //Firefox/Chrome 支持
}

*此方法不能取组合样式,如background,可以取默认样式; 
*getComputedStyle(obj, false) 中的第二个参数是为了兼容低版本的Firefox(很低很低);

3.3、obj.style.cssText = “width:200px;height:200px;” 
cssText 可以兼容设置CSS样式,缺点:覆盖行间样式;

4、事件

4.1、取事件对象

obj.onclick = function(ev){
    var oEvent = ev || event;
     //ev   兼容firefox
     //event 兼容IE/Chrome
};
oEvent.clientX / oEvent.clientY:
取鼠标的横纵坐标,不带px,在鼠标事件中经常用到;
oEvent.keyCode:取触发事件的键盘或者鼠标的键值;
oEvent.srcElement:
IE/Chrome 中的事件源(触发事件的元素,在所有事件中通用)
oEvent.target:
FireFox 中的事件源
oEvent.fromElement:
IE/Chrome中的移入源(在鼠标移入移出事件中用到的较多)
oEvent.relatedTarget:
FireFox中的移入源
oEvent.toElement:
IE/Chrome中的移入目标(在鼠标移入移出事件中用到的较多)
oEvent.relatedTarget:
FireFox中的移入目标,和移入源是同一个属性,在用的时候取的到底是那个属性,FireFox会根据事件判断

5、取高度

5.1、document.documentElement.clientHeight :浏览器视口高度,兼容的,不带px 
5.2、document.body.clientHeight :body的高度,兼容的,不带px 
5.3、页面的滚动高度,不带px

//chrome
var scroll=document.body.scrollTop;
//IE/Firefox
var scroll=document.documentElement.scrollTop;

6、父元素

parentNode :DOM结构上的父级 
offsetParent :有定位的父级

//取DOM元素在页面上的绝对位置
function getAbsolutePos(obj){
    var left = 0;
    var top = 0;
    while(obj){
        left += obj.offsetLeft;
        top += obj.offsetTop;
        obj = obj.offsetParent;
    }
    return {left:left, top:top};
}

7、元素操作

7.1、父级.appendChild(子元素) 
父级.insertBefore(插入的子元素, 谁的前面); 
//这两个方法都可以操作已有元素,相当于剪切,原来是属性/事件都存在

7.2、获取元素 
获取第一个子元素 
firstElementChild: Chrome/FF支持 
firstChild: IE支持 
获取最后一个元素:lastElementChild / lastChild 浏览器支持情况同上

获取相邻元素 上一个/下一个 
previousElementSibling:Chrome/FF 支持 
previousSibling: IE支持 
nextElementSibling / nextSibling 浏览器支持情况同上

children:获取该元素的一级子元素

8、事件绑定和解除

oBtn.addEventListener(事件不带on, 执行函数 , false); //非IE678 
oBtn.attachEvent(事件带on, 执行函数) ; //IE678 
oBtn.removeEventListener(事件不带on, 执行函数句柄 , false); //浏览器支持情况如上 
oBtn.detachEvent(事件带on , 执行函数句柄); // 执行函数句柄 == > 函数名

事件绑定中不能用this,因为 IE不兼容; 
可以用此方法给对象绑定多个事件,此种绑定方式和基本的事件不会冲突,如:

function bindEvent(obj, ev, fn){
    if(document.addEventListener){
        obj.addEventListener(ev, fn, false);
    }else{
        obj.attachEvent("on"+ev, fn);
    }
}
window.onload = function(){
    var oBtn = document.getElementById("btn");
    oBtn.onclick = function(){
        alert(1);
    };
    bindEvent(oBtn, "click", show);
    bindEvent(oBtn, "click", show1);
    function show(){
        alert(2);
    }
    function show1(){
        alert(3);
    }
    //结果:1、点击按钮,先弹出1,
    //再依次弹出 2、3(Firefox/Chrome/IE8以上)或者 3、2(IE8及其以下),
};

9、IE独有-事件捕获

obj.setCapture(); 
当执行到此句代码时,整个浏览器的事件都不执行(注:是整个浏览器,F12什么的也都不好使了), 只执行当前事件; 
*此事件只能给对象加,不能给 document 加; 
*obj.releaseCapture(); // 解除IE事件捕获

应用场景:因为是IE独有的,Chrome 和 Firefox没法做兼容,所以应用场景极少,目前只遇到过一个场景,就是在实现DOM元素的拖拽(移动)的时候,元素 onkeydown 时会选中页面的文字,解决方案如下,(详细效果代码会在以后的专栏中整理)

if(moveObj.setCapture){
    moveObj.setCapture();  //IE中屏蔽文字选中
}
return false;  //Firefox 和 Chrome 中阻止文字选中

10、文本框的文本改变事件

用户在文本框或文本域中输入字符或者进行剪切、删除操作等时触发的事件 
oninput:Chrome/Firefox/高版本IE(IE9及其以上)支持 
onpropertychange:IE6及其以上支持,但在 IE9中,剪切、删除不会触发该事件(这应该属于bug)

ECMAScript

1、作用域 
for /if 的作用域是open的!!简直是不可思议,仔细想想,是不是和JS的预解析有关呢?

2、getElementById(id) 最好是document下使用,因为在HTML文档中,id唯一才有意义; 
getElementsByClassName();//FF、Chrome支持,IE8及其以下低版本不支持

3、字符串 
字符串通过下标取某个字符(str[0]),这个是不兼容的(IE7及其以下不支持),使用charAt()这个是兼容的; 
substring(开始位置[,结束位置]) :[开始,结束) 前闭后开,只有一个参数时,截取到末尾; 
substr(开始位置, 长度) :包括开始位置

4、数组 
push(arg1, arg2, ……) 从数组末尾添加,可以有多个参数,返回数组长度; 
unshrift(arg1, arg2); 从前面添加 
pop() 删除最后一项,返回该项(弹出数组的最后一项) 
shift() 删除第一项,返回该项 
concat():arr1.concat(arr2, 2, “3”); // 连接返回新数组   
    实现数组的浅克隆:arr2 = arr1.concat(); //concat() 会返回新数组; 
    如果直接arr2=arr1,会形成指针,两个数组同步 
splice(开始位置,删除长度,要插入的n个值); //这个方法可以实现数组的删除、更新以及插入操作(主要由删除长度控制);插入操作的时候,插入到开始位置的前面

HTML

1、HTML标签中的id是可以包含各种特殊字符和空格的,如果使用 jquery,会受到严重影响–这个基本可以忽略吧,好的代码id中不会出现空格什么的吧;

2、select 标签 
2.1、select 标签有默认 value 值,默认第一个 option 的 value; 
2.2、如果 HTML 标签中没有给 option 设置 value,通过 select.value 取值是不兼容的,具体哪个不兼容,自行测试吧,这个问题基本也可以忽略吧,好的代码中怎么会不给 option 设置 value 呢; 
2.3、取 select 选中值的时候,直接 oSelect.value 即可取到, 
    也可以通过 oSelect.options[oSelect.selectedIndex].value 取得; 
2.4、取选中项的显示文本:oSelect.options[oSelect.selectedIndex].innerHTML ,这个没什么问题; 
    oSelect.options[oSelect.selectedIndex].text 在某些浏览器下,可以通过此种方式取显示的文本值,但是不兼容(如果没记错的话,IE低版本是可以的); 
2.5、创建option : var option = new Option(显示文本,value值); 
2.6、通过selectedIndex不仅可以取选中下标,还可以设置选中下标;

3、CSS问题 
IE6中的 height 相当于 min-height,高度不会固定,会被撑开;(一直没做过专职前端,现在公司IE6考虑的还多么,我觉得该放弃就得放弃,考虑IE6兼容问题的时间,还不如多做做用户体验,学习新的知识)。

4、autocomplete=”off” 文本框不自动填充值;

如果这篇文章对你有用,可以点击下面的按钮告诉我

0

发表回复