如何获取元素的最终background-color


Posted in Javascript onFebruary 06, 2017

一、题目

  用JS代码求出页面上一个元素的最终的background-color,不考虑IE浏览器,不考虑元素float情况。

二、题目解析

  1.考察底层JavaScript基础

  前端开发,日常最常接触的就是页面样式的编写。而摆脱jQuery等工具库,用原生js获取样式,是每个前端程序猿进阶阶段必须掌握的技能。

  2.考察面试者的思维缜密程度和开发经验

  如果认为单单求元素计算后的样式,就有点too young了。页面的样式的复杂,永远是最虐心的。就算前端有多牛逼,一听到兼容IE6,论谁都会心塞?。所以还要考虑特殊的情况:display,opacity,visibility的取值。

三、理论基础

  1. 内联样式

  内联样式可以通过元素的style属性获取,如果style属性有background-color值,则可以直接获取出来 (暂不考虑!important) 。

  2. 外联的层叠样式

  DOM2样式规范在document.defaultView中包含了一个getComputedStyle()方法。该方法返回一个只读的CSSStyleDeclaration对象,其中包含特定元素的所有计算样式。

四、解题

4.1 将所有工具方法封装在WDS(wall dom script)命名空间中

(function(WDS, undefined){
 // 封装代码...
})(window.WDS || (window.WDS = {}));

代码封装在命名空间里,不会造成无意间的代码污染。

4.2 工具方法camelize

// 字符串转换为驼峰写法
function camelize(str) {
 return str.replace(/-(\w)/g, function (strMatch, p1){
  return p1.toUpperCase();
 });
}

该方法是为了方便后续getStyle()方法的编写,而独立出来的。

作用是将连字符类的css属性值,转换成驼峰写法。

例如:将background-color转换为backgroundColor

4.3 获取特定元素的计算样式

// 获取元素计算后的样式
function getStyle(elem, property){
 if(!elem || !property){
  return false;
 }
 var value = elem.style[camelize(property)], // 先获取是否有内联样式
  css; // 获取的所有计算样式
 // 无内联样式,则获取层叠样式表计算后的样式
 if(!value){
  if(document.defaultView && document.defaultView.getComputedStyle){
   css = document.defaultView.getComputedStyle(elem, null);
   value = css ? css.getPropertyValue(property) : null;
  }
 }
 return value;
}

做到这一步,第一个考察点基本就满足了。也能获知面试者是否具备足够扎实的js基础。

另外,像安全保护性的判断if(!elem || !property)和功能嗅探if(document.defaultView && document.defaultView.getComputedStyle),都能很好地体现开发者的代码逻辑和开发经验。

4.4 排除特殊情况

// 检测获取的背景色是否有效
function checkBgValue(elem){
 var value = getStyle(elem, 'background-color'),
  hasColor = value ? true : false; // 是否有颜色
 // 排除特殊情况
 if(value == "transparent" || value == "rgba(0, 0, 0, 0)"){
  // 未设置background-color,或者设置为跟随父节点
  hasColor = false;
 }else if(getStyle(elem, 'opacity') == "0"){
  // dom节点透明度为全透明
  hasColor = false;
 }else if(getStyle(elem, 'visibility') == "hidden"){
  // dom节点不可见
  hasColor = false;
 }else if(getStyle(elem, 'display') == "none"){
  // dom节点不可见
  hasColor = false;
 }
 return hasColor;
}

4.5 获取div在页面最终显示的颜色

// 获取div最终显示的颜色
function getRealBg(elem){
 if(checkBgValue(elem)){
  return getStyle(elem, 'background-color');
 }else if(elem != document.documentElement){
  return getRealBg(elem.parentNode);
 }
 return '';
}

  获取样式值采用递归方式处理。

  如果能顺利获取到元素样式,且不触发4.4 排除特殊情况中的一种,则直接返回结果。

  触发了特殊情况,则需要查找父节点以及更上层的节点的样式,来获取肉眼能看到,显示在页面上的background-color值。

  在向上回溯的过程中,如果已经回溯到html根节点,则可以停止回溯。所以加了判断else if(elem != document.documentElement)

五、遗漏的大boss

5.1 大boss !important

  如果乱用 !important,对大型项目的维护和开发,绝对是一场噩梦。因为优先级规则的计算,!important永远处在食物链的最顶层。

  当前题目不考虑这种情况,也是我的偷懒?。确实很棘手,就不写这个逻辑分支的代码了。这里提醒一下~

5.2 大boss 父节点及根节点设置了不可见css属性

  只要设置该css语句:html {display:none;},页面所有元素立刻消失不见。而任意特定元素的上级节点,只要设置了 opacity,display,visibility,判断逻辑瞬间变得复杂起来。所以,这个浑水我也不趟 O(∩_∩)O哈哈~

六、改进的点

  其实特殊情况排除的判断,我偷懒没做到最好——rgb颜色值和特定颜色值(比如red)没有进行统一的转换,只是加了生硬的判断if(value == "transparent" || value == "rgba(0, 0, 0, 0)")。

有兴趣的可以搜索下颜色值转换的js方法,这里我就不写了。

七、源码和demo

源码地址:https://github.com/wall-wxk/blogDemo/blob/master/2017/02/05/getStyle.html

demo:https://wall-wxk.github.io/blogDemo/2017/02/05/getStyle.html

以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,同时也希望多多支持三水点靠木!

Javascript 相关文章推荐
JavaScript 异步调用框架 (Part 5 - 链式实现)
Aug 04 Javascript
jquery checkbox,radio是否选中的判断代码
Mar 20 Javascript
jquery中的$(document).ready()使用小结
Feb 14 Javascript
详解javascript传统方法实现异步校验
Jan 22 Javascript
JS正则表达式比较常见用法
Jan 26 Javascript
JavaScript设计模式开发中组合模式的使用教程
May 18 Javascript
详解vue过滤器在v2.0版本用法
Jun 01 Javascript
angular ng-click防止重复提交实例
Jun 16 Javascript
jQuery UI 实例讲解 - 日期选择器(Datepicker)
Sep 18 jQuery
微信小程序radio组件使用详解
Jan 31 Javascript
Vue.js进阶知识点总结
Apr 01 Javascript
微信小程序module.exports模块化操作实例浅析
Dec 20 Javascript
a标签置灰不可点击的实现方法
Feb 06 #Javascript
最常见和最有用的字符串相关的方法详解
Feb 06 #Javascript
jquery uploadify隐藏上传进度的实现方法
Feb 06 #Javascript
Javascript中的prototype与继承
Feb 06 #Javascript
canvas实现粒子时钟效果
Feb 06 #Javascript
javascript笔记之匿名函数和闭包
Feb 06 #Javascript
如何用JS/HTML将时间戳转换为“xx天前”的形式
Feb 06 #Javascript
You might like
一步一步学习PHP(4) php 函数 补充2
2010/02/15 PHP
在WordPress中实现发送http请求的相关函数解析
2015/12/29 PHP
php实现支付宝当面付(扫码支付)功能
2018/05/30 PHP
laravel dingo API返回自定义错误信息的实例
2019/09/29 PHP
js抽奖实现随机抽奖代码效果
2013/12/02 Javascript
node.js中的path.join方法使用说明
2014/12/08 Javascript
JavaScript中的Math.LN2属性用法详解
2015/06/12 Javascript
javascript表格的渲染组件
2015/07/03 Javascript
jQuery实现仿腾讯迷你首页选项卡效果代码
2015/09/17 Javascript
angularjs学习笔记之完整的项目结构
2015/09/26 Javascript
Javascript函数中的arguments.callee用法实例分析
2016/09/16 Javascript
详解如何在Angular中快速定位DOM元素
2017/05/17 Javascript
Javascript创建类和对象详解
2017/05/31 Javascript
JavaScript实现元素滚动条到达一定位置循环追加内容
2017/12/28 Javascript
vue-cli结合Element-ui基于cropper.js封装vue实现图片裁剪组件功能
2018/03/01 Javascript
JavaScript中的E-mail 地址格式验证
2018/03/28 Javascript
使用imba.io框架得到比 vue 快50倍的性能基准
2019/06/17 Javascript
vue的三种图片引入方式代码实例
2019/11/19 Javascript
JS array数组检测方式解析
2020/05/19 Javascript
Python字符串中查找子串小技巧
2015/04/10 Python
Python实现快速排序和插入排序算法及自定义排序的示例
2016/02/16 Python
pandas数据预处理之dataframe的groupby操作方法
2018/04/13 Python
Django模板导入母版继承和自定义返回Html片段过程解析
2019/09/18 Python
python爬虫模拟浏览器访问-User-Agent过程解析
2019/12/28 Python
python字典通过值反查键的实现(简洁写法)
2020/09/30 Python
CSS Houdini实现动态波浪纹效果
2019/07/30 HTML / CSS
HTML5拖拽文件到浏览器并实现文件上传下载功能代码
2013/06/06 HTML / CSS
HTML5进度条特效
2014/12/18 HTML / CSS
美国珠宝精品店:Opulent Jewelers
2019/08/20 全球购物
MySQL面试题
2014/01/12 面试题
大学三年的自我评价
2013/12/25 职场文书
社区党建工作汇报材料
2014/08/14 职场文书
政风行风评议整改方案
2014/09/15 职场文书
2015年世界水日活动总结
2015/02/09 职场文书
山楂树之恋观后感
2015/06/11 职场文书
js实现自动锁屏功能
2021/06/02 Javascript