2

一、iOS上浏览器使用jQuery不允许事件代理到document上

$(document).on("click", "选择器", function(){});

以上绑定可能会出现点击失效的情况。解决方法就是在这些代码前加一串代码:

$(body>*).bind("click", function(){....});

二、移动端点击输入框(input)禁止手机输入法键盘弹出

在移动端页面开发时,我们有时候经常会用到自己定义的输入键盘,而不想自带键盘弹出,那么可以在点击事件中加入以下代码:

$("选择器").click(function(){ document.activeElement.blur(); });

三、在iOS平台上input的button类型会带有默认样式。

这个在Android上使用以下代码就可以解决,但是iOS不起作用。

border: none;
outline: none;
background-color: 颜色;

但是在iOS上需要加一个:

-webkit-appearance: none;

这个属性同样适用于Android。

四、移动端Retina屏(iOS) 1px的解决方案

这个我在网上找到许多解决方案,这里就直接放链接了


移动端 Retina屏 各大主流网站1px的解决方案
如何在Vue项目中使用vw实现移动端适配

五、iOS浏览器在设置overflow: scroll;后滑动不流畅,感觉像是卡顿

这个目前在Android和PC上没得问题,但是iOS上有问题,解决方法就是加上属性:

-webkit-overflow-scrolling: touch;

参考资料:

【兼容性】ios上设置overflow: scroll不滚动bug
iOS Safari浏览器上overflow: scroll元素无法滑动bug解决方法整理
iOS safari浏览器上overflow: scroll元素无法滚动bug深究
解决页面使用overflow: scroll在iOS上滑动卡顿的问题

六、元素在设置为display:inline-block;后元素之间会产生间距

解决方法就是在包含这些元素的父元素上设置CSS属性font-size: 0;

七、Angular CLI和Vue CLI打包的项目上线不在根目录出现资源找不到问题!

  • 对于ng,在package.jsonbuild后面改成ng build --base-href ./
  • 对于Vue,如果CLI工具是3.3以下版本,在vue.config.js中加入以下代码:
module.exports = {
  baseUrl: process.env.NODE_ENV === 'production'
    ? '/henjievue/'
    : '/'
}
3.3以上的版本加入以下代码:
module.exports = {
  publicPath: process.env.NODE_ENV === 'production'
    ? '/henjievue/'
    : '/'
}

八、Angular CLI开发对于assets文件的处理问题。

assets文件夹里面的内容在build后不参与打包,仅仅完整复制,所以在开发过程中路径的写法按绝对路径写就好了,如下代码:

<img src="assets/index/ng.png">

九、解决ios10及以上Safari无法禁止缩放的问题

//以下代码是为了解决在iOS 10系统之后设置meta来禁止缩放失效的问题
      window.onload = function() {
        // 阻止双击放大
        document.addEventListener('touchstart', function(event) {
            if (event.touches.length > 1) {
                event.preventDefault();
            }
        });
        var lastTouchEnd = 0;
        document.addEventListener('touchend', function(event) {
            var now = (new Date()).getTime();
            if (now - lastTouchEnd <= 300) {
                event.preventDefault();
            }
            lastTouchEnd = now;
        }, false);

        // 阻止双指放大
        document.addEventListener('gesturestart', function(event) {
            event.preventDefault();
        });
      }

这个缩放有点问题就是在滚动页面的时候如果使用双指缩放是可以放大的,解决方法是给最外层的div(这儿我以vue开发单页面为例)设置一个样式,这个#app在index.html中设置即可

#app {
  overflow-x: hidden;
  -webkit-overflow-scrolling: touch; /* 加这个是为了滚动流畅 */
}

十、在最新的Vue脚手架工具下(3.x以上)使用2.x脚手架使用的搭建目录

在安装好最新的vue脚手架情况下,使用以下命令来安装一个额外工具:

npm install -g @vue/cli-init

之后就可以使用以下命令生成老的项目目录:

vue init webpack 项目名

十一、Vue CLi 3.0脚手架工具关闭ESlint检查

在vue.config.js中加一句话:

module.exports = {
  baseUrl: process.env.NODE_ENV === 'production'
    ? '/henjievue/'
    : '/',
  lintOnSave: false //加这句话可以关闭ESlint
}

十二、JS的循环里面有异步请求如何保证异步请求按次序执行

这个不能用循环来解决,应该用递归来实现,或者用Promise.all来实现,这里仅提供递归解决方法。

(function loop(index){
  axios.get("http://192.168.12.101:3000/news/list"+"?pageNum="+page[index]).then((response)=>{
    console.log(response);
    if(++index < page.length){
      loop(index);
    }
    else{
      console.log("全部执行完毕")
    }
  }).catch((error)=>{
    console.log(error);
  })
})(0)

十三、vue里面路由的路由守卫的beforeRouteEnter的钩子函数无法获取到vue实例(this)

这个钩子函数里不能直接使用this来获取vue实例,或者报undefined错误,解决方法如下:

const Foo = {
  template: `...`,
  beforeRouteEnter (to, from, next) {
    // 在渲染该组件的对应路由被 confirm 前调用
    // 不!能!获取组件实例 `this`
    // 因为当钩子执行前,组件实例还没被创建
  },
  beforeRouteUpdate (to, from, next) {
    // 在当前路由改变,但是该组件被复用时调用
    // 举例来说,对于一个带有动态参数的路径 /foo/:id,在 /foo/1 和 /foo/2 之间跳转的时候,
    // 由于会渲染同样的 Foo 组件,因此组件实例会被复用。而这个钩子就会在这个情况下被调用。
    // 可以访问组件实例 `this`
  },
  beforeRouteLeave (to, from, next) {
    // 导航离开该组件的对应路由时调用
    // 可以访问组件实例 `this`
  }
}
//以上为解释。以下为解决方法
beforeRouteEnter(to, from, next){ 
    next((vm)=>{
        console.log(vm);
        if(from.path == '/'){
            vm.isShowAppr = false;
        }
    });
},

十四、在Chrome浏览器下img标签在没有图片的情况下会显示边框的问题?

解决方法如下,添加一段css代码即可:

img[src=""], img:not([src]){
    opacity: 0;
}

十五、v-if绑定一个数组变量,改变变量的值并没有使v-if起作用

问题:当v-if绑定一个数组变量,改变变量的值并没有使v-if起作用。引出个问题由于 JavaScript 的限制,Vue 不能检测以下变动的数组:
1.当你利用索引直接设置一个项时
2.当你修改数组的长度时
原因:网上总结:

  1. Vue检测数据的变动是通过Object.defineProperty实现的,所以无法监听数组的添加操作是可以理解的,因为是在构造函数中就已经为所有属性做了这个检测绑定操作。
  2. Vue 中是通过对 每个键设置 getter/setter 来实现响应式的,开发者使用数组,目的往往是遍历,此时调用 getter 开销太大了,所以 Vue 不在数组每个键上设置,而是在数组上定义 ob ,并且替换了 push 等等能够影响原数组的原型方法。从vue源码可以清晰看到,Vue 跳过了对数组每个键设置响应式的过程,而是直接对值进行递归设置响应式。

    解决:
    
    第一类问题:
    Vue.set(vm.items, indexOfItem, newValue)
    vm.items.splice(indexOfItem, 1, newValue)
    vm.$set(vm.items, indexOfItem, newValue)
    eg: this.$set(this.isShowOKimg, index, true);
    第二类问题:
    vm.items.splice(newLength)

    v-if绑定一个数组变量,改变变量的值并没有使v-if起作用

    十六、表单中onchange事件的触发条件

    input输入框的onchange事件,要在 input 失去焦点的时候才会触发;在输入框内容变化的时候不会触发change,当鼠标在其他地方点一下才会触发;onchange 事件也可用于单选框与复选框改变后触发的事件。

    onchange event 所有主要浏览器都支持;
    onchange 属性可以使用于:<input>, <select>, 和 <textarea>。

  3. input事件
    oninput 事件在用户输入时触发,它是在元素值发生变化时立即触发;该事件在 <input> 或 <textarea> 元素的值发生改变时触发。
  4. onpropertychange事件
    onpropertychange会实时触发,会在元素的属性改变时就触发事件。当元素disable=true时不会触发。缺陷:只在IE 下支持,其他浏览器不支持,用oninput来解决。

input输入框的input事件和change事件

十七、vue中this.$route与this.$router的区别

1、this.$router

全局的路由实例,是router构造方法的实例。在 Vue 实例内部,你可以通过 $router 访问路由实例,

  • 注意this.$route和this.$router均不能在使用Vue.extend()构造器所构造的弹框等实例里面取到

有go、push、replace、forward等方法
1、this.$router.push()
// 字符串
      this.$router.push('home')
// 对象
      this.$router.push({ path: 'home' })
// 命名的路由
      this.$router.push({ name: 'user', params: { userId: 123 }})
// 带查询参数,变成 /register?plan=123
      this.$router.push({ path: 'register', query: { plan: '123' }})
2、this.$router.replace()
    同样是跳转到指定的url,但是这个方法不会向history里面添加新的记录,点击返回,会跳转到上上一个页面。上一个记录是不存在的。
3、this.$router.go()
    相对于当前页面向前或向后跳转多少个页面,类似 window.history.go(n)。n可为正数可为负数。正数返回上一个页面

2、this.$route

表示当前激活的路由的状态信息,包含了当前 URL 解析得到的信息,还有 URL 匹配到的 route records(路由记录)。路由信息对象:即$router会被注入每个组件中,可以利用它进行一些信息的获取。
**1.$route.path**
      字符串,对应当前路由的路径,总是解析为绝对路径,如 "/foo/bar"。
**2.$route.params**
      一个 key/value 对象,包含了 动态片段 和 全匹配片段,
      如果没有路由参数,就是一个空对象。
**3.$route.query**
      一个 key/value 对象,表示 URL 查询参数。
      例如,对于路径 /foo?user=1,则有 $route.query.user == 1,
      如果没有查询参数,则是个空对象。
**4.$route.hash**
      当前路由的 hash 值 (不带 #) ,如果没有 hash 值,则为空字符串。锚点
**5.$route.fullPath**
      完成解析后的 URL,包含查询参数和 hash 的完整路径。
**6.$route.matched**
      数组,包含当前匹配的路径中所包含的所有片段所对应的配置参数对象。
**7.$route.name    当前路径名字**
**8.$route.meta  路由元信息


router.beforeEach((to, from, next) => {
  // to 和 from 都是 路由信息对象
})
watch: {
  $route(to, from) {
     // to 和 from 都是 路由信息对象
  }
}
this.$router的内容就是new VueRouter({})实例出来的对象(这个在router.js里面会创建并导出),他们两个是相同的。

十八、部分ios系统在键盘收回时不会将顶起的页面自动收回

在input的上加一个blur时间,这里以vue为例,其它类似

<input @blur="autoscrollBack" v-model="code" type="text" placeholder="请输入6位验证码">

autoscrollBack(){
    window.scroll(0, 0); //自动滚回
}

十九、节流和防抖

1、节流代码

    function throttle(callback, timeSolt){
        var last_time = 0;
        return function(){
            let context = this;
            let args = arguments;
            let now = new Date();
            if(now - last_time >= timeSolt){
                last_time = now;
                callback.apply(context, arguments);
            }
        }
    }
    document.addEventListener('scroll', throttle((e)=>{
        console.log(e.target) //输出#document
        console.log(this) //输出window对象
    }, 2000), false);
    注:其实上面addEventListener的回调函数最终执行的是throttle返回的函数

2、防抖代码

    function debounce(callback, timeSolt){
        let timer;
        return function(){
            let context = this;
            let args = arguments;
            if(timer){
                clearTimeout(timer);
            }
            timer = setTimeout(function(){
                callback.apply(context, args);
            }, timeSolt)
        }
    }

    document.addEventListener('scroll', debounce((e)=>{
        console.log(e.target) //输出#document
        console.log(this)     //输出window对象
    }, 2000), false)

3、防抖节流结合版

    function throttle_and_debounce(callback, timeSolt){
        let last_time;
        let timer;
        return function(){
            let context = this;
            let args = arguments;
            let now = new Date();
            if(now - last_time < timeSolt){
                clearTimeout(timer);
                timer = setTimeout(function(){
                    last_time = now;
                    callback.apply(context, args);
                }, timeSolt)
            }else{
                last_time = now;
                callback.apply(context, args);
            }
        }
    }
    document.addEventListener('scroll', throttle_and_debounce((e)=>{
        console.log(e.target) //输出#document
        console.log(this)     //输出window对象
    }, 2000), false)

二十、Js event对象offsetX, clientX, pageX, screenX, layerX, x区别

图片描述
图片描述
图片描述
图片描述
参考资料

二十一、offsetWidth, clientWidth, scrollWidth, innerWidth, outerWidth, pageXOffset等

图片描述
1、无滚动条时,dom对象的offsetWidth、clientWidth和scrollWidth等
图片描述
图片描述
2、有滚动条时,dom对象offsetWidth、clientWidth 和 scrollWidth等
图片描述
图片描述
3、window对象的 outerWidth、innerWidth、pageXOffset 和 screenLeft(screenX)
图片描述
参考资料
参考资料

二十二、vscode设置终端类型

1、命令面板(Ctrl+Shift+P)中,输入select选如图所示的选项
图片描述
2、之后选择目标Shell。
图片描述
参考资料

二十三、为git和github desktop设置代理

1、为git设置代理,这里以设置http协议为例,ssh暂未研究
在需要使用代理的项目下面使用 git bash 如下命令进行设置,我这里代理是127.0.0.1:8080

git config http.proxy http://127.0.0.1:8080 # 也可以是uri:port形式
这个是不需要鉴权的代理设置,如果需要鉴权,可能需要添加用户名密码信息:
git config http.proxy http://username:password@127....
如果git的所有项目都需要启用代理,那么可以直接启用全局设置:
git config --global http.proxy http://127.0.0.1:8080
为了确认是否已经设置成功,可以使用 --get 来获取:
git config --get --global http.proxy
这样可以看到你设置在global的 http.proxy 值。 需要修改的时候,再次按照上面的方法设置即可,git默认会覆盖原有的配置值。当我们的网络出现变更时,可能需要删除掉原有的代理配置,此时需要使用 --unset 来进行配置:
git config --global --unset http.proxy
在命令之后,指定位置的设置值将会被清空,你可以再次使用 --get 来查看具体的设置情况。如果使用了HTTPS,肯呢个会碰到HTTPS 证书错误的情况,比如提示: SSL certificate problem 。。。,此时,可以尝试将 sslVerify 设置为 false :
git config --global http.sslVerify false
到此设置完毕。

参考资料

2、为github desktop设置代理
这个设置起来相对简单,以win 10为例,找到以下路径C:\Users\你的用户名,找到名为.gitconfig文件,添加以下内容:

[http]
    proxy = http://127.0.0.1:8080

设置完成后保存即可。
参考资料

二十四、css实现单行、多行文本溢出显示省略号的方法

1、单行省略号

overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
注:这种方式一般都需要给固定宽度

2、多行省略号(这个属性只合适WebKit浏览器)

dispaly: -webkit-box;
-webkit-box-orient: vertical;
text-overflow: ellipsis;
-webkit-line-clamp: 2; //这个显示几行
overflow: hidden;

3、多浏览器兼容方案

p {
    position:relative;
    line-height:1.4em; //要显示三行的话那么元素的高度就是行高的3倍,其它情况以此类推。
    /* 3 times the line-height to show 3 lines */
    height:4.2em;
    overflow:hidden;
}
p::after {
    content:"...";
    font-weight:bold;
    position:absolute;
    bottom:0;
    right:0;
    padding:0 20px 1px 45px;

}

参考资料

二十五、JS里面生成随机整数

首先要了解几个函数

1、Math.random()生成[0, 1)之间的数。
2、Math.round()将小数四舍五入。
3、Math.floor()下取整。
4、Math.ceil()上取整。

1、生成[min, max]之间的整数。

var result = Math.round(Math.random() * (max - min)) + min;

2、生成[min, max)之间的整数。

var result = Math.floor(Math.random() * (max - min)) + min;

3、生成(min, max]之间的整数。

var result = Math.ceil(Math.random() * (max - min + 1)) + min;

3、生成(min, max)之间的整数。

var result = Math.floor(Math.random() * ((max-1) - (min+1))) + (min+1);相当于 min+1 ≤ r ≤ max - 1

参考资料
参考资料

二十六、Babel相关的概念

  • @babel/core: babel的核心,核心的api都在包含在这里。
  • @babel/cli: 命令行工具,通过命令对js文件进行转换的工具。
  • @babel/perset-env: 指定转换的工作环境。
  • @babel/polyfill: 相当于一个填充,因为babel本身只支持转换箭头函数、结构赋值这些语法糖类的语法,而一些新的API或者Promise函数等是无法转换的。@babel/polyfill就是解决这个问题的。
  • babel-loader: webpack的加载器,用于调用@babel/core的核心API来完成编译。
    1、@babel/core与babel-core区别

    @babel/core是babel 7过后的版本标识,babel-core是以前版本的标识。

    2、.babelrc和babel.config.js

    .babelrc和babel.config.js均是babel的配置文件,babel.config.js是bebel 7引入的新的方式。
    3、@babel/polyfill和@babel/plugin-transform-runtime和@babel/runtime和@babel/runtime-corejs2(都是用来转换新Api的)
  • (1)@babel/polyfill:babel-polyfill则是通过改写全局prototype的方式实现,比较适合单独运行的项目。开启babel-polyfill的方式,可以直接在代码中require,或者在webpack的entry中添加,也可以在babel的env中设置useBuildins为true来开启,但是babel-polyfill会有近100K,打包后代码冗余量比较大,对于现代的浏览器,有些不需要polyfill,造成流量浪费污染了全局对象。

    //使用方法一在entry中添加
    module.exports = {
      entry: {
          main: ["@babel/polyfill", path.resolve(__dirname, "./src/index.js")]
      }
    }
    //使用方式二babel.config.js中设置
    module.exports = {
      presets: [
          "@babel/preset-env", { "useBuiltIns": true }
      ]
    }

  • (2)@babel/runtime和@babel/plugin-transform-runtime:babel-runtime和 babel-plugin-transform-runtime的区别是,相当一前者是手动挡而后者是自动挡,每当要转译一个api时都要手动加上require('babel-runtime'),而babel-plugin-transform-runtime会由工具自动添加,主要的功能是为api提供沙箱的垫片方案,不会污染全局的api,因此适合用在第三方的开发产品中。

  • (3)@babel/runtime-corejs2:plugin-transform-runtime 可以设置成 false 或者 2,在babel.config.js的配置文件下有以下代码:

    module.exports = {
      preset: ["@babel/preset-env"],
      plugins: [
          "@babel/plugin-transform-runtime", { corejs: 2 }
      ]
    }
    1、corejs 是一个给低版本的浏览器提供接口的库,如 Promise, map, set 等。在 babel 中你设置成 false 或者不设置,就是引入的是 corejs 中的库,而且在全局中引入,也就是说侵入了全局的变量。
    2、如果你的全局有一个引入,不要让引入的库影响全局,那你就需要引把 corejs 设置成 2。
    所以一旦你使用了2这个参数就必须引入@babel/runtime-corejs2
    3、@babel/plugin-transform-runtime是必须装的,如果corejs设置为2的话安装@babel/runtime-corejs2来代替@babel/runtime,反正设置为false的话就需要@babel/runtime,根据你的设置来安装即可。

    在babel 7下:

  • babel.config.js 是对整个项目(父子package) 都生效的配置,但要注意babel的执行工作目录。
  • .babelrc 是对 待编译文件 生效的配置,子package若想加载.babelrc是需要babel配置babelrcRoots才可以(父package自身的babelrc是默认可用的)。
  • 任何package中的babelrc寻找策略是: 只会向上寻找到本包的 package.json 那一级。
  • node_modules下面的模块一般都是编译好的,请剔除掉对他们的编译。如有需要,可以把个例加到 babelrcRoots 中。

    默认情况下.babelrc不作用于子包,那么在babel.config.js下加入一下babelrcRoots来指定即可。

      module.exports = {
        babelrcRoots: ['.', './frontend', './backend'] // 允许这两个子 package 加载 babelrc 相对配置
      }

    一文读懂 babel7 的配置文件加载逻辑
    对babel-transform-runtime,babel-polyfill的一些理解
    babel7中 corejs 和 corejs2 的区别
    babel preset env配置
    babel学习笔记

二十七、window.scrollTo(x, y)与window.scrollBy(x, y)区别。

1.scrollTo()是绝对位置滚动,每次都是相对初始位置(0, 0)位置滚动。
2.scrollBy()是相对位置滚动,相对于上次移动的最后位置移动。
3.window.scrollX是文档在x方向的滚动距离,返回文档/页面水平方向滚动的像素值。
4.window.scrollY是文档在y方向的滚动距离,返回文档/页面垂直方向滚动的像素值。
5.window.scroll()效果跟scrollTo效果相同。

  • 注:目前在Chrome上测试window.scrollY获取到的值跟document.documentElement.scrollTop的一样。只不过scrollY是只读属性,不能修改值,而scrollTop可以修改。

二十八、iOS 12在新iPhone上收起输入法后页面不会自动恢复滚动到初始位置(十八的方案用户体验不太好,每次都会滚到顶部去)

this.$refs.drawnameInput.addEventListener('blur', function(){
    var currentPosition;
    var speed=1;//页面滚动距离
    currentPosition=document.documentElement.scrollTop || document.body.scrollTop;
    currentPosition-=speed; 
    window.scrollTo(0,currentPosition);//页面向上滚动
    currentPosition+=speed; //speed变量
    window.scrollTo(0,currentPosition);//页面向下滚动
})

二十九、防止页面被调试的JS代码

        //添加debuger进行反调试
        (function anti_debuger(){
            function testDebuger(){
                var d=new Date();
                debugger;
                if(new Date()-d>10){
                    document.body.innerHTML='<div>年轻人,不要太好奇</div>';
                    return true;
                }
                return false;
            }
         
            function start(){
                while(testDebuger()){
                    testDebuger();
                }
            }
            if(!testDebuger()) {
                window.onblur = function(){
                    setTimeout(function(){
                        start();
                    },500)
                }
            }
            else{
                start();
            }
        })();

如何防止页面被调试

三十、移动端唤起QQ聊天 (ios android 包含微信、qq内置浏览器,不兼容ios10及以下版本(window.open()改成location.href=''这种就不会存在兼容性问题))(本人测试为ios safari跳转到QQ没问题)

        var u = navigator.userAgent;
        var isiOS = !!u.match(/\(i[^;]+;( U;)? CPU.+Mac OS X/);
        if(isiOS){
          //uin=这个部分就是你要聊天的QQ号
          if(u.toLowerCase().match(/MicroMessenger/i) == "micromessenger"){
            window.open('http://wpa.qq.com/msgrd?v=3&uin=2290747606&site=qq&menu=yes');
          }else{
            window.open('mqqwpa://im/chat?chat_type=wpa&uin=2290747606&version=1&src_type=web&web_src=oicqzone.com')
          }
        }else{
          if(u.toLowerCase().match(/MicroMessenger/i) == "micromessenger"){
            window.open('http://wpa.qq.com/msgrd?v=3&uin=2290747606&site=qq&menu=yes');
          }else{
            window.open('mqqwpa://im/chat?chat_type=wpa&uin=2290747606&version=1&src_type=web&web_src=oicqzone.com');
          }
        }

三十一、移动端指定的时间格式。

移动端在使用new Date()生成指定时间的时间戳时,里面的格式有要求,否则不能正确获取。
var time = new Date('2019/9/18 18:00') //这个里面不要使用2019-9-18这种格式,PC端的虽然可以正常识别。

在IOS平台慎用Date.parse()方法,这个在ios上支持不好,会失效!

三十二、ES5默认参数写法的弊端

function testDef(name, age){
    var name = name || 'default';
    var age = age || 23;
    console.log(name, age);
}
testDef('Lee', 0);

像上面那样你传的0过去,但是Js里面0判定为false,它会把23赋给age,而得不到传入的值0。科学方法是使用ES6的方式

function testDef(name='default', age=23){
    var name = name;
    var age = age;
    console.log(name, age);
}
testDef('Lee', 0);

三十三、VSCode编译器类名使用横杠-双击无法选中全部单词的解决方法

搜索设置editor.wordSeparators。找到`~!@#$%^&*()-=+[{]}\\|;:'\",.<>/?。去掉横杠即可!

三十四、Vue父组件下的子组件强制重新加载数据

父组件下的子组件的内容默认情况不会强制刷新(主要是利用history返回到这个页面的情况下),实现方法入下。

    //data中定义一个变量
    isReload: false
    //子组件处用v-if来判断是否重新渲染
    <app-child v-if="isReload"></app-child>
    //使用watch来监听父组件里面会发生变化的变量,如从后端返回的数据user
    watch: {
        user(){
            this.isReload = false;
            this.$nextTiock(() => {
                this.isReload = true;
            })
        }
    }

三十五、document.documentElement与document.body

document.documentElement表示获取到html,document.body表示获取到body。当页面声明了DOCTYPE(DTD),使用document.body.scrollTop获取不到页面滚动的距离,就必须使用document.documentElement.scrollTop来获取。

  • 完美的获取scrollTop 赋值短语 :var scrollTop = document.documentElement.scrollTop || window.pageYOffset || document.body.scrollTop;

三十六、IOS Safari里面异步ajax请求最好不要再写异步请求,容易出意想不到的问题。

比如下面这种:

    axios.get('/index').then((res)=>{
        cosole.log(res);
        axios.get.('/index/extra').then((res)=>{
            console.log(res);
        })
    })

三十七、vue css样式里面使用scoped的坑

在使用了scoped的关键字后会出现css样式覆盖不生效的情况,比如:
使用了v-html注入一段代码<span class="style-color">爱爱爱</span>,在当前页面写有样式:

  .style-color: {
    color: #fff;
  }

上述情况并不会生效,因为scoped情况下为类添加了一个类似[data-v-1ad6e6f7]特殊字符来保障唯一性。
解决方法就是:在static或者public的css样式文件下来写样式,这样不会注入特殊关键字符

三十八、VSCode里面开启在JSX(react)下可以自动补全html标签

打开VSCode,找到设置,然后搜索Emmet.Include Lanuage,找到在settings.json中编辑,在json文件中加入这句:

"emmet.includeLanguages": {
    "javascript": "javascriptreact"
},

三十九、解决启动VSCode初期cpu占用过高问题(rg.exe)

在设置里面搜索search.followSymlinks,找到后取消勾即可,或者直接在settings.json文件(这个文件可以在上面三十八方法里面找到,滑稽)里面加入:

"search.followSymlinks": false

四十、关于axiospost请求的问题

默认情况下,axios的post请求的参数是json形式,传递到后端是大多数情况没有问题,(这个在node.js里面因为有body-parser的原因,使用post请求加req.body的形式可以直接取到参数)比如这样:

axios.post('/login', {uname: uname, upwd: upwd}).then((res) => {})

但是如果后端是处理application/x-www-form-urlencoded这种的话,就必须对前端参数进行序列化,使用qs这个模块来实现

npm i qs -S

import qs from 'qs'

axios.post('/login', qs.stringify({uname: uname, upwd: upwd})).then((res) => {})

这样做了过后,在后端不使用body-parser的中间件(node.js为例)也可以取到参数了

关于 Axios Post 请求的坑
使用axios的post请求,请求参数好像有问题啊
axios用post提交的数据格式

四十一、addEventListener的第三个参数作用

<div id="s1">
  <div id="s2"></div>
</div>

第三个参数 false 和 true 分别对应 事件冒泡 和 事件捕获
假设上面的代码, s1和s2都用addEventListener绑定了点击事件
当false时, 点击s2, 则先执行s2, 再执行s1, 即从点击的元素开始往父级冒泡
当true是, 点击s2, 则先执行s1, 再执行s2, 即按document -> html -> body -> s1 -> s2的顺序捕获

四十二、当元素使用了弹性布局flex后元素里面的文字长度超过元素宽度不会再自动换行。

解决这个问题需要使用一个css属性,在展示文字的元素里面使用以下代码即可:

overflow-wrap: break-word; /* flex布局下文字不会自动换行,需要加这个属性 */

四十三、如何判断JS对象为空

1.1 使用JSON.stringify()

把JS对象转换为JSON字符串再比较

    let a = {name: 'lee'};
    if(JSON.stringify(a) === '{}'){
        console.log('这是空对象');
    }else {
        console.log('这不是是空对象');
    }

2.1 使用for in

利用for in的特性,如果不是空对象,那一定会进循环部分里面

    let a = {};
    let isEmptyObj = true;
    for(let key in a) {
        isEmptyObj = false;
    }
    if(isEmptyObj === true) {
        console.log('这是空对象');
    }else {
        console.log('这不是空对象');
    }

2.3 使用ES6 Object.keys

Object.keys() 方法会返回一个由给定对象的自身可枚举属性组成的数组。 如果我们的对象为空,他会返回一个空数组

    let a = {name: 'lee'};
    if(Object.keys(a).length === 0) {
        console.log('这是一个空对象');
    }else {
        console.log('这不是一个空对象');
    }

四十四、iOS safari的表单元素问题

在ios safari上面如果你在表单元素上将disabled属性开启,那么除了不能输入外,默认的value值以及placeholder的值都不能显示,在chrome上就不会有这个问题,所以在ios safari上要阻止输入最好用readonly属性不要用disabled。

四十五、使用Scss时如果使用node-sass时出现报错,如找不到python之类的。

这种大多数情况都是因为下载node-sass超时引起的安装错误,解决方法就是使用其它安装源代替。输入以下命令,使用淘宝镜像:

npm i node-sass --sass\_binary\_site=https://npm.taobao.org/mirrors/node-sass/

参考地址

四十六、使用html的script标签的代码若使用了import语法会报错。

报错信息为:

Uncaught SyntaxError: Cannot use import statement outside a module

解决方法是在script标签上加上一个属性type="module"

<script type="module" src="./2.js"></script>

四十七、iOS Safari在ajax回调函数里面使用window.open()会失效

在一些ajax或者jquery的getjson等回调代码中只要调用window.open都失效。原因是苹果的安全策略拦截。

解决方案


(1)用window.location.replace()来替代,【或者改变location.href,可以解决,缺点就是不是新开的窗口】

(2)苹果系统设置,偏好设置->安全性,去掉阻止弹窗的复选框就ok了。 【不建议,会改变用户的设置】

(3)在回到函数中生成一个链接,让用户再次点击下,因为链接是无论如何不会被拦截的。【不建议,多加了一个动作】

(4)在回调代码之前打开一个空窗口,例如 var w=window.open(xxx); 然后在回调函数中设置它的location。


参考资料

四十八、Windows 10使用Powershell运行脚本提示无权限(比如使用create-react-app)

首先找到以下路径C:\\Windows\\System32\\WindowsPowerShell\\v1.0,找到powershell.exe,右键以管理员身份运行。

输入以下命令Set-ExecutionPolicy RemoteSigned

之后会提示,输入Y回车即可。

设置margin:auto使块级元素居中,但是水平方向出现了滚动条,body没有占满浏览器窗口。

图片描述

//HTML代码
<div id="smart">
    <div class="smart-container-one">
        <p style="position: relative; left: 600px;"><img src="img/lazyload-b3704113c8.gif"/></p>
    </div>
</div>

//CSS代码
#smart>.smart-container-one {
    width: 1240px;
    height: 450px;
    margin: auto;
}

出现这样的结果就是由于<p style="position: relative; left: 600px;"><img src="img/lazyload-b3704113c8.gif"/></p>造成的,p元素是块级元素,定位如果为relative的话会占用位置,导致父元素被撑开了。

解决方法有:
1.给p元素设置绝对定位position: absolute即可。
2.p元素换成内联元素,如span
3.把p元素设置为内联元素,如display: inline

注:这儿p标签包img太业余了,大家平时写不要这样写,一般用div,菜鸟一枚,还请大家见谅。

ReferenceError
3 声望0 粉丝