争取把 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 的需求,发生了一个这样的问题:

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

代码如下:
.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: 48px,flex 是默认的 0 1 auto;另一个子盒(.action-sheet-content)的 flex 是 1 1 auto。但是,当第二个子盒的高度太大的时候(在例子中,有 400px, 远大于父盒的 200px),由于 flex-shrink: 1 的存在,第一个盒子的高度就会被压缩掉。
解决的方式有两种:
- .action-sheet-header设置- flex: 0 0 auto
- 为 .action-sheet-content设置overflow: hidden,根据 BFC 是页面上一个隔离的容器,容器内的子元素不会影响到外面的元素,反之也成立 的规则,使得第二个盒子不影响第一个盒子
移动端 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
- 还有一种是简单一点,只用一个 <div>标签来模拟 1 像素如下:
.line-point-5
  height: 1px
  transform: scaleY(0.5)
  transform-origin: 50% 100%
css 文本溢出
文本溢出的处理主要包含三个属性:white-space、overflow 和 text-overflow。
.container
  width: 100px
  overflow: hidden
  white-space: nowrap
  text-overflow: ellipsis
多行文本溢出
上面的方式,只能进行单行的文本溢出,多行文本溢出并没有效果,方法有:
- 添加 webkit 内核的一个私有属性
overflow : hidden
text-overflow: ellipsis
display: -webkit-box
-webkit-line-clamp: 2
-webkit-box-orient: vertical
- 利用 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 返回的是字符串
所以,对于 true 和 false 等值,可以使用 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 应该包装进基类吗?如何设计一个类?依赖注入适合在这个地方吗?