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

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);
    },
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值