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 相关文章推荐
AJAX分页的代码(后台asp.net)
Feb 14 Javascript
Javascript中克隆一个数组的实现代码
Dec 06 Javascript
Javascript中级语法快速入手
Jul 30 Javascript
javascript 动态样式添加的简单实现
Oct 11 Javascript
jQuery使用方法
Feb 04 Javascript
JS字符串false转boolean的方法(推荐)
Mar 08 Javascript
React 高阶组件入门介绍
Jan 11 Javascript
在angular 6中使用 less 的实例代码
May 13 Javascript
vue 组件内获取actions的response方式
Nov 08 Javascript
vue多个元素的样式选择器问题
Nov 29 Javascript
jQuery实现简单QQ聊天框
Aug 27 jQuery
三种方式清除vue路由跳转router-link的历史记录
Apr 10 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
解决php中Cannot send session cache limiter 的问题的方法
2007/04/27 PHP
php中操作memcached缓存进行增删改查数据的实现代码
2014/08/15 PHP
PHP利用APC模块实现文件上传进度条的方法
2015/01/26 PHP
PHP准确取得服务器IP地址的方法
2015/06/02 PHP
jquery获取多个checkbox的值异步提交给php的方法
2015/06/24 PHP
PhpStorm 如何优雅的调试Hyperf的方法步骤
2019/11/24 PHP
JavaScript 入门·JavaScript 具有全范围的运算符
2007/10/01 Javascript
Javascript 匿名函数及其代码模式原理
2010/03/19 Javascript
js操作二级联动实现代码
2010/07/27 Javascript
用JQuery调用Session的实现代码
2010/10/29 Javascript
node.js应用后台守护进程管理器Forever安装和使用实例
2014/06/01 Javascript
JS+CSS实现简单的二级下拉导航菜单效果
2015/09/21 Javascript
基于JavaScript代码实现随机漂浮图片广告
2016/01/05 Javascript
Angular 应用技巧总结
2016/09/14 Javascript
Vue之Vue.set动态新增对象属性方法
2018/02/23 Javascript
改变vue请求过来的数据中的某一项值的方法(详解)
2018/03/08 Javascript
[36:54]Mineski vs Winstrike 2018国际邀请赛小组赛BO2 第一场 8.16
2018/08/17 DOTA
Windows和Linux下使用Python访问SqlServer的方法介绍
2015/03/10 Python
python实现协同过滤推荐算法完整代码示例
2017/12/15 Python
Python numpy 提取矩阵的某一行或某一列的实例
2018/04/03 Python
Python用for循环实现九九乘法表
2018/05/31 Python
Python实现的朴素贝叶斯算法经典示例【测试可用】
2018/06/13 Python
Pandas数据分析的一些常用小技巧
2021/02/07 Python
Charlotte Tilbury澳大利亚官网:英国美妆品牌
2018/10/05 全球购物
意大利在线大学图书馆:Libreria universitaria
2019/07/16 全球购物
美国家居用品和厨具购物网站:DealsDot
2019/10/07 全球购物
init进程的作用
2015/08/20 面试题
员工培训心得体会
2013/12/30 职场文书
铁路工务反思材料
2014/02/07 职场文书
2014年幼儿园元旦活动方案
2014/02/13 职场文书
元宵晚会主持词
2014/03/25 职场文书
房屋买卖委托书格式范本格式
2014/10/13 职场文书
党的群众路线教育实践活动个人对照检查材料(企业)
2014/11/05 职场文书
2014年最新版离婚协议书范本
2014/11/25 职场文书
九寨沟导游词
2015/02/02 职场文书
MySQL的意向共享锁、意向排它锁和死锁
2022/07/15 MySQL