js获取隐藏元素宽高的实现方法


Posted in Javascript onMay 19, 2016

网上有一些js获取隐藏元素宽高的方法,但是可能会存在某些情况获取不了。

例如:

<!DOCTYPE html>
<html lang="en">
<head>
  <meta http-equiv="Content-Type" content="text/html;charset=UTF-8" />
  <title>test</title>
</head>
<body>
<div id="test" style="display:none">
   我有一壶酒,足以慰风尘。尽倾江海里,赠饮天下人。
</div>
<div id="test2" style="display:none">
   <div style="display:none">
     <div id="test2_child">
        我有一壶酒,足以慰风尘。尽倾江海里,赠饮天下人。
     </div>
   </div>
</div>
<div id="test3">
   <div>
     <div id="test3_child">
        我有一壶酒,足以慰风尘。尽倾江海里,赠饮天下人。
     </div>
   </div>
</div>
</div>
</body>
</html>

test获取得了,但是test2_child是获取不到的。鉴于这种情况,于是自己写了一个方法解决。

解决思路:

1. 获取元素(拿宽高那个)所有隐藏的祖先元素直到body元素,包括自己。

2. 获取所有隐藏元素的style的display、visibility 属性,保存下来。

3. 设置所有隐藏元素为 visibility:hidden;display:block !important;(之所以要important是避免优先级不够)。

4. 获取元素(拿宽高那个)的宽高。

5. 恢复所有隐藏元素的style的display、visibility 属性。

6. 返回元素宽高值。

代码实现:

function getSize(id){
   var width,
     height,
     elem = document.getElementById(id),
     noneNodes = [],
     nodeStyle = [];
   getNoneNode(elem); //获取多层display:none;的元素
   setNodeStyle();
   width = elem.clientWidth;
   height = elem.clientHeight;
   resumeNodeStyle();
  
   return {
     width : width,
     height : height
   }

   function getNoneNode(node){
     var display = getStyles(node).getPropertyValue('display'),
        tagName = node.nodeName.toLowerCase();
     if(display != 'none'
        && tagName != 'body'){
        getNoneNode(node.parentNode);
     } else {
        noneNodes.push(node);
        if(tagName != 'body')
          getNoneNode(node.parentNode);
     }
   }
  
   //这方法才能获取最终是否有display属性设置,不能style.display。
   function getStyles(elem) {

     // Support: IE<=11+, Firefox<=30+ (#15098, #14150)
     // IE throws on elements created in popups
     // FF meanwhile throws on frame elements through "defaultView.getComputedStyle"
     var view = elem.ownerDocument.defaultView;

     if (!view || !view.opener) {
        view = window;
     }
     return view.getComputedStyle(elem);
   };
  
  
   function setNodeStyle(){
     var i = 0;
     for(; i < noneNodes.length; i++){
        var visibility = noneNodes[i].style.visibility,
        display = noneNodes[i].style.display,
        style = noneNodes[i].getAttribute("style");
        //覆盖其他display样式
        noneNodes[i].setAttribute("style", "visibility:hidden;display:block !important;" + style);
        nodeStyle[i] = {
          visibility :visibility,
          display : display
        }
     }       
   }
  
   function resumeNodeStyle(){
     var i = 0;
     for(; i < noneNodes.length; i++){
        noneNodes[i].style.visibility = nodeStyle[i].visibility;
        noneNodes[i].style.display = nodeStyle[i].display;
     }  

   }
}

例子演示:

var testSize = getSize('test');
console.log("test-> width:" + testSize.width + " height:" + testSize.height);

var test2ChildSize2 = getSize('test2_child');
console.log("test2Child2-> width:" + test2ChildSize2.width + " height:" + test2ChildSize2.height);

var test3ChildSize = getSize('test3_child');
console.log("test3_child-> width:" + test3ChildSize.width + " height:" + test3ChildSize.height);   
 
//打印值如下
test-> width:417 height:18
test2Child2-> width:417 height:18
test3_child-> width:417 height:18

注意事项:

1. 打开显示所有隐藏祖先元素,然后获取元素的宽高值,可能在某些情况下获取值是不正确的。

PS:不过这个不用担心,真正出错时再hack方法就行。

2. 之所以要保存隐藏祖先元素display、visibility 属性,是为了后面可以设置回来,不影响其本身。

3. 另外getStyles方法是从jquery源码中摘取出来,这方法才能获取最终是否有display属性设置。

PS:不能从style.display获取。

以上这篇js获取隐藏元素宽高的实现方法就是小编分享给大家的全部内容了,希望能给大家一个参考,也希望大家多多支持三水点靠木。

Javascript 相关文章推荐
jquery单行文字向上滚动效果示例
Mar 06 Javascript
原生javascript实现隔行换色
Jan 04 Javascript
js实现带按钮的上下滚动效果
May 12 Javascript
jQuery实现简单的图片查看器
Sep 11 Javascript
JavaScript仿商城实现图片广告轮播实例代码
Feb 06 Javascript
jQuery获取radio选中项的值实例
Jun 18 Javascript
AngularJS中比较两个数组是否相同
Aug 24 Javascript
JS 实现banner图片轮播效果(鼠标事件)
Aug 04 Javascript
Bootstrap实现翻页效果
Nov 27 Javascript
JavaScript定时器常见用法实例分析
Nov 15 Javascript
详解JavaScript之ES5的继承
Jul 08 Javascript
Vue用mixin合并重复代码的实现
Nov 27 Vue.js
jquery实现无刷新验证码的简单实例
May 19 #Javascript
AngularJs解决跨域问题案例详解(简单方法)
May 19 #Javascript
JavaScript:Array类型全面解析
May 19 #Javascript
JavaScript:Date类型全面解析
May 19 #Javascript
javascript中对Date类型的常用操作小结
May 19 #Javascript
JS Attribute属性操作详解
May 19 #Javascript
jQuery点击输入框显示验证码图片
May 19 #Javascript
You might like
如何将数据从文本导入到mysql
2006/10/09 PHP
PHP字符转义相关函数小结(php下的转义字符串)
2007/04/12 PHP
在php和MySql中计算时间差的方法
2011/04/22 PHP
深入apache配置文件httpd.conf的部分参数说明
2013/06/28 PHP
Linux编译升级php的详细方法
2013/11/04 PHP
PHP队列用法实例
2014/11/05 PHP
php的闭包(Closure)匿名函数初探
2016/02/14 PHP
搜索附近的人PHP实现代码
2018/02/11 PHP
取消选中单选框radio的三种方式示例介绍
2013/12/23 Javascript
JavaScript实现网页加载进度条代码超简单
2015/09/21 Javascript
jQuery的ajax下载blob文件
2016/07/21 Javascript
利用jquery去掉时光轴头尾部线条的方法实例
2017/06/16 jQuery
Vue实现动态创建和删除数据的方法
2018/03/17 Javascript
浅谈Node.js 沙箱环境
2018/05/15 Javascript
vue中使用vee-validator完成表单校验方案
2019/11/01 Javascript
[00:02]DOTA2新版本使用PA至宝后暴击展示
2014/11/19 DOTA
用python实现的去除win下文本文件头部BOM的代码
2013/02/10 Python
Python urllib、urllib2、httplib抓取网页代码实例
2015/05/09 Python
python读取word文档的方法
2015/05/09 Python
将Emacs打造成强大的Python代码编辑工具
2015/11/20 Python
python使用正则表达式替换匹配成功的组并输出替换的次数
2017/11/22 Python
Python匿名函数/排序函数/过滤函数/映射函数/递归/二分法
2019/06/05 Python
django框架model orM使用字典作为参数,保存数据的方法分析
2019/06/24 Python
Django 模型类(models.py)的定义详解
2019/07/19 Python
Python爬取腾讯视频评论的思路详解
2019/12/19 Python
Python3.7+tkinter实现查询界面功能
2019/12/24 Python
HTML+CSS3模拟心的跳动实例代码
2017/09/05 HTML / CSS
详解使用双缓存解决Canvas clearRect引起的闪屏问题
2019/04/29 HTML / CSS
意大利宠物用品购物网站:Bauzaar
2018/09/15 全球购物
墨尔本最受欢迎的复古风格品牌:Princess Highway
2018/12/21 全球购物
美国球迷装备的第一来源:FOCO
2020/07/03 全球购物
Ruby如何定义一个类
2012/10/08 面试题
优秀高中生事迹材料
2014/02/11 职场文书
幼儿园优秀班主任事迹材料
2014/05/14 职场文书
婚礼秀策划方案
2014/05/19 职场文书
2016年第十九届推普周活动总结
2016/04/06 职场文书