webstorm编辑器

webstorm以下简称ws

一、更改webstorm使用时效;

下载完ws后,默认应该是英文版的,找到Help(帮助)里的register,如下图所示:

找到License server选项,并把图中的链接敲进去,点击Activate,然后重启ws编辑器,就不会出现使用时间的限制了。太赞了~~~

二、ws汉化

去网上下载ws对应版本的汉化包,找到你的webstorm的安装路径目录名称lib,然后把下载好的汉化包粘贴到
该目录下,然后重启ws即可。

三、ws中安装插件

通过步骤二想必你的ws编辑器已经是中文版的了,哈哈~~~点击文件中的设置属性,弹出的框中左侧有个Plugins,可搜索自己想要安装的插件。

持续更新中…

【vue报错】——listen EADDRINUSE :::8080 解决方案

原因:8080端口号被占用。

解决方法:

打开cmd,输入netstat —ano;

查看所有端口信息,如图,找到8080端口,以及对应的PID

输入tskill PID即可杀死进程。

到此本以为可以成功杀死进程,但被告知没有权限,接着往下走:

在cmd中输入tasklist,查看所有任务列表,找到如下图中的PID,

再输入tskill PID即可。

匿名函数自执行问题

今天遇到了以下这样一段代码,看到后一脸懵逼,脑中一片空白,不知如何下手,代码如下:

var test = (function(a){
    this.a = a;
    return function(b){
        return this.a + b;
    }
})((function(a,b){
    return a;
})(1,2));
console.log(test(4));

一步步剖析,一步步理解:

仔细看的话可以看到有两个自执行函数:(function(a))和(function(a,b)),下面这个自执行函数是

对比这样的函数:

(function(){})();
(function(参数){})(参数实例);

可以看出参数和参数实例是相等的,即参数实例就是该函数的参数;

所以以上代码可以理解为:function(a,b){}这个函数是function(a){}函数中的参数,即参数a = function(a,b){}中的返回值;

根据以上描述,可以得到(function(a,b){return a;})(1,2))函数返回值为a = 1;将a=1传入函数中,得到this.a = 1;

最后function(a){}自执行函数返回个函数给test变量;即test = function(b){return this.a + b};将test(4),将参数4带入函数中,得到1 + 4 = 5;

以上是我自己的理解;如果有其他的理解欢迎共享。

事件代理/委托

概述

事件委托就是利用事件冒泡,只指定一个事件处理程序,就可以管理某一类型的所有事件。

为什么要用事件委托

一般来说,DOM需要有事件处理程序,我们都会直接给它设事件处理程序就好了,那如果有很多的DOM需要添加事件处理呢?比如有100个li,每个li都有相同的click事件,可能我们会用for循环的方法来遍历所有的li,然后给它们添加事件,这么做会存在什么影响呢?

在javascript中,添加到页面上的事件处理程序数量将直接关系到页面的整体运行性能,因为需要不断的与DOM节点进行交互,访问DOM的次数越多,引起浏览器重绘与重排的次数也就越多,就会延长整个页面的交互就绪时间,这就是为什么性能优惠的主要思想之一就是减少DOM操作的原因;如果用时间委托,就会将所有的操作放到js程序里,与DOM的操作就只需要交互一次,就能大大的减少与DOM的交互次数,提高性能。

例子

一、子节点实现相同的功能:

<ul id="ul1">
    <li>111</li>
    <li>222</li>
    <li>333</li>
    <li>444</li>
</ul>

实现功能是点击li,弹出123:

window.onload = function(){
    var oUl = document.getElementById("ul1");
    var aLi = oUl.getElementsByTagName('li');
    for(var i=0;i<aLi.length;i++){
        aLi[i].onclick = function(){
            alert(123);
        }
    }
}

事件委托的方式:

window.onload = function(){
    var oUl = document.getElementById("ul1");
    oUl.onclick = function(){
        alert(123);
    }
}

这里用父级ul做事件处理,当li被点击时,由于冒泡原理,事件就会冒泡到ul上,因为ul上有点击事件,所以事件就会触发。

让事件代理的效果跟直接给节点的事件效果一样:

Event对象提供了一个属性叫target,可以返回事件的目标节点,我们成为事件源,也就是说,target可以表示为当前的事件操作的DOM,但不是真正的DOM,当然,这个是有兼容性的,标准浏览器用ev.targetIE浏览器用event.srcElement,此时只是获取了当前节点的位置,并不知道是什么节点名称,这里我们用nodeName来获取具体是什么标签名,这个返回的是一个大写的值,我们要转成小写(toLowerCase)再做比较:

window.onload = function(){
  var oUl = document.getElementById("ul1");
  oUl.onclick = function(ev){
    var ev = ev || window.event;
    var target = ev.target || ev.srcElement;
    if(target.nodeName.toLowerCase() == 'li'){
        	alert(123);
         alert(target.innerHTML);
    }
  }
}

二、子节点实现不同的功能:

<div id="box">
    <input type="button" id="add" value="添加" />
    <input type="button" id="remove" value="删除" />
    <input type="button" id="move" value="移动" />
    <input type="button" id="select" value="选择" />
</div>

js代码:

window.onload = function(){
    var Add = document.getElementById("add");
    var Remove = document.getElementById("remove");
    var Move = document.getElementById("move");
    var Select = document.getElementById("select");
    Add.onclick = function(){
        alert('添加');
    };
    Remove.onclick = function(){
        alert('删除');
    };
    Move.onclick = function(){
        alert('移动');
    };
    Select.onclick = function(){
        alert('选择');
    }
}

事件代理:

window.onload = function(){
    var oBox = document.getElementById("box");
    oBox.onclick = function (ev) {
    	var ev = ev || window.event;
        var target = ev.target || ev.srcElement;
        if(target.nodeName.toLocaleLowerCase() == 'input'{
            switch(target.id){
                case 'add' :
                    alert('添加');
                    break;
                case 'remove' :
                    alert('删除');
                    break;
                case 'move' :
                    alert('移动');
                    break;
                case 'select' :
                    alert('选择');
                    break;
            }
        }
    }  
 }

用事件委托就可以只用一次dom操作就能完成所有的效果;

我们可以发现,当用事件委托的时候,根本就不需要去遍历元素的子节点,只需要给父级元素添加事件就好了,其他的都是在js里面的执行,这样可以大大的减少dom操作,这才是事件委托的精髓所在。

关于javascript语法特性的变态题

1、

    (function () { 
        return typeof arguments; 
    })(); 

A. “object”
B. “array”
C. “arguments”
D. “undefined”

答案:”object”

**arguments 是对象,typeof类型是 “object” **

2、

var f = function g() {
    return 23;
};
typeof g();

A. “number”
B. “undefined”
C. “function”
D. Eorror

答案:Error

在 JS 里,声明函数只有 2 种方法:

第 1 种: function foo(){…} (函数声明)

第 2 种: var foo = function(){…} (等号后面必须是匿名函数,这句实质是函数表达式)

g 未定义,这里如果求 typeof g ,会返回 undefined。

3、

(function (x) {
    delete x;
    return x;
})(1);

A. 1
B. null
C. undefined
D. Error

答案:1

delete 不能删除变量,也不能删除函数,可以删除对象的属性。。

4、

var y = 1,
    x = y = typeof x;
x;

A. 1
B. “number”
C. undefined
D. “undefined”

答案:”undefined”

先定义了 y 并赋值为 1,然后将 typeof x 赋值给 y ,此时 x 未定义,故为 “undefined”,最后将 y 的值赋给 x。

5、

(function f(f) {
    return typeof f();
})(function () {
       return 1;
});

A. “number”

B. “undefined”

C. “function”

D. Error

答案:”number”

在函数里的 f() 其实是参数的那个 f 的执行结果,所以是 typeof 1,也就是 “number”。

6、

var foo = {
bar: function () {
    return this.baz;    
    },
       baz: 1
};
(function () {
    return typeof arguments[0]();
})(foo.bar);

A. “undefined”

B. “object”

C. “number”

D. “function”

答案暂略

7、

var foo = {
    bar: function(){ return this.baz; },
    baz: 1
  }
  typeof (f = foo.bar)();

A. “undefined”

B. “object”

C. “number”

D. “function”

答案:”undefined”

因为CallExpression是不带有上下文信息,this会指向global;
当你以foo.bar() 调用时,被调用的function是「MemberExpression」,而如果进行了f=foo.bar()赋值之后,那么function就会变成「CallExpression」了,因此this绑定就失效了。

8、

var f = (function f(){ return "1"; }, function g(){ return 2; })();
  typeof f;

A. “string”

B. “number”

C. “function”

D. “undefined”

答案:”number”

前面的函数被后面的覆盖。

9、

var x = 1;
if (function f(){}) {
    x += typeof f;
  }
  x;

A. 1

B. “1function”

C. “1undefined”

D. NaN

答案:”1undefined”

括号内的 function f(){} 不是函数声明,会被转换成 true ,因此 f 未定义。

10、

var x = [typeof x, typeof y][1];
typeof typeof x;

A. “number”

B. “string”

C. “undefined”

D. “object”

答案:”string”

第一行执行完后 x === “undefined” ,所以连续求 2 次 typeof 还是 “string”

11、

 (function(foo){
    return typeof foo.bar;
  })({ foo: { bar: 1 } });

A、“undefined”

B、“object”

C、“number”

D、Error

答案:”undefined”

typeof foo.bar 中的 foo 是参数,不多解释了。

12、

(function f() {
function f() {
    return 1;
}
return f();
function f() {
    return 2;
}
})();

A、1

B、2

C、Error (e.g. “Too much recursion”)

D、undefined

答案:2

由于声明提前,后面的 f() 会覆盖前面的 f()。

13、

function f(){ return f; }
new f() instanceof f;

A、true

B、false

答案:false

构造函数不需要显式声明返回值,默认返回this值。当显式声明了返回值时,如果返回值是非对象(数字、字符串等),这个返回值会被忽略,继续返回this值。但是如果返回值是对象,那么这个显式返回值会被返回。
因为 f() 内部返回了自己,故此时 new f() 的结果和 f 相等。

伪元素before,after,first-line,first-letter,selection

::before和::after

作用:相当于一个标签,在父标签内容之前/之后显示,可以添加文本:

<style>
    p::before{
            content:"hello";
    }
</style>
<p>我的博客</p>

页面显示的内容是“hello我的博客”。

这两个伪元素在内容为空时(content:””为必选,不可省略),可以当做span标签来使用,它们有span标签的所有属性,你也可以这样理解,它们两个是写在CSS里面的span标签。

first-line

作用:改变第一行文本样式,只能改变文本样式

first-letter

作用:改变第一个汉字或者英文字母的样式

selection

作用:选中文本内容时,改变文本颜色和背景颜色且只能改变这两个属性。

移动端的自适应方法

移动端的自适应方法

框架下载

https://github.com/amfe/lib-flexible

可使用上一篇文章中的git clone把相关文件下载到本地。

或者直接引用

<script src="http://g.tbcdn.cn/mtb/lib-flexible/{{version}}/??flexible_css.js,flexible.js"></script>

建议对于js做内联处理,在所有资源加载之前执行这个js。

执行这个js后,会在html(也就是document.documentElement)上增加一个data-dpr属性,以及font-size样式,可在网页操作台查看。

之后页面中的元素,都可以用rem单位来设置。html上的font-size就是rem的基准像素。

把视觉稿中的px转换成rem

首先,目前视觉稿大小分为640,750以及,1125这三种。

当前方案会把这3类视觉稿分成100份来看待(为了以后兼容vh,vw单位)。每一份被称为一个单位a。同时,1rem单位认定为10a。拿750的视觉稿举例:

1a = 7.5px
1rem = 75px

Vue中img的src属性

不少人在vue的开发中遇到这样一个问题: img的src属性绑定url变量,然而图片加载失败。

大部分的情况中,是开发者使用了错误的写法,例如:

<img src="{{ imgUrl }}"/>

这样写肯定是不对的,正确的写法应该使用v-bind:

<img v-bind:src="imgUrl"/>

不过,有时候即使使用了正确的语法,依旧无法显示图片,因为你的imgUrl使用了本地图片的路径。
例如,有下面一个文件结构:

现在,我们要在App.vue里使用位于src/assets/目录下的logo.png图片,于是,我们设:

imgUrl = './assets/logo.png'

奇怪的事情出现了,图片加载失败。查看网页源代码,发现一个错误:

看这个错误代码,我们发现,网页把根域名作为相对路径的根目录了,然而我们文件的路径是相对于项目文件的根目录的,当然就找不到了。

既然这样,那我们去找build后的dist文件夹。发现文件的结构是这样:

是不是说只要把url改成./static/img/logo.png就可以了呢?依然是不行的。打开img文件夹我们可以发现,所有的文件名后都被添加上了一个随机字符串,原始的文件名已经无法对应了。

那么,到底应该怎么加载本地图片呢?回头看vue-cli的文件结构,发现其中有一个叫做static的文件夹,尝试将logo.png放入这个文件夹,然后修改imgUrl:

imgUrl = '/static/logo.png'

成功读取到了logo.png. 执行npm run build后查看dist文件,发现logo.png原封不动地放在了根目录下。

原来,之前的目录结构是有问题的,图片一类的静态文件,应该放在这个static文件夹下,这个文件夹下的文件(夹)会按照原本的结构放在网站根目录下。这时我们再去使用/static绝对路径,就可以访问这些静态文件了。

一种方法
<img :src="imgUrl">

 data() {
    return {
      imgUrl: './static/img/logo.png'
 };
另一种方法

直接引用:

<img src="../static/img/logo.png">

word-break和word-wrap区别

word-wrap:

css的 word-wrap 属性用来标明是否允许浏览器在单词内进行断句,这是为了防止当一个字符串太长而找不到它的自然断句点时产生溢出现象。

word-break:

css的 word-break 属性用来标明怎么样进行单词内的断句。

看图更直接: