关于这段时间工作中遇到的一些问题和收获

368 阅读7分钟

前言

好长时间没有写文章了,这段时间沉迷游戏,不思进取。感觉自己整个人都荒废了。所以趁着今天还算有点空闲的时间,写一篇文章总结一下这段时间工作中的一些收获

自适应

这段时间,工作上一直在做关于数据大屏的页面,就是一个vue页面加上一些echarts图表。由于动画效果没有做太多的要求,导致并没有动力去研究什么炫酷的动画。所以我就在掘金上面查阅了一些文章,基本上就是四种方法:

  • 第一种,使用媒体查询;

  • 第二种,使用rem作为单位;

  • 第三种,使用viewPort单位——vw或者vh

  • 第四种,使用百分比;

但是这个项目并不是我构建的,项目的搭建者使用了媒体查询的方法。媒体查询这种方法的优点是可以基于每一个分辨率场景下做出针对性的调整,可以做到比较精细化。但是缺点是,可能需要写好几套相应的分辨率的css代码。很大程度的加重了编码量。

而第二种rem,和第三种viewport单位的方案。相比之下就好得多。基本上可以做到一套代码多种分辨率下都可以适配,即使有的分辨率下产生了样式错乱的问题,也可以使用媒体查询专门的进行修复。

但是问题是当前这个项目的有些公共组件已经使用媒体查询写完了。如果想要使用rem的方案需要引入一个js文件,这就会导致那些已经写好的公共组件的样式发生错乱。这就有点得不偿失了。所以,我就只能使用第三种viewport单位的方案了。

然后在我使用了一段时间的vwvh之后,意外的觉得很香。在没有使用这俩单位之前,经常纠结如何制作一个正方形,百分比不行;使用js强行计算的话,需要很多的代码量,会非常的麻烦。根本不划算。而如果使用viewport单位的话,就非常的简单,只需要长和宽设置为相同的单位即可。而我使用的是scss这个css预处理语言。我的使用方法如下:

app.scss

/* 设计图整体宽度 */
$designPageWidth: 1920;
/* 设计图整体高度 */
$designPageHeight: 1080;
/*计算viewport单位,vw和vh*/
@function calcViewPort($divisor,$dividend) {
  @return $divisor / $dividend * 100;
}

text.vue

<template>
	//省略
</template>
<script>
export default {
    //省略
}
</script>
<style lang="scss" scoped>
	@import "src/app.scss"
    #text {
        width: calcViewPort(100vw, $designPageWidth);
        height: calcViewPort(100vw, $designPageWidth);
    }
</style>

当然我这种方法其实比较笨,但是胜在比较灵活,因为我做这个项目的时候是vwvh混用的,所以就这么写了。如果你只想使用其中之一的单位,那么完全可以使用一些辅助插件,比如webstorm上面的pxtorem这个插件。

这样的话,既可以随时调整是用vw还是vh,还可以直观得看出来设计图上设计的长度是多少。渐渐的我现在有点后悔怎么没早早的使用viewport单位了。viewport在我看来不仅可以在一定程度上替代rem,还具有非常好的兼容性,毕竟是原生css就具有的东西,也不需要使用rem的时候还需要引入对应的rem计算js文件。除此之外,如果遇到那种以高度为基准的页面,还可以整个页面以vh作为主要的单位,这样的话,当非全屏状态或者分辨率变低的时候,也不会发生变形。

除此之外,还可以看一下下面这些文章来进一步了解响应式相关的一些知识:

关于mouseover和mouseenter的区别

前段时间我试着自己写了一个”无缝衔接“的轮播图,其中有一个点是,当鼠标移动到图片上的时候,显示出来上一页和下一页的按钮,但是我给最外层包裹着的元素添加mouseover事件之后,每当图片切换完毕的时候移动鼠标,就会重新触发mouseovermouseout事件,这令我百思不得其解。

为此,我特地去看了一下element-ui框架的carousel(跑马灯)组件的源码,发现源码里面是使用的mouseentermouseleave。然后立马去百度了一下他们之间的区别,才知道:

不论鼠标指针穿过被选元素或其子元素,都会触发 mouseover 事件。对应mouseout

只有在鼠标指针穿过被选元素时,才会触发 mouseenter 事件。对应mouseleave

就是说他们之间的区别在于内部有没有子元素。

carousel组件为了保险,还增加了.stop事件修饰符。

这让我不禁感叹,如果不去试着造轮子,那么我还不知道啥时候才能发现这俩事件的区别呢。不过,另一方面也说明我在这方面的知识体系还有所空缺。

关于这个查阅到的文章是:

关于如何获取动态获取宽高

还是关于之前写这个轮播图的时候,由于页面是响应式的,轮播图的外层容器会随着页面的高度或者宽度的变化而变化。这个时候就需要监听浏览器的onresize事件来实时的获取外层容器的宽度,进而来确认每次轮播图移动的距离。而很多时候为了计算轮播图移动的基准值,我们可能不光是需要获取宽度,可能还需要获取marginborder等。然后我就参考了这篇文章:

发现使用getComputedStyle就可以完美的获取到外层容器的各个css属性。不过获取的大部分都是字符串,还得需要转化成数字才可以使用。

如何解决flex-grow:1的时候,父元素依旧被子元素撑开的问题

还是在做数据大屏页面的时候,为了保证全屏和非全屏状态下都能显示出来完整的内容,但是又不至于一些背景图片因此发生变形,这个时候就要考虑那些元素是需要保证一定的宽高比(这些元素均使用vw单位),而剩下的一些echarts图表啊,表格之类的就可以使用一些浮动的高度。

但是,当设置一个div元素flex-grow:1之后,内部填充了很多子元素之后,就会导致此div依旧会被撑开,导致flex-grow:1失效。而这个时候只需要在div上面加上width:0或者height:0就可以了。这个解决方法参照了这篇文章:

flex:1时,父元素宽度被子元素撑开

但是这个解决方案的具体原理是什么,我并不知道。

除此之外,还有一种方法就是添加overflow:hidden。这种方法虽然可以,但是如果我里面的子元素并不希望超出的部分被隐藏的话,这种方案其实并不好。

在此之前我一直以为是不是BFC(Block Formatting Context)——块儿级格式化上下文没有触发的原因。

为此,我还试了一遍各种如何触发BFC的方法:比如设置display:inline-block或者float:left等等,结果都没有效果。

一番百度之后也没有找到答案,只是知道需要这么做。如果有掘金老哥们知道这是什么原理的话,可以告诉我一下。

查漏补缺

1、当发生了外边距重叠应该怎么解决:

CSS查漏补缺:CSS盒模型、外边距重叠、BFC

2、什么是BFC

面试官:请说说什么是BFC?大白话讲清楚

BFC布局与普通文档流布局比较