即日起在codingBlog上分享您的技术经验即可获得积分,积分可兑换现金哦。

CSS并不简单–一道微信面试题的实践

微信 web前端课程 20℃ 0评论
本文目录
[隐藏]

1.

本系列会持续分享本人学习到的CSS知识点、技巧和效果展示。如有错误,希望您能指出。

前段时间有一位大牛分享的几道微信的面试题,其中一道是求一个HTML元素的background-color的题目,鉴于对这道题目的学习,我写下了这篇文章。

1.1.1.优先级的计算规则

  • !important 这个关键字的优先级最高。要优化考虑使用样式规则的优先级来解决问题而不是 !important.

    下面要引入特殊值 0,0,0,0 每一位为0~255(基本上不会超过255的)

  • 内联样式. 记做: 1,0,0,0

  • 然后是ID选择器. 记做: 0,1,0,0

  • 类选择器、属性选择器和伪类选择器. 记做: 0,0,1,0

  • 元素选择器和伪元素选择器. 记做: 0,0,0,1

  • 通用选择器(星号)、组合符合(+,>,~,” “)和否定伪类(:not())不影响优先级.

  • 如果他们的优先级一样的话,则是后声明的样式覆盖前面声明的样式.

    举个简单的栗子:

  a:hover {    color: red;
  }  a:link {    color: yellow;
  }

根据以上的计算规则我们可以得到 a:hover的优先级为 0,0,1,1,a:link的优先级也为 0,0,1,1。所以a:link的样式覆盖了a:hover。所以我们平常写这两个的不同样式时会把hover放在link的后面。

1.1.2.原生JS获取元素的样式

可能很多人用惯了jquery,突然让你用原生JS获取一个div的背景颜色,高高兴兴的搜了一个element.style.backgroundColor,然后一脸懵逼,为什么没有值?

  var d = document.querySelector('#d1');
  d.style.backgroundColor; //为什么它有时间没有值。

因为style不能读取样式表中的样式,是不是很尴尬!接下来让我们来感受一下JS的魅力:

  /**
   * 将属性名转化为驼峰命名格式
   */
  function camelize(str) {    return str.replace(/-(\w)/g, function (matchStr, p1) {      return p1.toUpperCase();
    })
  }  function getStyle(element, name) {    if (!element || !name) {      return false;
    }    //查看内敛样式是否存在 它的优先级最高 !important这里不考虑
    var value = element.style[name];    if (value) {      return value;
    }    if (element.currentStyle) {      //IE中
      value = element.currentStyle[name];
    } else {      if (window.getComputedStyle) {         //标准浏览器
         value = window.getComputedStyle(element, null).getPropertyValue(name);
      }
    }    return value;
  }

是不是感觉其实原生的JS也是那么的优美,只是浏览器的兼容性埋没它的美丽。以上是个简单的获取元素某个样式属性的方法。其中还有很多问题,比如说!important。。。

在下面微信面试题求解的方法这篇文章的评论中,有人提到了用canvas的方式。然后我查阅了文档,看到了Drawing DOM Content To Canvas这篇文章,不过通过实践,发现通过svg将html元素转化图片,再填入到canvas中的方式,外部样式表并不能起作用。这就尴尬了,可能是我对那篇文章理解的还不够深刻(如果有人遇到同样的问题,能够指点一下),最终我选择了通过html2canvas插件实现我的需求。

  • 获取到目标元素的位置信息

  • 去除目标元素的后代元素, 以防止造成干扰判断。

  • 对整个页面进行截图,回调函数中恢复目标元素的后代节点。

  • 获取目标元素的像素集合。

  • 因为只能获取到一个个的像素点,我这里只想到了去掉border区域的其他的某点颜色作为背景颜色。

  • 这里只能判断纯色背景(好像有点蠢),有更好的判断方法,请留言指点。

    直接上代码:

    const canvas = document.createElement('canvas'),
             context = canvas.getContext('2d'),
             div = document.querySelector('.demo1');const rect = div.getBoundingClientRect(), //获取元素的位置信息
          x = rect.left,
          y = rect.top,
          w = rect.width,
          h = rect.height;
    
    canvas.width = document.body.clientWidth;
    canvas.height = document.body.clientHeight;function getColor() {  //去掉目标元素的后代元素
      let childnodes = removeChilds(div);  //对页面进行截屏
      html2canvas(document.body, {canvas: canvas}).then((canvas) => {    //获取目标元素的像素集合
        const imageData = context.getImageData(x,y,w,h);    //恢复目标元素的后代元素
        addChilds(div, childnodes);
        childnodes = null;    /**
         * 去掉border的影响
         */
        const border = parseInt(getStyle(div,"border-width"));    const index =  (border * w + border) * 4;    const r = imageData.data[index],
              g = imageData.data[index + 1],
              b = imageData.data[index + 2],
              a = imageData.data[index + 3];    console.log("rgba(" + r + "," + g + "," + b + "," + a + ")");
      });
    };//剥离后代元素function removeChilds(element) {  let eleArray = Array.from(element.childNodes);
      eleArray.forEach((item) => {
        element.removeChild(item);
      })  return eleArray;
    }//加上后代元素function addChilds(element, nodes) {
      nodes.forEach((item) => {
        element.appendChild(item);
      })
    }

作者:valar_cC

源自:http://www.jianshu.com/p/64d5cabfab89

声明:文章著作权归作者所有,如有侵权,请联系小编删除。


-THE END-


前端学习群:224970289(仅限学习前端的小伙伴)

转载请注明:CodingBlog » CSS并不简单–一道微信面试题的实践

喜欢 (0)or分享 (0)
发表我的评论
取消评论

*

表情