原生js实现jQuery的功能 height()方法实现(一)
2018-01-11 17:40
971 查看
jquery好比一把锋利的匕首,用的好能让你效率倍增,用的不好能让你反受其害。
最近公司的产品出现了严重的内存泄漏,经过分析是jquery造成的,可能不是jquery本身造成,但jquery的存在导致程序员的事件滥用,dom操作过于频繁,而且jquery+iframe特别是嵌套iframe时,那内存泄漏就是杠杠的了。
痛定思痛之后,公司决定了去掉jquery的依赖,对公司的组件和产品界面进行全面的改造,自然需要用原生js来实现jquery里面常用的一些方法。
今天我们介绍下height()方法的实现。
(一)如果存在行内样式
如果html代码是
发现
(二)如果不存在行内样式,而是定义在css文件中
如果html代码是
则结果并不相等了
那就改成如果行内样式中获取高度为0时则从css中获取吧
(三)如果class中也没定义height样式,ie中会输出auto,需要计算
以为大功告成,欣喜的开始使用,谁知道html代码如果写成下面这种方式,在ie上又不好使了
会发现输出结果是:
只能通过offsetHeight从新计算,注意jquery里面获取的高度是不包含边框和padding的 所以需要通过offsetHeight来减去相应的边框和边距。
以为大功告成,那就大错特错了,如果html代码是这样的
结果是:
(四)元素是display:none,需要设置显示后再进行获取高度
思路还是比较简单就是把元素显示出来,计算出高度后,再将元素隐藏。
(五)最终代码应该如下:
最近公司的产品出现了严重的内存泄漏,经过分析是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); },
相关文章推荐
- 原生js实现jQuery的功能 width()方法实现 (二)
- 原生js实现jQuery的功能 show()方法实现 (三)
- jquery.cookie.js实现用户登录保存密码功能的方法
- JS原生方法实现jQuery的ready()
- 原生js实现jquery的getJSON方法
- 原生JS取代一些JQuery方法的简单实现
- js原生方式实现jquery中的append()方法
- JavaScript之JS原生方法实现jQuery的ready()
- JS原生方法实现jQuery的ready()
- 利用原生js和jQuery实现单选框的勾选和取消操作的方法
- jquery全选/全不选/反选另一种实现方法(配合原生js)
- JS原生方法实现jQuery的ready()
- 原生js实现复制对象、扩展对象 类似jquery中的extend()方法
- 【JS】怎样用原生JS实现jQuery的ready方法
- 【笔记】js原生方法 在元素外部或内部实现添加元素功能(类似jq 的 insert 和 append)
- JS原生方法实现jQuery的ready()
- 习惯了使用jQuery的ajax方法,看看原生js使用xmlhttpRequest实现ajax请求
- 原生JS和jQuery版实现文件上传功能
- 使用原生JS实现jQuery的addClass, removeClass, hasClass函数功能
- JavaScript Tag标签切换实现的几种方法 原生js + jquery