前端奇淫技巧|牛气冲天新年征文

309 阅读3分钟

1.html5 video 调用play()的问题

ps: 同一个video标签在初始化时完成了自动播放,后续通过其他事件触发play()都是没问题的

1.html5 video autoplay 自动播放失效的问题

  1. chrome66以及更高的版本不允许媒体自动播放。
  2. safari 阻止自动播放视频

设置 muted 静音属性可以实现自动播放

<video src="xx" autoplay muted></video>

2.监听ios微信关闭页面事件

pushHistory(); 
window.addEventListener("popstate", function(e) { 
    // alert("我监听到了浏览器的返回按钮事件啦");//根据自己的需求实现自己的功能 
    // 关闭当前微信窗口
   WeixinJSBridge.call('closeWindow');
}, false); 
function pushHistory() { 
    var state = { 
        title: "title", 
        url: "#"
    }; 
    window.history.pushState(state, "title", "#"); 
}



3.js动态修改animationDuration无效

根据w3c规定运行中的动画改变animation timing / keyframe被忽略是符合标准的。

解决方案利用body动态添加一个class样式,在这个样式单独设置animationDuration,最后添加class即可

4.vue监听手机物理返回键(浏览器返回)


//1、挂载完成后,判断浏览器是否支持popstate
mounted(){
  if (window.history && window.history.pushState) {
    // history.pushState(null, null, document.URL);
    // 这里不使用 ` pushState `` 因为会产生一条历史记录
    // 而使用 ` replaceState ` 但是会直接替换掉当前url,而不会在history中留下记录
    history.replaceState(null, null, document.URL);
    window.addEventListener('popstate', this.goBack, false);
  }
},
//页面销毁时,取消监听。否则其他vue路由页面也会被监听
destroyed(){
  window.removeEventListener('popstate', this.goBack, false);
},
//3、将监听操作写在methods里面,removeEventListener取消监听内容必须跟开启监听保持一致,所以函数拿到methods里面写
methods:{
  goBack(){
    this.$router.replace({path: '/'});
    //replace替换原路由,作用是避免回退死循环
  }
}

5.vue 对子组件使用v-if,子组件无法watch到props的值


    watch: {
    levelDetail: {
      immediate: true, // 很重要!!!
      handler (val) {
        this.levelPersonal = !val ? {} : val
        // console.log('action Value:', val, this.levelPersonal)
      }
    }
  }
  

6.解决npm有时候无法下载的情况

npm config set registry https://registry.npm.taobao.org
-- 配置后可通过下面方式来验证是否成功
npm config get registry

7.手机和电脑同局域网下,手机打不开链接

往往是电脑没有关闭防火墙

8.安卓部分机型文字会有一部分被截取的问题

设置 line-height 即可

9.处理ios input 获取焦点时背景顶上去的bug


function disposeIosInputFocus() {
    var u = navigator.userAgent;
    var flag;
    var myFunction;
    var isIOS = !!u.match(/\(i[^;]+;( U;)? CPU.+Mac OS X/);
    if(isIOS){
        document.body.addEventListener('focusin', () => {  //软键盘弹起事件
            flag=true;
            clearTimeout(myFunction);
        })
        document.body.addEventListener('focusout', () => { //软键盘关闭事件
            flag=false;
            if(!flag){
                myFunction = setTimeout(function(){  
                    window.scrollTo({top:0,left:0,behavior:"smooth"})//重点  =======当键盘收起的时候让页面回到原始位置(这里的top可以根据你们个人的需求改变,并不一定要回到页面顶部)
                    
                },200);
            }else{
                return
            }
        })
    }else{
        return
    }
}

10.安卓app里面内嵌html5页面当设置手机字体大小的时候会影响到页面的显示

解决方案:安卓设置 webview.getSettings().setTextZoom(100); 即可

11.ios在使用渐变透明色会出现样式错误问题

解决方案:将 transpaent 换成 rgba(x,x,x,x) 即可

12.解决安卓、ios遮罩层背景还可以滚动的问题

<div @touchmove="onPreventTouchMove"></div>
function onPreventTouchMove() {
    /* istanbul ignore else */
    if (typeof event.cancelable !== 'boolean' || event.cancelable) {
      event.preventDefault()
    }
    
    event.stopPropagation()
}

13.使用html2canvas截图不全的问题

如果截图的内容高度高于当前浏览器可视区域,则需要在截图前将body滚动条置顶

14.服务端部署的一些小事

  • 尽量将npm i 换成下面语句,可以保证安装依赖的时候是使用 package-lock.json中的版本,并且在linux拥有root最高权限

  • 尽量不要使用cnpm,cnpm将无法自动生成或者更新 package-lock.json

  • npm太慢可以设置成国内淘宝源 npm config set registry registry.npm.taobao.org

npm ci --unsafe-perm

15.node-sass安装失败

除了使用cnpm去安装还可以通过设置全局环境变量

SASS_BINARY_SITE = https://npm.taobao.org/mirrors/node-sass

16. vue+axios图片上传爬坑

因上传文件要使用到 FormData对象,代码如下

onUpload() {
    const formData = new FormData()
    formData.append('file', file)
    axios.post(url, formData, {
        headers: { 'Content-Type': 'multipart/form-data' }
    })
}

这个时候你会发现请求头是没有boundary ,主要的原因还是我的axios做了全局拦截器,里面是有做一些数据处理,并且我们的headers 是不需要额外去处理的,浏览器会自动判断类型加上
// http.js
// 添加请求拦截器,主要是做全局参数和签名处理
axios.interceptors.request.use(config => {
    if (config.method === 'post' && !whiteList.includes(config.url)) {
        config.data = qs.stringify(Object.assign(config.data || {}, {
            sign: paramsToMd5(Object.assign(config.data || {}, {
                timestamp: Date.now()
            }))
        }))
    } else {
        config.params = Object.assign(config.params || {}, {
            sign: paramsToMd5(Object.assign(config.params || {}, {
                timestamp: Date.now()
            }))
        })
    }
    console.log('config = ', config)

	return config
}, error => {
	// 对请求错误做些什么
	return Promise.reject(error)
})

最终的解决方案就是重新axios create一个纯净的axios对象方可解决


onUpload() {
    const formData = new FormData()
    formData.append('file', file)
    axios.create().post(url, formData)
}

17.移动端适配

目前移动端有两种流行的两种适配方式

  • px转换rem
  • px转换vw

今天介绍一下px转换vw

安装 postcss-px-to-viewport

npm i postcss-px-to-viewport -D

配置文件

在项目根目录创建 postcss.config.js 代码如下

module.exports = {
  plugins: {
    autoprefixer: {},
    'postcss-px-to-viewport': {
      // 视窗的宽度,对应的是我们设计稿的宽度,我们公司用的是375
      viewportWidth: 375,
      // 视窗的高度,根据750设备的宽度来指定,一般指定1334,也可以不配置
      // viewportHeight: 1334,
      // 指定`px`转换为视窗单位值的小数位数
      unitPrecision: 3,
      // 指定需要转换成的视窗单位,建议使用vw
      viewportUnit: 'vw',
      // 指定不转换为视窗单位的类,可以自定义,可以无限添加,建议定义一至两个通用的类名
      selectorBlackList: ['.ignore'],
      // 小于或等于`1px`不转换为视窗单位,你也可以设置为你想要的值
      minPixelValue: 1,
      // 允许在媒体查询中转换`px`
      mediaQuery: false
    }
  }
}

18.vue-cli3 中 /sockjs-node/info?t= net::ERR_SSL_PROTOCOL_ERROR 的解决方案

配置 vue.confing.js ,在配置中对 devServer 进行如下配置,然后重启

module.exports = {
    devServer: {
        proxy: 'http://localhost:8080',
        public: 'localhost:8080'  // 本地ip
    }
}

19.vue项目 Module not found: Error: Can't resolve 'regenerator-runtime/runtime'

重新安装 npm install --save @babel/runtime 就好了

20.使用chrome浏览器解决跨域问题

版本号49之后的chrome跨域设置 chrome的版本升到49之后,跨域设置比以前严格了,在打开命令上加--disable-web-security之后还需要给出新的用户个人信息的目录。众所周知chrome是需要用gmail地址登录的浏览器,登录后就会生成一个存储个人信息的目录,保存用户的收藏、历史记录等个人信息。49版本之后,如果设置chrome浏览器为支持跨域模式,需要指定出一个个人信息目录,而不能使用默认的目录,估计是chrome浏览器怕用户勿使用跨域模式泄露自己的个人信息(主要是cookie,很多网站的登录token信息都是保存在cookie里)。

具体做法为:

1.在电脑上新建一个目录,例如:C:\MyChromeDevUserData

2.在谷歌浏览器属性页面中的目标输入框里加上 --disable-web-security --user-data-dir=C:\MyChromeDevUserData,--user-data-dir的值就是刚才新建的目录。

3.点击应用和确定后关闭属性页面,并打开chrome浏览器。

再次打开chrome,发现有“--disable-web-security”相关的提示,说明chrome又能正常跨域工作了。

跨域成功后,首页换成了google的welcome页面,同时原来收藏的链接和历史记录都不见了,而C:\MyChromeDevUserData目录下则生成了新的个人信息相关的文件。

如果需要访问之前为跨域的状态需要复制多一个快捷方式出来

21.vue使用vant如何修改主题色

官方说的修改主题颜色有点草率,这里我详细介绍一下如何修改vant主题颜色

你的babel.config.js看起来是这样的

module.exports = {
    plugins: [
        ['import', {
            libraryName: 'vant',
            libraryDirectory: 'es',
            style: (name) => `${name}/style/less`,
        }, 'vant']
    ]
};

你的vue.config.js看起来是这样的

module.exports = {
    css: {
        loaderOptions: {
            less: {
                // 若使用 less-loader@5,请移除 lessOptions 这一级,直接配置选项。
                lessOptions: {
                    modifyVars: {
                        'font-size-sm': '13px',
                        'font-size-md': '15px',
                        'font-size-lg': '17px',
                        // 直接覆盖变量
                        'tabs-default-color': '#E02D47',
                    },
                },
            },
        },
    },
}

最后通过修改变量名达到修改主题色的效果

附属文档

vant变量颜色配置文件

22.vue-cli3 项目在低版本安卓浏览器白屏得问题

首先安装这两个插件
npm i babel-polyfill es6-promise -S
紧接着在 main.js 导入
// 解决低版本兼容性问题
import 'babel-polyfill'
import Es6Promise from 'es6-promise'
require('es6-promise').polyfill()
Es6Promise.polyfill()
babel.config.js 增加以下代码
module.exports = {
    presets: [
        [
            "@vue/app",
            {
                "useBuiltIns": "entry",
                polyfills: [
                    'es6.promise',
                    'es6.symbol'
                ]
            }
        ]
    ]
};

最后在 vue.config.js 增加以下代码
module.exports = {

    // 默认情况下 babel-loader 会忽略所有 node_modules 中的文件。
    // 如果你想要通过 Babel 显式转译一个依赖,可以在这个选项中列出来
    transpileDependencies: [],
    chainWebpack: config => {

        config.module.rule('compile')
        .test(/\.js$/)
        .include
        .add(resolve('src'))
        .add(resolve('test'))
        .add(resolve('node_modules/webpack-dev-server/client'))
        .add(resolve('node_modules'))
        .end()
        .use('babel')
        .loader('babel-loader')
        .options({
          presets: [
            ['@babel/preset-env', {
              modules: false
            }]
          ]
        });

    }
}

23.vscode vue模板增加对象属性自动补全

  1. 打开vscode 插件,进入vetur插件
  2. 点击 在sessions.json中编辑
  3. 增加如下一行代码 "vetur.experimental.templateInterpolationService": true

24. onpageshow 事件

onpageshow 事件在用户浏览网页时触发。 onpageshow 事件类似于 onload 事件,onload 事件在页面第一次加载时触发, onpageshow 事件在每次加载页面时触发,即 onload 事件在页面从浏览器缓存中读取时不触发,此外还有pagehide在不显示的时候触发。

为了查看页面是直接从服务器上载入还是从缓存中读取,可以使用 PageTransitionEvent 对象的 persisted 属性来判断。

window.addEventListener('pageshow', function(event) {
    console.log("PageShow Event  " + event.persisted);
    console.log(event)
})