前端海底捞不定期跟新

2017年8月

1,ES6 Map和Set

Map

ES6中新增的数据类型,类似PHP中的键值对形式结构

var m = new Map([['a',1],['b',2],['c',3]]);

m.get('a'); //1

m.set('d',4); //新增

Set

ES6中新增了Set数据结构,类似于数组,但是它的成员都是唯一的,其构造函数可以接受一个数组作为参数

let array = Array.from(newSet([1,1,1,2,3,2,4]));
//Array.from函数可以实现set-->Array的转化
console.log(array);// => [1, 2, 3, 4]

2,MVVM

angular,js
脏检查模式:在angular中当触发某些执行条件时(如change,input等),执行一个检测轮询,来遍历所有数据,对比更改的地方,然后执行变化,响应到DOM
因为此方法不科学,有很多多余的遍历,故称为脏检查
vue.js
数据劫持:在ES5中定义了一个名为"属性描述符的对象",可以通过Object.getPropertyDescriptor()来查询,getPropertyDescriptor接收一个对象,和对象上的某个属性两个参数,查询该属性的四个描述符状态,如:

Object.getPropertyDescriptor({x:1},x);
//返回该属性的值,可写性,可枚举性和可配置性
{
          value:1,
          writable:true,
          enumeable:true,
          configurable:true
}

而需要设置,修改这些特性时,使用Object.defineProperty。在vue vm中通过Object.defineProperty()对需要监听的每个对象属性设置getter和setter,每当对象属性的数据发生变更时,触发setter的函数(劫持),在setter中通知所有的订阅者,watcher监听到变化之后更新视图

函数节流

「函数节流让一个函数只有在你不断触发后停下来歇会才开始执行,中间你操作得太快它直接无视你。」
为了节制某些函数的执行频率,在触发时设置setTimeout,如果短时间内再次触发,清除上一个定时器,设置新的定时器。

function throttle(method, context) {
     clearTimeout(methor.tId);
     method.tId = setTimeout(function(){
         method.call(context);
     }, 100);
 }
//接收一个函数和一个上下文(函数执行上下文为非必选参数),将定时器设为该函数的一个属性,100ms内再次调用这个函数将清除并重新设置定时器
//调用
window.onresize = function(){
    throttle(myFunc);
}
//摘自js高程

2017年9月

1,获取浏览器窗口大小

//PC
var pageWidth = document.documentElement.clientWidth || document.body.clientWidth;
pageHeight = document.documentElement.clientHeight || document.body.clientHeight;
//移动设备中,除了以上方法window.innerWidth || window.innerHeight都保存着可见视口信息

2,常见的POST数据提交方式

application/x-www-form-urlencoded:浏览器的原生表单提交,若不设置参数格式,默认就为application/x-www-form-urlencoded,后端可以方便读取
multipart/form-data:常用于文件上传,于表单和请求头中设置
application/json:这种方案,可以方便的提交复杂的结构化数据,特别适合 RESTful 的接口。各大抓包工具如 Chrome 自带的开发者工具、Firebug、Fiddler,都会以树形结构展示 JSON 数据,非常友好。

3,前端安全XSS和CRSF

XSS,跨站脚本攻击,全称cross-site scripting,使用js脚本注入的方式攻击网站。

防范:
1,过滤转义输入输出,若输入输出中带有<script>等标签,将不会被执行。
2,通信cookie使用httponly属性,防止被读写.

CRSF,跨站请求伪造,伪造请求发送到服务器

防范:
1,防止登录的session长时间储存在客户端中,设置reprice
2,检测请求域名
3,关键请求使用验证码

4,CSS中的box-sizing

box-sizing用于设置盒模型的模式
其中属性
context-box:(默认值)标准盒模型,border和padding不计入元素width中,一个块的总宽度等于margin+padding+border+width
border-box:IE怪异盒模型,border和padding计入width中,一个块的总宽度等于margin+width
padding-box:padding计算入width内

5,H5语义化标签

标签写得语义化有助于SEO,搜索引擎易检索查到。
充分利用各种HTML标签完成他们本职的工作。

h5.png

6,创建对象方式

1,对象字面量 var obj = {a:1}
2,构造函数创建对象 var obj = new Function()
3,对象原生方法创建 var obj = Object.create({})

7,New一个新对象时发生了什么?

var obj = new Function()
1,创建了一个新对象 obj
2,将this上下文指向这个新对象 this-->obj,此时的这个对象已经是继承于构造函数.prototype
3,执行构造函数中的代码
4,返回一个新对象 return obj 共四步

8,性能优化

1,雪碧图,减少http请求
2,减少dom操作(事件代理等)
3,压缩js,css
4,CDN静态资源托管
5,DNS预加载(在头部添加meta标签,预先请求域名外的域名文件)

9,今日杂项

1,表单reset之后不是清空表表单,而是重置到每个input都为默认的value值
2,Jq中设置dom属性为$("#id").attr('src',path);
而在JS中为dom.setattribute('value',value);
3,原生表单提交阻止页面自动跳转,设置一个隐藏的iframe,然后将表单的target指向该iframe,返回信息显示在iframe中而页面不会跳转。原始发送表单submit()。
4,刷新页面location.reload。

10,ES6深拷贝

var arr = [1,2,3]
var copy = Object.assign([],arr)   //此处的第一个参数也能换成{}对象形式,返回的copy即为键值对对象
copy.push(4)
console.log(arr)   //[1, 2, 3]
console.log(copy)  //[1,2,3,4]  对copy的操作并未对arr产生影响

11,事件委托性能优化

在一个UI李有10个li,实现点击对应的li,输出对应的下标

var lis = querySelectorAll('li')
for(var i = 0 ; i < 10 ; i++){
   lis[i].onclick = (function(a) {
      return function() {
       alert(a)
    }
  })(i)   //闭包实现块级作用域
}   

使用事件委托

利用冒泡的原理,把事件加到父级上,触发执行效果。

1.可以大量节省内存占用,减少事件注册。
2.可以方便地动态添加和修改元素,不需要因为元素的改动而修改事件绑定。

var ul = document.querySelector('ul'); 
var list = document.querySelectorAll('ul li'); 
   
ul.addEventListener('click', function(ev){ 
    var ev = ev || window.event; 
    var target = ev.target || ev.srcElemnt; 
   
    for(var i = 0, len = list.length; i < len; i++){ 
        if(list[i] == target){ 
            alert(i + "----" + target.innerHTML); 
            return
        } 
    } 
}); 

!!!!注意:addEventListener()方法添加的匿名函数是无法移除的,所以如果需要移除监听器,添加时应使用函数名添加。(若多次添加相同的监听器不会覆盖,而是在触发时执行两次)

11,split、join、splice、slice

var a = [1,2,3,4,5]
a = a.join('-')   //将数组以传入的参数连接起来,返回一个合并的字符串
console.log(a)    //1-2-3-4-5
a = a.split("") //将字符串以传入的参数分隔,返回一个分隔的数组
console.log(a)    //[1,-,2,-,3,-,4,-,5]
var del = a.splice(0,3)  //直接对源数组进行修改从下标0开始的长度为3数组
console.log(del)  //[1,-,2]
console.log(a)    //[-,3,-,4,-,5]
a = a.slice(0,1)  //不修改原数组,返回从下标0开始长度为1的截取的数组
console.log(a)    //[-]
***********************************************************************************
split(' ')操作字符串
join('-')操作数组  -->合并为字符串
splice(0,3)操作数组 -->删除
slice(0,3)操作字符串,数组皆可  -->即可分隔数组,又可分隔字符串

12,Object.creat()函数

Object.creat()函数接受两个参数,第一个设置的是这个新创建的对象所指向的原型对象,第二个是这个新创建对象的属性。收获一种新的创建对象的方法hhh

var  obj = Object.create(null,{   //此处原型对象可以传空值,此时obj的__proto__指针指向null
    name:{
        value:'cty', //使用Object.create创建对象时,对象的属性名内,属性值必须用value设置
        enumerable: true //enumerable设为true将其设置为可枚举属性
    }
})
console.log(obj.name) //cty

13,文件上传

直接上代码

label for="resource" class="upload">pdf上传</label>
<input type="file" id="resource" name="resource" ref="resource" @change="fileChange">
----------------分割线-----------------------
fileChange(e) {
//通过事件获取到上传的文件,操作字符串获得文件格式,files的size方法控制上传文件大小
    var fileSize = 0;        
    获取上传的文件
    var files = e.target.files || e.dataTransfer.files;
    fileSize = e.target.files[0].size;        
    var size = fileSize / 1024;    
    if(size>2000){  
     alert("附件不能大于2M");
     e.target.value="";
     return
    }
      var name = e.target.value;
      var fileName = name.substring(name.lastIndexOf(".")+1).toLowerCase();
      if(fileName != "pdf" && fileName != "mp4" && fileName != "ppt" && fileName != "pptx" && fileName != "avi"){
            this.$alert('文件格式有误,请选择PPT,PDF,PPTX,avi,mp4格式上传', '提示', {
                 confirmButtonText: '确定', 
                 type: 'warning'
            })
          e.target.value="";
          return
}

14,js获取事件和h5中的data-*属性

在全局下发生点击的事件可以直接传入函数中,如click(e)(即便绑定时并没有传入这个参数)
然后,通过e.target可以获取目标元素,即事件流中的事件触发阶段的最具体的元素
再然后,
获取元素上绑定的data-*属性,用原生js,方法为let value = e.target.dataset.*
动态设置,用原生js,方法为e.target.dataset.*='xxx'
dataset属性的值是DOMStringMap的一个实例,名值对的映射。每个data-name形式的属性都有一个对应的属性,只不过该属性名没有data-前缀。

15,reduce方法

reduce为数组方法,数组对象可以调用,接收的回调函数接收两个参数,第一个是上一次处理后的属性的值,第二个是上一个属性的下一个属性

var arr = [1,2,3,4,5]
arr.reduce(function(pre,cur){
    return pre+cur
})
//可以简单地对number数组求和
//回调函数第一次执行pre为空,cur为1
//第二次执行pre为上一次返回的数值,即1,cur进入数组下一个值为2
//第三次执行pre为上一次返回的数值,即3,cur进入数组下一个值为3
//...以此类推,最后得出1至5的累加为15

15,Object.key(obj)

或得一个对象数组的属性值,通常检测属性值可以使用hasOwnProperty

var o = {a:'123',b:'456'}
Object.keys(o).forEach(res=>{
        console.log(res)
})   //a  b

2017年10月

1,这里放一些Vue全局对象的基本操作

1,axios.defaults.withCredentials = true

默认允许后台跨域操作,如在客户端存储cookie等需要权限的操作。重要,若请求不设置,后端无法在客户度设置cookie,再发起请求时无法在请求头中携带cookie会发生302错误

2,Vue.config.productionTip = false

设置 Vue.config.productionTip = false 来关闭生产模式下给出的提示

3,Vue.prototype.$axios = axios

Vue实例添加axios方法

4,前端响应式布局

rem怎么来的?

rem是css3中新增加的一个单位属性(font size of the root element),根据页面的根节点的字体大小进行转变的单位。根节点,也就是html。
例:(下面例子中的根节点是html ,它的字体大小是100px,所以根节点下面的元素所设置的rem,都是1rem=100px。)
rem的初始值是16px,也就是说在没有设置根节点的font-size的时候,1rem=16px;
于是,只要在媒体查询中改变根节点的font-size设置,rem将自动根据根节点设置的font-size进行适配。

html,body{ 
height: 100%;
margin: 0; 
padding: 0; 
font-size: 14px;
}
@media screen and (max-width:320px ) {
   html{font-size: 12px;} 
}
@media screen and (min-width:321px) and (max-width:750px ) {
   html{font-size: 14px;} 
} 
@media screen and (min-width:751px ) { 
  html{font-size: 16px;}
}

以此适配三种屏幕大小。

5,判断一个字符串是否是回文字

function isreverse(str){
      //reverse只能作用于数组,将数组反转
      return str.split('').reverse().join('') == str
}

6,统计一个字符串中出现最多的字符

var str = 'aabbcc'
function findMaxDuplicateChar(str){
    var obj = {}
    var max = 0
    var maxindex = []
    for(var index in str){
                //存储在对象类数组中,并统计次数
        if(!obj[str[index]]){
            obj[str[index]] = 1
        }else{
            obj[str[index]] += 1
        }
    }
    for(var index in obj){
        //for..in..也可以作用于类数组  
        if(obj[index] >= max){
            max = obj[index]
            maxindex.push(index)
        }
    }
    return maxindex
} 
findMaxDuplicateChar(str)
> 输出(3) ["a", "b", "c"]

以下排序算法皆是从小到大

7,冒泡排序

冒泡排序原理是,每次比较数组中相邻的两个元素,每次将大的数放在后面,小的数向上冒泡,所以经过第一轮冒泡后,最大的数已经在最后一位了。第一轮比较了n-1次,第二轮只要比较n-2次,最后最大的那个数已经不用比较了。代码如下:

function bubbleSort(arr){
        //每次要比较的次数减一
    for(var i = arr.length ; i > 0 ; i--){
        for(var j = 0 ; j < i ; j++){
            if(arr[j] > arr[j+1]){
                        //如果满足条件,交换位置 
                var tmp = arr[j]
                arr[j] = arr[j+1]
                arr[j+1] = tmp 
            }
        }   
    }
    return arr
}
var arr = [1,4,3,6,7,23,56,2]
bubbleSort(arr)
> 输出(8) [1, 2, 3, 4, 6, 7, 23, 56]

8,快速排序

快速排序的原理是:递归
每次递归判断数组长度是否小于或等于1个数。若否,则取出数组中的第一个数,对剩下的n-1个数进行遍历,把较大的数放在右边,较小的数放在左边,再对左右数组再次进行快排,分别以左右两边数组的第一个数为哨兵,再次比较分组,最后将所有的分组数组使用[].concat方法连接,得到一个从小到大的数组。代码如下:

function quickSort(arr){
    //此处还有左边或右边数组一个元素都没有的情况
    if(arr.length <= 1){
        return arr
    }

    let leftArr = []
    let rightArr = []
    let p = arr[0]

    for(var i = 1 ; i < arr.length ; i++){
        if(arr[i] < p){
            leftArr.push(arr[i])
        }else{
            console.log(arr[i])
            rightArr.push(arr[i])
        }
    }

    return [].concat(quickSort(leftArr),arr[0],quickSort(rightArr))
}
var arr = [7,3,45,2]
quickSort(arr)
> 输出(4) [2,3,7,45]

9,斐波那契数列

又称黄金分割数列:0,1,1,2,3,5,8,13.....
斐波那契数列的原理也是递归,代码如下

function getFibonacci(n){
      var fibarr = []
      for(var i = 0 ; i < n ; i++){
            if(i < 2){
                //前面两个数不需要递归,从0,1开始产生递归
                fibarr.push(i)    
            }else{
                fibarr.push(fibarr[i-2]+fibarr[i-1])
            }
      }
      //其实整个方法只调用了一次,只是通过fibarr[i-2]+fibarr[i-1]不断调用了之前的数组,所以也叫递归
      return fibarr
}

上次笔试竟然写不出来。。。。平时用不到,但是原理不能忘!!!

10,前端上传多种格式文件参数设置

fileChange(e){
//监听文件上传的input框change事件
      var value = e.target.dataset.type
      var name = e.target.value
      var fileName = name.substring(name.lastIndexOf(".")+1)
      //获取文件后缀名,这里也可以用slice
      //var fileName = name.substring(name.lastIndexOf(".")+1).toLowerCase()
      if(value == 'pdf'){
        if(fileName != "pdf"){
            this.$alert('文件格式有误,请选择PDF格式上传', '提示', {
                              confirmButtonText: '确定', 
                              type: 'warning'
                          })
          e.target.value="";
          return
                }else{
                this.file1 = event.target.files[0]                  
                }
      }
      if(value == 'ppt'){
        if(fileName != "ppt" && fileName != "pptx"){
            this.$alert('文件格式有误,请选择PPT,PPTX格式上传', '提示', {
                              confirmButtonText: '确定', 
                              type: 'warning'
                          })
          e.target.value="";
          return
            }else{
                this.file2 = event.target.files[0]
            }           
      }
                        this.loading = true
          //通过验证
          this.$axios.post(BASEPATH+'/subject/info/list/all').then(
                        res=>{
                        var data = res.data.allSubjectList
                        var subId = document.getElementById('subjectid').value
                        //重复验证
                        for(var index in data){
                                if(subId == data[index].subjectid){                         
                                    this.$alert('此课程id重复,请重新输入!', '提示', {
                              confirmButtonText: '确定',
                              type: 'warning'
                           })                               
                                    return
                                }
                        }                           

                        //文件转为formData格式才能正确上传带文件的from表单
                        var formData = new FormData();//formData属性
                        formData.append('subjectid',this.subjectid)
                        formData.append('title',this.title)
                        formData.append('remark',this.remark)
                        formData.append('parentid',this.parentid)
                        formData.append('status',this.status)
                        //formData.append('imgPath',this.imgPath)
                        formData.append('lessonDetail',this.lessonDetail)
                        formData.append('relatedLesson',this.relatedLesson)
                        if(this.file1){
                                                //file文件append到formData后数据格式发生变化
                            formData.append('resource',this.file1)
                        }    
                        formData.append('lessonPptnum',this.lessonPptnum)
        var config = {
                      //文件上传使用multipart/form-data格式上传,设置ajax参数
                  headers: {
                    'Content-Type': 'multipart/form-data'
                    }
                }
//发送请求  this.$axios.post(BASEPATH+'/subject/info/upload',formData,config).then(res=>{
                     if(res.data.code == 1){
                            this.$message({
                                type: 'success',
                                message: '上传成功!'
                                })
                            this.$router.push({path:'super_courselist'})
                     }else{
                        this.$message({
                                type: 'error',
                                message: '上传失败!'
                                })
                        this.loading = false
                        
                     }
            })
                        }).catch(err=>{
                            this.$alert('提交出错!', '提示', {
                              confirmButtonText: '确定', 
                              type: 'error'
                       })
                        this.loading = false                        
                        })
        }).catch((err) => {
          this.$message({
            type: 'warning', 
            showClose: true,
            message: '已取消提交'
          });          
        });             
        },
                //判断输入字符格式,使用了ES6模板解析
        isString(...s){
            for(var i of s){
                if(i!=null && typeof i != 'string'){
                    return false
                }
            }
            return true
        },
        isNumber(...n){    
            var pattern =/^[0-9]+([.]{1}[0-9]{1,2})?$/          
            for(var i of n){
                if(i!=null && !pattern.test(i)){
                    return false
                }
            }
            return true
        }
  }

11,css伪类创建三角形箭

原理是利用绝对定位的伪类元素,创建边框颜色为透明色的,仅有边框的正方形,在需要设箭头方向的的另一侧设置边框为所需箭头颜色。即出现一个小△。
若要出现箭头,则使用after,before两个大小相同的三角形通过position定位重叠后留下一个小箭头。

12,闭包

闭包是指能够访问其他函数内部变量的函数。
最常见的产生闭包的方法就是在一个函数内部创建另一个函数。
闭包的作用域链包含所引用的外部函数的活动对象自身活动对象(如果有的话)和全局变量对象(全局变量对象,谁都有)
理解闭包的作用域链,就可以清晰地知道this的指向了

this对象是在运行时基于函数的执行环境绑定的:在全局函数中,this指向window对象,而当函数被当作某个对象的方法调用时,this等于那个对象。

匿名函数的this对象延作用域链向上搜寻,但是只会搜索到其活动对象为止,搜索不到外外部函数的活动对象,如果都没有,this则会指向全局对象window

13,清除浮动

1,给父元素设置高度
2,在父元素的结尾处添加一个有clear:both属性的盒子标签
3,overflow:hidden
4,使用伪类元素

.clearfix:after{
      content:'';
      height:'';
      display:block;
      visibility:hidden;
      clear:both;
}
.clearfix{
      zoom:1;//兼容ie
}

第五种方法应用最为广泛,不用添加额外的标签,而且可以通用,添加一个class类名即可。

14,BFC(block fomating context)块级格式上下文

描述:简单地说,BFC描述的是块级盒的布局规则
作用:BFC可以用来清除浮动和防止margin重叠
防止margin重叠:因为当块级盒外层没有BFC作保护时,margin-top和margin-bottom会发生重叠,解决办法是在外层套一个BFC保护,则不会再发生重叠
**清除浮动""

  1. BFC会阻止垂直外边距(margin-top、margin-bottom)折叠
  2. BFC不会重叠浮动元素
  3. BFC可以包含浮动

我们可以利用BFC的第三条特性来“清浮动”,这里其实说清浮动已经不再合适,应该说包含浮动。也就是说只要父容器形成BFC就可以,如何形成BFC

  1. float为 left|right
  2. overflow为 hidden|auto|scroll
  3. display为 table-cell|table-caption|inline-block
  4. position为 absolute|fixed

我们可以对父容器添加这些属性来形成BFC达到“清浮动”效果。

15,undefined和null的区别

如果一个变量声明后未初始化,那么改值为undefined
如果一个变量声明后接下来是为了保存某种对象的,那么就把它初始化为null,也因此typeof null结果为object

16,文档声明<!DOCTYPE>

文档声明在html文档的最前面,作用是为了告知浏览器的解析器,用什么文档类型规范来解析这个文档,只有正确地确定了一个文档类型,html和css才能正常生效。
html4.01是基于SGML(标准通用标记语言,xml可扩展标记语言是它的子集)的,在文档声明中需要引用.dtd文件(DTD文件就是文档类型声明文件)
根据DTD引入的不同会触发两种格式

标准模式和混杂模式
标准模式,浏览器以其支持的最高标准呈现页面
混杂模式,页面以一种比较宽松的向后兼容的方式显示。混杂模式通常模拟老式浏览器的行为以防止老站点无法工作。

而html5既然没有DTD,也就没有严格模式与宽松模式的区别,html5有相对宽松的语法,实现时,已经尽可能大的实现了向后兼容。文档声明只要简单的<!DOCTYPE html>

17,==运算符

下面程序得到的结果分别是什么?()

console.log(([])?true:false);

console.log(([]==false?true:false));

console.log(({}==false)?true:false)

A.false true true B.true true true C.true false true D.true true false

解析:

Boolean([]); //true Number([]); //0 Number({}); // NaN Number(false); //0

因此:

console.log(([])?true:fasle);// => console.log((true)?true:false); //true

console.log([]==false?true:false); // => console.log(0==0?true:false); //true

console.log(({}==false)?true:false); // => console.log((NaN==0)?true:false); //false

选D选项

拓展:《JavaScript权威指南》的部分相关知识点

“==”运算符(两个操作数的类型不相同时)

如果一个值是null,另一个值是undefined,则它们相等

如果一个值是数字,另一个值是字符串,先将字符串转换为数学,然后使用转换后的值进行比较。

如果其中一个值是true,则将其转换为1再进行比较。如果其中的一个值是false,则将其转换为0再进行比较。

如果一个值是对象,另一个值是数字或字符串,则将对象转换为原始值,再进行比较。

18,Vue Virtual DOM

由于原始的DOM操作非常耗时,对性能造成了很大的影响,但是js很快。
vue框架使用的是virtual dom来进行dom操作。
虚拟dom的核心思想是:对复杂的文档dom结构,提供一种方便的工具进行最小化的dom操作。dom的子节点,标签,属性,都可以用js来表示,当数据状态发生改变时,先通过js对象表示的虚拟dom计算出实际dom需要进行的最小改动再去操作dom。

11月

1,简单的git操作

提交

$ git add . 将文件添加到缓存区
$ git commit -m "说明" 提交缓存区的代码
$ git push origin master 推送到源分支


拉取并合并

$ git pukk origin master

2,--save和--save-dev

  1. --save将install的依赖包名放入package.json的dependencies中,dependencies属于项目发布之后还是需要依赖的东西。
  2. --save-dev将insatll的依赖包名放入package.json的devDependencies中,devDependencies属于项目发布前打包,编译等需要所依赖的工具,项目上线以后并不需要这些东西。webpack属于打包工具,安装时npm install webpack --sava-dev

3,css选择器权重

行内样式(1000) > id选择器(100) > class选择器(10) == 属性选择器(10) > 伪类选择器(+1) > 标签选择器(1) > 通用选择器(0)

4,逗号选择器总是由逗号最后的一个表达式决定的

5,浏览器渲染过程

  1. html文档加载后,构建dom tree
  2. css文档加载后,构建css rule tree
  3. dom tree 和 rule tree 结合生成 render tree,渲染树
  4. layout 计算出每一个渲染对象的位置和尺寸,将其安置在浏览器窗口的正确位置,叫回流,或者布局
  5. 绘制(Painting)根据上一步的layout计算出的位置和元素尺寸进行页面的绘制
    dom tree --> rule tree --> render tree --> layout --> painting

6,call,apply

通过document.getElementsByTagName选择的dom 节点是一种类似array的array。它不能应用Array下的push,pop等方法。我们可以通过:
var domNodes = Array.prototype.slice.call(document.getElementsByTagName("*"));
这样domNodes就可以应用Array下的所有方法了。

12月

1,Object.prototype.toString.call([1,2,3])

数组是类对象,但它不是真正的对象,不能直接调用toString方法,通过call改变this的指向,使得数组调用对象原型上的toString方法,数组作为类对象返回[Object string],而真正的对象则返回[Object object]。
另外判断其是否为数组

[1,2,3].__proto__.constructor == Array
true

2,vue生命周期的操作问题

vue生命周期从init到destroy,应该在哪个地方操作dom,那个地方操作数据?
首先,获取异步数据在created中,因为created中还未挂载vue实例,且未渲染,如果在其后获取异步数据,虽然也可以,但是会导致页面刷新两次,导致加载时间过长,所以获取异步数据,预处理数据都应该在created中操作。
其次,操作dom,应该在mounted或者vm.nextTick之后,因为此时所有的dom的挂载和渲染都已经完成,此时操作dom才不会出现问题。
最后再提一下updated,updated在每次数据更新的时候都会被触发,而mounted只触发一次,如果updated中获取异步数据,则每次页面有数据变化时都会触发这个异步请求。所以updated一般不推荐使用。

3,fork和clone的区别

  1. 区别
    git clone 是在自己电脑(这里我是ubuntu)直接敲命令,结果是将github仓库中的项目克隆到自己本地电脑中了
    fork是直接访问github网站,在项目页面中点击fork,然后自己github项目中就会多出一个复制的项目
  2. 用法
    如果我们想要修改他人github项目的话,我们直接git clone代码到本地是不能pull的,所以我们使用fork,先把代码复制到自己的github仓库,然后git clone到本地修改,然后在提交pull(这里的pull是pull到自己github仓库了,我们自己的github仓库中的代码是fork源的一个分支),这时候我们想要把修改的代码提交给他人的话,就可以在自己github上pull,等其他人看到后就可以把代码做一个合并。

2018.5.21

1,重温圣杯布局和双飞翼布局

圣杯布局和双飞翼布局都是三列布局左右长度固定,中间宽度随左右变化的的一种方式,当然现在可以使用flex,中间flex为1,左右固定。
圣杯布局:

外层标准盒模型盒子向内padding,之后全部左浮动,利用margin负边距和relative相对定位(相对自身定位)来实现。
image.png

双飞翼布局:
盒子固定,中间自适应内容用新的宽度100%的盒子包裹,新盒子向内padding,左右两侧仅需利用margin负边距即可。
image.png
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,530评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 86,403评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 151,120评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,770评论 1 277
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,758评论 5 367
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,649评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,021评论 3 398
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,675评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,931评论 1 299
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,659评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,751评论 1 330
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,410评论 4 321
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,004评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,969评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,203评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,042评论 2 350
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,493评论 2 343

推荐阅读更多精彩内容

  • Spring Cloud为开发人员提供了快速构建分布式系统中一些常见模式的工具(例如配置管理,服务发现,断路器,智...
    卡卡罗2017阅读 134,594评论 18 139
  • 在线阅读 http://interview.poetries.top[http://interview.poetr...
    程序员poetry阅读 114,237评论 24 450
  • 【今日话题】 你吃过最好吃的东西是什么?描述一下吧 ! 生蚝羊肉火锅: 生蚝鲜美,汤汁浓郁,搭配羊肉,在冬天可以补...
    好听的暖阳阅读 190评论 0 0
  • 单身的甲(女)和乙(男)通过熟人牵线搭桥,相互加微信,只是见过对方的照片而已,没多久甲便是主动询问起男方乙的家境状...
    胡桃_f08b阅读 350评论 0 0
  • 一对黑天鹅,在湖中相依相偎,恩爱有加。阳光洒在水面上,形成彩色的涟漪,给单一颜色的湖面增添了几分美感。 好不容易等...
    故乡月阅读 173评论 0 4