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 相关文章推荐
javascript 年月日联动实现核心代码
Dec 21 Javascript
THREE.JS入门教程(6)创建自己的全景图实现步骤
Jan 25 Javascript
jquery弹出层类代码分享
Dec 27 Javascript
解决json日期格式问题的3种方法
Feb 02 Javascript
JavaScript整除运算函数ceil和floor的区别分析
Apr 14 Javascript
JavaScript返回上一页的三种方法及区别介绍
Jul 04 Javascript
js实现具有高亮显示效果的多级菜单代码
Sep 01 Javascript
需灵活掌握的Bootstrap预定义排版类 你精通吗?
Jun 20 Javascript
VueJs路由跳转——vue-router的使用详解
Jan 10 Javascript
webuploader分片上传的实现代码(前后端分离)
Sep 10 Javascript
Vue使用watch监听一个对象中的属性的实现方法
May 10 Javascript
浅析Vue下的components模板使用及应用
Nov 27 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 广告调用类代码(支持Flash调用)
2011/08/11 PHP
php中使用exec,system等函数调用系统命令的方法(不建议使用,可导致安全问题)
2012/09/07 PHP
下拉列表多级联动dropDownList示例代码
2013/06/27 PHP
php 在线导入mysql大数据程序
2015/06/11 PHP
PHP中如何使用session实现保存用户登录信息
2015/10/20 PHP
php读取torrent种子文件内容的方法(测试可用)
2016/05/03 PHP
项目中应用Redis+Php的场景
2016/05/22 PHP
jQuery学习基础知识小结
2010/11/25 Javascript
jQuery提示效果代码分享
2014/11/20 Javascript
JS显示下拉列表框内全部元素的方法
2015/03/31 Javascript
jQuery中dom元素上绑定的事件详解
2015/04/24 Javascript
轻量级的原生js日历插件calendar.js使用指南
2015/04/28 Javascript
一个用jquery写的判断div滚动条到底部的方法【推荐】
2016/04/29 Javascript
node错误处理与日志记录的实现
2018/12/24 Javascript
js如何获取访问IP、地区、当前操作浏览器
2019/07/23 Javascript
基于canvasJS在PHP中制作动态图表
2020/05/30 Javascript
JavaScript构造函数原理及实现流程解析
2020/11/19 Javascript
[37:22]DOTA2上海特级锦标赛D组资格赛#2 Liquid VS VP第一局
2016/02/28 DOTA
Python构建网页爬虫原理分析
2017/12/19 Python
pycharm运行和调试不显示结果的解决方法
2018/11/30 Python
python rsa实现数据加密和解密、签名加密和验签功能
2019/09/18 Python
python 使用while循环输出*组成的菱形实例
2020/04/12 Python
美国一家著名的儿童鞋制造商:Stride Rite
2017/01/02 全球购物
个性化皮包、小袋、生活配件:Mon Purse
2019/03/26 全球购物
Loreto Gallo英国:欧洲领先的在线药房
2021/01/21 全球购物
在DELPHI中调用存储过程和使用内嵌SQL哪种方式更好
2016/11/22 面试题
档案检查欢迎词
2014/01/13 职场文书
人事文员岗位职责
2014/02/16 职场文书
餐厅采购员岗位职责
2014/03/06 职场文书
初三学习决心书
2014/03/11 职场文书
事业单位绩效考核实施方案
2014/03/27 职场文书
报考公务员诚信承诺书
2014/08/29 职场文书
学生检讨书怎么写?
2014/10/10 职场文书
中学生社区服务活动报告
2015/02/05 职场文书
三八节活动简报
2015/07/20 职场文书
python中pd.cut()与pd.qcut()的对比及示例
2022/06/16 Python