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 Select(单选) 模拟插件 V1.3.62 改进版
Jul 17 Javascript
jquery里的each使用方法详解
Dec 22 Javascript
利用jquery操作Radio方法小结
Oct 20 Javascript
Javascript基础教程之argument 详解
Jan 18 Javascript
JS模仿腾讯图片站的图片翻页按钮效果完整实例
Jun 21 Javascript
jquery表单插件Autotab使用方法详解
Jun 24 Javascript
Vue.js系列之项目结构说明(2)
Jan 03 Javascript
JS数组去重(4种方法)
Mar 27 Javascript
xmlplus组件设计系列之选项卡(Tabbar)(5)
May 03 Javascript
开发用到的js封装方法(20种)
Oct 12 Javascript
JS数据类型STRING使用实例解析
Dec 18 Javascript
微信小程序用canvas画图并分享
Mar 09 Javascript
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
在线竞拍系统的PHP实现框架(一)
2006/10/09 PHP
967 个函式
2006/10/09 PHP
CodeIgniter CLI模式简介
2014/06/17 PHP
php实现获取文件mime类型的方法
2015/02/11 PHP
在WordPress中使用wp-cron插件来设置定时任务
2015/12/10 PHP
CI框架入门之MVC简单示例
2016/11/21 PHP
用 JavaScript 迁移目录
2006/12/18 Javascript
Google Map V3 绑定气泡窗口(infowindow)Dom事件实现代码
2013/04/26 Javascript
一个简单的jquery进度条示例
2014/04/28 Javascript
javascript 构造函数方式定义对象
2015/01/02 Javascript
jquery操作复选框checkbox的方法汇总
2015/02/05 Javascript
浅谈轻量级js模板引擎simplite
2015/02/13 Javascript
jQuery Validate插件实现表单强大的验证功能
2015/12/18 Javascript
JavaScript事件处理的方式(三种)
2016/04/26 Javascript
jquery div模态窗口的简单实例
2016/05/28 Javascript
必备的JS调试技巧汇总
2016/07/20 Javascript
bootstrap基础知识学习笔记
2016/11/02 Javascript
微信小程序实战之运维小项目
2017/01/17 Javascript
浅谈js中function的参数默认值
2017/02/20 Javascript
javascript实现文本框标签验证的实例代码
2018/10/14 Javascript
zepto.js 实时监听输入框的方法
2018/12/04 Javascript
js实现鼠标点击页面弹出自定义文字效果
2019/12/24 Javascript
[46:14]VGJ.T vs Liquid 2018国际邀请赛小组赛BO2 第一场 8.19
2018/08/21 DOTA
详解在Python程序中自定义异常的方法
2015/10/16 Python
Python参数解析模块sys、getopt、argparse使用与对比分析
2019/04/02 Python
在python里面运用多继承方法详解
2019/07/01 Python
python matplotlib.pyplot.plot()参数用法
2020/04/14 Python
python使用hdfs3模块对hdfs进行操作详解
2020/06/06 Python
web字体加载方案优化小结
2019/11/29 HTML / CSS
维德科技C#面试题笔试题
2015/12/09 面试题
冰淇淋店创业计划书范文
2013/12/27 职场文书
工业设计专业自荐书
2014/06/05 职场文书
2015元旦主持词开场白和结束语
2014/12/14 职场文书
2015年小班保育员工作总结
2015/05/27 职场文书
海弦WR-800F
2022/04/05 无线电
Apache Kafka 分区重分配的实现原理解析
2022/07/15 Servers