前端日常开发笔记

本文共有8167个字,关键词:

audio.currentTime失效

html5的audio标签可以直接通过设置currentTime来跳到指定时间播放,但有时候失效了,即使设置了currentTime,但音频依然是从头开始播。
查找原因发现,与服务端返回的音频header有关。
在chrome中,需要:Content-LengthAccept-Ranges必须都有才可更改 currentTime。
参考: HTML5 audio ,在chrome中设置currentTime无效

正则替换html中所有img的src

// 将html中的所有img的src替换成占位图的路径
// str是一段html字符串
function imgPlaceHolder (str) {
  return str.replace(/<img([^>]*?)src=(['"].*?['"])(.*?)>/gi, `<img $1 src="/static/images/placeholder.png" $3>`)
}

div内显示两行,超出部分用省略号

    overflow: hidden;
    text-overflow: ellipsis;
    display: -webkit-box;
    -webkit-line-clamp: 2;(行数)
    -webkit-box-orient: vertical;

给图片添加一个自上而下的渐变遮罩层

/* 表示从透明到白色的渐变,50%表示透明部分占图片上部分的50%(此处不渐变);
   在下半部分渐变120%,数值越大渐变效果越淡 */
.mask{
  height:100%;
  background: -webkit-linear-gradient(transparent 50%, rgba(255, 255, 255, 0.5) 120%);
  background: -o-linear-gradient(transparent 50%, rgba(255, 255, 255, 0.5) 120%);
  background: -moz-linear-gradient(transparent 50%, rgba(255, 255, 255, 0.5) 120%);
  background: linear-gradient(transparent 50%, rgba(255, 255, 255, 0.5) 120%);
}

移动端video标签使用注意

  1. source文件格式尽量多支持
  2. video的width内联不支持百分比形式,但可以在外联样式中设置。如果要设置固定数值,不要加单位,如width="100"
  3. 可添加的属性: 自动播放autoplay,播放控件controls,循环播放loop,预加载preload,width,height,src,视频封面(安卓某些浏览器不支持)poster
  4. 在微信浏览器,点击播放时视频默认全屏,想要实现小窗播放,需要添加属性
<video  src=""  controls="" x5-playsinline="" playsinline="" webkit-playsinline="" poster="" preload="auto"></video>
  1. 安卓浏览器播放时,滚动页面视频会跟随,将会像fixed在顶部一样。
  2. 更多参考:html5--移动端视频video的android兼容,去除播放控件、全屏等
  3. 播放器控制个人demo:Github
  4. 隐藏视频的播放控件
    第一种办法:把视频放在canvas中播放。完美解决微信video视频隐藏控件和内联播放问题

第二种:css样式,最简单的办法。

<style type="text/css"> 
    video::-webkit-media-controls-enclosure { 
        display: none !important; 
    } 
</style> 

移动端1像素边框问题

/* css粗放版,只针对dpr=2的机型进行border宽度减半,在3dpr的机型显示相当于1.5px,要求不高的项目可以满足使用 */
.xxx:after{
  content: '';
  position: absolute;
  top: 0;
  left: 0;
  border: 1px solid #748187;
  -webkit-box-sizing: border-box;
          box-sizing: border-box;
  width: 200%;
  height: 200%;
  -webkit-transform: scale(0.5);
      -ms-transform: scale(0.5);
          transform: scale(0.5);
  border-radius: 6px;
  -webkit-transform-origin: left top;
      -ms-transform-origin: left top;
          transform-origin: left top;
}

如何在组件中添加原生事件

比如想像这样给ElementUI中的input添加click事件:<el-input @click="clickMe"></el-input>,会发现点击事件并没有触发;正常来说,el-input这个组件是不支持click事件的,至少官方文档中不支持。但是偶尔有些奇葩需求,就是需要在组件中添加一个原生的自定义事件,这时候需要用到.native修饰符。如下:

<el-input @click.native="clickMe"></el-input>

参考:将原生事件绑定到组件

vue2父组件传递props异步数据到子组件

父组件.vue

// asyncData为异步获取的数据,想传递给子组件使用
<template>
  <div>
    父组件
    <child :child-data="asyncData"></child>
  </div>
</template>

<script>
  import child from './child'
  export default {
    data: () => ({
      asyncData: ''
    }),
    components: {
      child
    },
    created () {
    },
    mounted () {
      // setTimeout模拟异步数据
      setTimeout(() => {
        this.asyncData = 'async data'
        console.log('parent finish')
      }, 2000)
    }
  }
</script>

子组件.vue

<template>
  <div>
    子组件{{childData}}
  </div>
</template>

<script>
  export default {
    props: ['childData'],
    data: () => ({
    }),
    created () {
      console.log(this.childData) // 空值
    },
    methods: {
    }
  }
</script>

解决办法1(推荐): 在父组件.vue加一个v-if的判断,asyncData不为空时才渲染。

<child :child-data="asyncData" v-if="asyncData"></child>

解决办法2: 子组件通过watch来实现。

Computed property "xx" was assigned to but it has no setter.

使用Vue过程中常会遇到的一个问题。
解决一: 加一个setter。

data () {
        return {
            text: 'myVal'
        };
    },
    computed: {
        computedText: {
            get () {
                return this.text
            },
            set (newVal) {
                this.text = newVal
            }
        }
    }

解决二: 将computed的字段放到data中。
这种方法的前提是错误是子组件对props字段computed尝试修改引发的,而且需求是computed字段只使用一次。比如这种使用场景:

// 父组件parent.vue
<child :testVal="父组件传进来的值"></child>

// 子组件child.vue
export default {
    props: {
        testVal: {
          type: String
        }
    }
    computed () {
        childVal () {
          return this.testVal
        }
    },
    methods: {
        changeVal (){
            this.childVal = 'xxxx'
        }
    }
}

调用changeVal方法就会引发该错误,这种场景我们可以通过将computed的字段放到data中来解决。

// 父组件parent.vue
<child :testVal="父组件传进来的值"></child>

// 子组件child.vue
export default {
    props: {
        testVal: {
          type: String
        }
    },
    data () {
        return {
          childVal: this.testVal
        }
    },
    methods: {
        changeVal (){
            this.childVal = 'xxxx'
        }
    }
}

解决这个问题后,如果parent.vue传入的testVal是ajax异步获取的,会有可能引发新的问题:childVal在data中拿不到this.testVal(原因是子组件初始化时,父组件的testVal由于是异步还没获取到,导致传给子组件时是null或undefined)。这时候可以通过:

    1. 加v-if判断:<child :child-data="asyncData" v-if="asyncData"></child>
  • 2.或者某些情况可能需要异步组件来解决,将子组件的加载设置到父组件数据加载完毕后。
// 父组件parent.vue
<template>
<child :testVal="testVal"></child>
</template>
<script>
import Vue from 'vue'
const Child = Vue.component('Child', function (resolve) {
  setTimeout(function () {
    require(['./Child.vue'], resolve)
  }, 100) // 需要比异步获取数据的时间晚
})
export default {
  data () {
      return {
        testVal: ''
      }
  },
  components: {
    Child
  },
  created () {
    // 异步获取的testVal
    setTimeout(() => {
        this.testVal = '我是异步获取的值'
    }, 10)
  }
</script>

如何在页面初始化前将异步数据获取到vuex中。

这里主要想做到在页面created前就将服务器的data获取到,需要用到Vue的beforeRouteEnter钩子。具体如下:

export default {
  data() {
    return {
      myData: ''
    }
  },
  beforeRouteEnter (to, from, next) {
    // get data.....
    next()
  }
}

如果是要将数据存放到vuex中,则可以:

import store from '@/store'
export default {
  name: 'Layout',
  beforeRouteEnter (to, from, next) {
    // 通过dispatch触发vuex中的action, 需要提前在store中定义fetchPublisher的方法(可以是异步获取api数据的方法)
    store.dispatch('fetchPublisher')
    next()
  },
  methods: {
  },
  components: {
  }
}
</script>

在vue初始化前会显示绑定的变量名

<ul v-for="item in items">
  <li>{{ item.name }}</li>
</ul>

解决:标签加上v-cloak,并设置css

<ul v-cloak v-for="item in items">
  <li>{{ item.name }}</li>
</ul>
/* css */
[v-cloak] {
  display: none;
}

预加载自定义字体

<link rel="preload" href="./static/font/HuaKangHaiBaoTiW12-P-1.woff2" as="font" type="font/woff2" crossorigin>

判断页面字体是否加载成功

document.fonts.check('bold 16px HuaKangW12')
// true 表示页面已加载该字体

新标签打开页面时不要携带refer

描述:<a href="baidu.com" target="_blank">test</a>,浏览器中打开页面时发现携带了项目中的refer和header。某些情况下不想携带这些信息,可以加上rel="noreferrer",如:<a rel="noreferrer" href="baidu.com" target="_blank">test</a>

iOS 10+ Safari 禁止双击或触摸缩放页面

ios 10+系统会强制允许缩放,meta标签也无法限制,只能通过js控制。
除了meta上要加:<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,user-scalable=no,viewport-fit=cover">外,需加上以下js:

    window.onload = () => {
      document.addEventListener('touchstart', (event) => {
        if (event.touches.length > 1) {
          event.preventDefault()
        }
      }, {
        passive: false
      })

      let lastTouchEnd = 0
      document.addEventListener('touchend', (event) => {
        const now = (new Date()).getTime()
        if (now - lastTouchEnd <= 300) {
          event.preventDefault()
        }
        lastTouchEnd = now
      }, false)
    }

若使用的是vue,可以加在App.vuemounted钩子中。
(持续更新...)

「一键投喂 软糖/蛋糕/布丁/牛奶/冰阔乐!」

fengxianqi

(๑>ڡ<)☆谢谢老板~

使用微信扫描二维码完成支付

版权声明:本文为作者原创,如需转载须联系作者本人同意,未经作者本人同意不得擅自转载。
添加新评论
暂无评论