您的位置:首页 > Web前端 > JQuery

原生js实现jQuery的功能 height()方法实现(一)

2018-01-11 17:40 971 查看
jquery好比一把锋利的匕首,用的好能让你效率倍增,用的不好能让你反受其害。

最近公司的产品出现了严重的内存泄漏,经过分析是jquery造成的,可能不是jquery本身造成,但jquery的存在导致程序员的事件滥用,dom操作过于频繁,而且jquery+iframe特别是嵌套iframe时,那内存泄漏就是杠杠的了。

痛定思痛之后,公司决定了去掉jquery的依赖,对公司的组件和产品界面进行全面的改造,自然需要用原生js来实现jquery里面常用的一些方法。

今天我们介绍下height()方法的实现。

(一)如果存在行内样式

如果html代码是

<div id="box" class="test" style="height:100px">
1111111
</div>


发现

$("#box").height()=document.getElementById("box").style.height;//输出都是100px


(二)如果不存在行内样式,而是定义在css文件中

如果html代码是

<style type="text/css">
#box{
height:100px;
}
</style>

<div id="box" class="test">
1111111
</div>


则结果并不相等了

$("#box").height()//输出100px;
document.getElementById("box").style.height;//则是空咯 因为这种方式只能从行内样式获取对应的值


那就改成如果行内样式中获取高度为0时则从css中获取吧

_getStyleValue:function(elObj,attr){
elObj = GoingUtils.getElObj(elObj);
if(elObj.currentStyle){      //IE
return elObj.currentStyle[attr];
}else{
return getComputedStyle(elObj)[attr];     //Firefox
}
}
parseFloat(GoingUtils._getStyleValue(elObj,"height"));


(三)如果class中也没定义height样式,ie中会输出auto,需要计算

以为大功告成,欣喜的开始使用,谁知道html代码如果写成下面这种方式,在ie上又不好使了

<style type="text/css">
.test{
background-color: #FF0;padding:100px;border:100px solid #023456;
}
</style>

<div id="box" class="test">
1111111
</div>


会发现输出结果是:

$("#box").height(); //输出21
而
GoingUtils._getStyleValue(elObj,"height") //输出是auto


只能通过offsetHeight从新计算,注意jquery里面获取的高度是不包含边框和padding的 所以需要通过offsetHeight来减去相应的边框和边距。

var borderTopWidth = GoingUtils._getStyleValue(elObj, "borderTopWidth");
var borderBottomWidth = GoingUtils._getStyleValue(elObj, "borderBottomWidth");
var paddingTop = GoingUtils._getStyleValue(elObj, "paddingTop");
var paddingBottom = GoingUtils._getStyleValue(elObj, "paddingBottom")
var backHeight = parseFloat(elObj.offsetHeight) - parseFloat(borderTopWidth) - parseFloat(borderBottomWidth) - parseFloat(paddingTop) - parseFloat(paddingBottom);
return parseFloat(backHeight);


以为大功告成,那就大错特错了,如果html代码是这样的

<style type="text/css">
.test{
background-color: #FF0;padding:100px;border:100px solid #023456;display: none;
}
</style>

<div id="box" class="test">
1111111
</div>


结果是:

$("#box").height()//输出21
而原生的js获取到的还是0


(四)元素是display:none,需要设置显示后再进行获取高度

思路还是比较简单就是把元素显示出来,计算出高度后,再将元素隐藏。

(五)最终代码应该如下:

_getStyleValue:function(elObj,attr){
elObj = GoingUtils.getElObj(elObj);

var view = elObj.ownerDocument.defaultView;
if (!view || !view.opener) {
view = window;
}

if(elObj.currentStyle){      //IE
return elObj.currentStyle[attr];
}else{
return view.getComputedStyle(elObj)[attr];     //Firefox
}
},
isShow: function (elObj) {
elObj = GoingUtils.getElObj(elObj);
var display = GoingUtils._getStyleValue(elObj, 'display');
if (display === 'none') {
return false;
} else {
return true;
}
},
//获取某个元素的高度
getElHeight: function (elObj) {
//如果传入的不是对象是字符串 则通过字符串转换成对象
elObj = GoingUtils.getElObj(elObj);
if (elObj != null&&GoingUtils.isShow(elObj)) {
//从style中获取对应的高度
if (elObj.style.height != null && elObj.style.height.length > 0) {
return parseFloat(elObj.style.height);
}
//如果elObj.style.height为空  则从css里面获取是否定义了height信息如果定义了 则读取css里面定义的高度height
if(parseFloat(GoingUtils._getStyleValue(elObj,"height"))>0) {
return parseFloat(GoingUtils._getStyleValue(elObj,"height"));
}

//如果从css里获取到的值不是大于0  可能是auto 则通过offsetHeight来进行计算
if (elObj.offsetHeight > 0) {
var borderTopWidth = GoingUtils._getStyleValue(elObj, "borderTopWidth");
var borderBottomWidth = GoingUtils._getStyleValue(elObj, "borderBottomWidth");
var paddingTop = GoingUtils._getStyleValue(elObj, "paddingTop");
var paddingBottom = GoingUtils._getStyleValue(elObj, "paddingBottom")
var backHeight = parseFloat(elObj.offsetHeight) - parseFloat(borderTopWidth) - parseFloat(borderBottomWidth) - parseFloat(paddingTop) - parseFloat(paddingBottom);
return parseFloat(backHeight);
}
return 0;
} else {
//将元素显示出来 获取高度 再将元素隐藏掉
GoingUtils.attrEl(elObj,'style',"visibility:hidden;display:block !important;");
var height=GoingUtils.getElHeight(elObj);
elObj.removeAttribute('style');
return height;
}
return parseFloat(elObj.style.height);
},
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: