争取把 CSS 写好

这个是以前写在其他地方的一个笔记,现在挪过来,促进内容的更新。

防止用户重复点击

问题阐述:有些时候服务器响应比较慢,需要等待一段时间,可能会造成用户重复点击按钮

answer: 用户提交表单后把按钮设为 disabled,ajax 成功后,再去掉 disabled 属性。另外,由于服务器响应比较慢,可以在请求 http 时加一个动态效果。

移动端 h5 无限滚动

Waiting for content...

button 内文本不换行

只需要一个属性即可:

white-space: nowrap

移动端 h5 去除 button 等元素的默认样式

在移动端开发的时候,不同设备的渲染不一致,尤其是有一些 :active:focus 等浏览器的默认样式,这个时候,需要进行 reset

button
  outline: none
  border-style: none
  &:active
    /*重置代码*/

一长串连续英文字符和数字的换行

在标签内部,中文的换行是没有问题的。但英文的换行就有问题。当出现一长串连续的英文字符时,换行就失效了,这是因为浏览器会将它识别为一个单词。通常的方式是:

p
  word-wrap: break-word
  word-break: break-all

对后端可能返回的 null 做 default 处理

后端返回的数据很多情况下会返回 null, 但是在处理过程中经常会用到数组的 length 属性和方法,所以要使用之前,一定要针对可能返回的 null 做预处理。

input 只上传图片

<input type="file" accept="image/*">

animation 最后回到元素的本来位置

animation-fill-mode: both

flex 盒的造成的 height 为 0 的原因剖析

之前做了一个 action sheet 的需求,发生了一个这样的问题:

flex_height_0

设置了头部的 height 值,但计算的结果如下:

flex-1

代码如下:

.action-sheet-container
  display: flex
  flex-direction: column
  width: 100%
  box-sizing: border-box
  height: 200px
  min-height: 180px
  background-color: #F0F2F0
  overflow: hidden
  .action-sheet-header
    display: flex
    justify-content: space-between
    align-items: center
    height: 48px
    padding: 0px 16px
    .action-sheet-title
      font-size: 18px
      color: #303133
  .action-sheet-content
    flex: 1
    margin: 13px 16px

可以看到,我们这是一个弹性盒。外部 container(.action-sheet-container) 的 flex-direction: column,然后给内部子盒(.action-sheet-header)定义了一个高度 height: 48pxflex 是默认的 0 1 auto;另一个子盒(.action-sheet-content)的 flex1 1 auto。但是,当第二个子盒的高度太大的时候(在例子中,有 400px, 远大于父盒的 200px),由于 flex-shrink: 1 的存在,第一个盒子的高度就会被压缩掉。

解决的方式有两种:

  1. .action-sheet-header 设置 flex: 0 0 auto
  2. .action-sheet-content 设置 overflow: hidden,根据 BFC 是页面上一个隔离的容器,容器内的子元素不会影响到外面的元素,反之也成立 的规则,使得第二个盒子不影响第一个盒子

移动端 1 像素问题

  1. 伪类加 transform 是一种较为好的方法。原理是: 把原来的 border 去掉,利用 :before:after 来重做 border
.box
  position: relative
  border:none

.box:after
  content: ''
  position: absolute
  bottom: 0
  background: #000
  width: 100%
  height: 1px
  -webkit-transform: scaleY(0.5)
  transform: scaleY(0.5)
  -webkit-transform-origin: 0 0
  transform-origin: 0 0
  1. 还有一种是简单一点,只用一个 <div> 标签来模拟 1 像素如下:
.line-point-5
  height: 1px
  transform: scaleY(0.5)
  transform-origin: 50% 100%

css 文本溢出

文本溢出的处理主要包含三个属性:white-spaceoverflowtext-overflow

.container
  width: 100px
  overflow: hidden
  white-space: nowrap
  text-overflow: ellipsis

多行文本溢出

上面的方式,只能进行单行的文本溢出,多行文本溢出并没有效果,方法有:

  1. 添加 webkit 内核的一个私有属性
overflow : hidden
text-overflow: ellipsis
display: -webkit-box
-webkit-line-clamp: 2
-webkit-box-orient: vertical
  1. 利用 after 伪元素模拟
p {
    position:relative;
    line-height:1.5em;
    /* 高度为需要显示的行数*行高,比如这里我们显示两行,则为3 */
    height:3em;
    overflow:hidden;
}
p:after {
    content:"...";
    position:absolute;
    bottom:0;
    right:0;
    padding: 0 5px;
    background-color: #fff;
}

white-space、word-wrap和word-break

white-space 用来处理文本中 空白,包括如何处理多个空白符换行符是否允许过长折行。常用的属性值:

  • normal:连续的空白符和换行符合并为一个(换行符当做空白符处理),过长折行
  • nowrap:连续的空白符和换行符合并为一个(换行符当做空白符处理),过长不折行

word-wrap 处理文本到达一行的末尾时,是否进行分割。注意: css3 已经改名为 overflow-wrap 了。

  • normal:不进行分割
  • break-word:达行的末端,进行分割

word-break 当文本到达一行的末尾时,如何进行分割。

  • normal:不进行分割
  • break-all:到达行的末端,进行分割

其实看的比较明显,overflow-wrap 如果有可换行的的分割点,就会按照分割点进行分割。而 word-break 会尽量挤占空间,直到没有任何空余的空间。

item 自动折到下一行

大概就是这样的一个需求,可能会有多个,为了提高可复用性,希望能采用一种较为合理的方式。

常规方式:

<div class="item-container">
  <div class="item">
    <!--something else to show-->
  </div>
</div>
<style lang="sass">
.item-container
  text-align: left
  font-size: 0px
.item
  display: inline-block
  width: calc(50% - 30px)
  font-size: 14px
  margin-right: 60px
  &:nth-child(2n)
    margin-right: 0
</style>

另一种就是使用 flex 盒子,flex-wrap 的值为 wrap

.item-container
  display: flex
  flex-wrap: wrap
  justify-content: space-between
.item
  width: calc(50% - 30px)
  &:nth-child(even)
      margin-left: 20px

使用 localstorage 返回的是字符串

所以,对于 truefalse 等值,可以使用 JSON.parse() 处理一下。

window.parent 判断是不是子 iframe

如果 window.parent === window,表明该 window 即为顶层 window

npm i 报错

错误信息是:

Module build failed: Error: Node Sass does not yet support your current environment: OS X 64-bit with Unsupported runtime (64)

原因是 Node Sass 不支持高版本的 Node,切换到 8.12.0 的稳定版本

一个对面向对象编程认识不深刻的写法错误

新系统上线,线上报大量异常。最后定位到一个写法问题:

// base.ts
import axios from 'axios'
import env from '@/common/config'
import { urlSplice } from '@/common/utils/assist'
import { IQueryParams } from '@/common/service/types'

export default class {
  private ksid: string = window.localStorage.getItem('ksid') || ''

  private shopId: string = window.localStorage.getItem('shopId') || ''

  protected get (base: string, queryParams?: IQueryParams) {
    let url = base.concat(urlSplice({
      ...queryParams,
      ksid: this.ksid,
      shopId: this.shopId
    }))
    return axios
      .get(baseUrl.concat(url))
      .then(res => res.data)
  }
  protected post (base: string, params: IQueryParams) {
    return axios
      .post(baseUrl.concat(base), { ...params, ksid: this.ksid, shopId: this.shopId })
      .then(res => res.data)
  }
}

然后有一个类继承了这个类。

// campaign-service.ts
import Base from '@/common/service/base'

class CampaignService extends Base {
  queryApplyingCampaigns () {
    return super.get('/napos-applying-campaigns')
  }
}

问题在于在编译时,此时还未获取到 ksid 和 shopId, 因此值都为空字符串。

改成:

export default class {
  get ksid () {
    return window.localStorage.getItem('ksid') || ''
  }
  get shopId () {
    return window.localStorage.getItem('shopId') || ''
  }
  ...
}

现在我想的问题是,ksid 和 shopId 应该包装进基类吗?如何设计一个类?依赖注入适合在这个地方吗?

上次更新: 4/25/2019, 10:09:36 AM