2018

2018.05.03

去除移动端点击事件出现的背景框

-webkit-tap-highlight-color 是一个 不规范的属性(unsupported WebKit property),它没有出现在 CSS 规范草案中。当用户点击iOS的Safari浏览器中的链接或JavaScript的可点击的元素时,覆盖显示的高亮颜色。该属性可以只设置透明度。如果未设置透明度,iOS Safari使用默认的透明度。当透明度设为 0 ,则会禁用此属性;当透明度设为 1 ,元素在点击时不可见。

body {
  -webkit-tap-highlight-color: transparent;
}

2018.05.08

移动端滚动卡顿问题

最近的一次开发中,使用到了overflow:scroll 属性来滑动div。 如果你对某个div或模块使用了overflow: scroll属性,在iOS系统的手机上浏览时,则会出现明显的卡顿现象。

以下代码可解决这种卡顿的问题:-webkit-overflow-scrolling: touch;,是因为这行代码启用了硬件加速特性,所以滑动很流畅。

postcss 二倍图插件

npm install postcss-at2x --save-dev

const fs = require('fs');
const postcss = require('postcss');
const at2x = require('postcss-at2x');

const input = fs.readFileSync('input.css', 'utf8');

const output = postcss()
  .use(at2x())
  .process(input)
  .then(result => console.log(result.css));

配置项:

identifier (default: '@2x') {string} 设置二倍图后缀

detectImageSize (default: false) {boolean} 自动获取一倍图的图片大小,并自动设置background-size

skipMissingRetina (default: false) {boolean} 如果在文件夹中找不到二倍图,将跳过并不输出到css

resolveImagePath (default: process.cwd()) 自动获取图像大小所解析的目录

使用:

.icon {
  background-image: url('test.png') at-2x;
}

less 函数

.icon(@url, @width, @height) {
  display: inline-block;
  width: @width;
  height: @height;
  background-image: url(@url) at-2x;
}

.i-close {
  .icon('close.png', .28rem, .28rem);
}

2018.05.14

eslint node api

const { CLIEngine } = require('eslint')

let cli = new CLIEngine(option)
let report = cli.executeOnFiles(['src'])
fix && CLIEngine.outputFixes(report) // eslint修复文件
let isError = report.errorCount // 是否有错误
let formatter = cli.getFormatter('table')(report.results) // 错误格式化
console.log(formatter)

// option
let option = {
  cwd, // 检测的文件所在路径
  fix, // false 是否自动修复(设置为true并不会自动修复,需要手动调用CLIEngine.outputFixes函数)
  useEslintrc: true, // true 是否使用eslintrc等配置文件检测,默认为true
  configFile, // 设置检测的配置文件(当useEslintrc为true或不赋值时,会自动合并配置项,冲突项使用configFile)
  // 包含解析器选项的对象
  parserOptions: {
    parser: require.resolve('babel-eslint'),
    sourceType: 'module'
  },
  extensions: ['.js', '.vue'], // 需要检测的文件后缀
  envs: ['node'], // 环境
  // 自定义规则
  rules: {
    'vue/max-attributes-per-line': 0
  }
}

更多关于eslint node api

移动端 点击刺穿(touch, click)

背景:在移动端坚听点击事件时,可以使用 click/touchstart/touchend

触发:当使用 touchstart/touchendclick 混合使用时,将造成点击刺穿问题

原因:因为pc端事件( click 等事件)相对于移动端事件有 300ms 的延迟

当在一个页面触发某元素的 touch 相关事件时,跳转到另一页面触发了同一位置且绑定了 click 事件的元素的 click 事件

解决:以下示例为在vue中示例

<div
  @touchstart="onTouchStart"
  @touchmove="onTouchMove"
  @touchend="onTouchEnd"></div>
data () {
  return {
    isClick: false
  }
},
methods: {
  onClick () {
    // click todo
  },
  onTouchStart () {
    this.isClick = true
  },
  onTouchEnd () {
    if (this.isClick) this.onClick()
  },
  onTouchMove () {
    this.isClick = false
  }
}

postcss 在 webpack 中的配置

var ExtractTextPlugin = require("extract-text-webpack-plugin")
const webpackConfig = {
  entry: '',
  module: {
    rules: [
      {
        test: /\.(css|less)$/,
        use: ExtractTextPlugin.extract({
          fallback: 'style-loader',
          use: [
            {
              loader: 'css-loader?-autoprefixer',
              options: {
                importLoaders: 1,
              }
            },
            { loader: 'postcss-loader' },
            { loader: 'less-loader' }
          ]
        })
      }
    ]
  }
}

postcss.config.js

var postcss = require('postcss')
module.exports = {
  modules: true,
  plugins: [
    require('postcss-at2x')(),
    require('postcss-adaptive')({
      remUnit: 50,
      autoRem: true
    }),
    require('postcss-sprites')({
      'stylesheetPath': '',
      'spritePath': '../dist/images/',
      'retina': true,
      'groupBy': function (image) {
        /* eslint no-unused-vars:off */
        let [str, name] = image.url.match(/static\/images\/sprite\/(.*)\//) || []
        if (name && typeof name === 'string') return Promise.resolve(name)
        return Promise.reject(new Error('Not a sprite image.'))
      },
      hooks: {
        onUpdateRule: function (rule, token, image) {
          var backgroundSizeX = (image.spriteWidth / image.coords.width) * 100
          var backgroundSizeY = (image.spriteHeight / image.coords.height) * 100
          var backgroundPositionX = (image.coords.x / (image.spriteWidth - image.coords.width)) * 100
          var backgroundPositionY = (image.coords.y / (image.spriteHeight - image.coords.height)) * 100

          backgroundSizeX = isNaN(backgroundSizeX) ? 0 : backgroundSizeX
          backgroundSizeY = isNaN(backgroundSizeY) ? 0 : backgroundSizeY
          backgroundPositionX = isNaN(backgroundPositionX) ? 0 : backgroundPositionX
          backgroundPositionY = isNaN(backgroundPositionY) ? 0 : backgroundPositionY

          var backgroundImage = postcss.decl({
            prop: 'background-image',
            value: 'url(' + image.spriteUrl + ')'
          })

          var backgroundSize = postcss.decl({
            prop: 'background-size',
            value: backgroundSizeX + '% ' + backgroundSizeY + '%'
          })

          var backgroundPosition = postcss.decl({
            prop: 'background-position',
            value: backgroundPositionX + '% ' + backgroundPositionY + '%'
          })

          rule.insertAfter(token, backgroundImage)
          rule.insertAfter(backgroundImage, backgroundPosition)
          rule.insertAfter(backgroundPosition, backgroundSize)
        }
      },
      spritesmith: {
        padding: 5
      }
    })
  ]
}

2018.05.16

移动端弹出框,阻止页面滚动

created () {
  window.document.body.style.overflow = 'hidden'
},
mounted () {
  this.$el.addEventListener('touchmove', function (e) {
    e.preventDefault()
  })
},
beforeDestroy () {
  window.document.body.style.overflow = 'auto'
}

2018.05.22

js animate api

let el = document.querySelector('selector')
let keyFrames = [
  { left: '0px' },
  { left: '1000px' },
  { left: '5000px' }
]
let option = {
  duration: 1000, // 毫秒
  easing: 'linear'
}
let animate = el.animate(keyFrames, option)

Using the Web Animations API

Animation

2018.05.23

使某div在滚动区域内可见

let el = document.querySelector('.el')
el.scrollIntoView()
// 下面方法更好用!!!
el.scrollIntoViewIfNeeded()

2018.05.30

css span 换行

.example {
  overflow-wrap: break-word;
}

git commit 后还原到没有 commit 的状态

git log # 找到对应 commit 的 id

git reset --soft commitId

图片居中的两种

.picture {
  background-image: url('url');
  position: relative;
  background-position: center;
  background-repeat: no-repeat;
  &.cover {
    background-size: cover;
  }
  &.contain {
    background-size: contain;
  }
}

2018.06.08

判断手机横竖屏

let mql = window.matchMedia('(orientation: portrait)')
function onMatchMeidaChange(mql){
    if(mql.matches) {
        // 竖屏
    }else {
        // 横屏
    }
}
onMatchMeidaChange(mql)
mql.addListener(onMatchMeidaChange)

参考链接