前端大全

  • Post author:
  • Post category:其他




position



1.position:relative;相对定位

  • 对照自身原来的位置定位,发生定位偏移以后自身原来的位置还在,不脱离文档流。



2.position:absolute;绝对定位

  • 不会占据原有的位置,脱离文档流
  • 如果外层元素含有(非static 默认定位)定位属性,那么以外层定位元素(0,0)点为参照定位
  • 如果外层元素不含定位属性,那么以html(0,0)点为参照定位



3.position:fixed;固定定位

  • 不会占据原有的位置,脱离文档流
  • 以浏览器(0,0)点为参照定位



字符串的常用方法



1.计算字符串的长度


  • str.length

    ,会计算空格数。



2.查找字符在字符串中的位置:


  • Str.indexof("要找的字符")

    ,从前往后找,只找第一个,返回值是索引。没有找到返回值-1,兼容性很好。

  • Str.lastIndexof("要找的字符")

    ,从后往前找,只找第一个,返回值是索引。没有找到返回值-1,兼容性很好。



3.根据传入索引,查找该元素是什么


  • Str.charAt(index)



4.根据传入索引,查找该元素编码是什么


  • Str.charCodeAt(index)



5.根据字符编码查找该字符


  • String.fromCharCode()



6.字符串截取的方法


  • Str.slice(start,end)

    • 作用:对字符串截取,start表示截取的开始元素,end表示截取的截止元素,包前不包后。

    • 返回值:截取的字符串

    • console.log(str.slice(0,4));//0是起始索引,4是结束索引,不包含4
      console.log(str.slice(4));//表示从4到结束
      console.log(str.slice(-3));//表示倒数第三到最后
      

  • Str.substr(start,length)

    • 作用:对字符串截取,start表示截取的开始元素,length表示截取的长度

    • 返回值:截取的字符串

    •     console.log(str.substr(0,2));//从0开始截取2个
          console.log(str.substr(2));//从2开始到最后
          console.log(str.substr(-3,2))//从倒数第三个,截取2个
      

  • str.substring(start,end)

    • 作用:对字符串进行截取
    • 参数:start表示截取开始的索引,end表示截取结束的索引,end要大于start,不允许负数
    • 返回:从start到end的字符串,不包含end



7.字符串变小写


  • Str.toLowerCase()



8.字符串变大写


  • Str.toUpperCase()



9.去除前后空格


  • str.trim()



数组的常用方法



1.兼容性较好



1.1.增


  • 数组.unshift(item)

    ;


    从数组前面增加一个元素

    • 作用:从数组前面增加一个元素
    • 参数:item要新增的那个元素
    • 返回值:数组的长度
    • 注意点:直接在原数组操作


  • 数组.push(item)




    从数组后面增加一个元素

    • 作用:从数组后面增加一个元素
    • 参数:item要新增的那个元素
    • 返回值:数组的长度
    • 注意点:直接在原数组操作


1.2.删


  • 数组.shift()




    删除数组中的第一个元素

    • 作用:删除数组中的第一个元素。
    • 返回值:被删除的那个元素。
    • 参数:无
    • 注意:直接在原数组操作,不会生成新数组。


  • 数组.pop()




    删除数组中的最后一个元素

    • 作用:删除数组中的最后一个元素
    • 返回值:被删除的那个元素。
    • 参数:无
    • 注意:直接在原数组操作,不会生成新数组。


  • 数组.splice(start,n)


    :**

    从数组的start位置开始删除n个元素

    • 作用:从数组的start位置开始删除n个元素
    • 参数:start表示从哪个索引开始删除,n表示要删除几个元素
    • 返回值:被删除的元素的集合
    • 注意点:直接在原数组操作



    数组.splice(start,n,.....)




    从数组的start位置开始删除n个元素,然后再添加什么元素

    • 作用:从数组的start位置开始删除n个元素,新增m个元素
    • 参数:start表示从哪个索引开始删除或者增加,n表示要删除几个元素,后面由m个参数,就是要增加要数组中的新元素,从索引是start位置开始增加。
    • 返回值:被删除的元素的集合
    • 注意点:直接在原数组操作


1.3.截取


  • 数组.slice(start,end)

    :从数组中截取一部分

    • 作用:从数组中截取一部分
    • 参数:start表示开始截取的索引,end表示结束截取的索引,包start,不包end,(包前不包后)
    • 返回值:返回一个新的数组,包含从 start 到 end (不包括该元素)的 所有元素
    • 注意点:返回一个新数组,原数组不变


1.4.

颠倒数组



  • 数组.reverse()




    颠倒数组

    • 作用:颠倒数组
    • 参数:无
    • 返回值:原数组
    • 注意点:直接在原数组操作


1.5.

连接数组



  • 数组1.concat(数组2,数组3,......)


    • 作用:用于连接多个数组
    • 参数:要被连接的那些数组
    • 返回值:连接好的新数组
    • 注意点:不在原数组操作,会产生新数组


1.6.数组变字符串
  • 数组.join(“分割符”):把数组变成字符串

    • 作用:把数组变成字符串
    • 参数:默认是逗号,分隔符
    • 返回值:生成的那个字符串
    • 注意点:不会改变原数组


1.7.查询

  • 数组.indexof(ele,start)

    • 作用:查找数组中某个元素的索引

    • 返回值:如果没找到就返回-1,如果找到了就返回该元素的索引值。

    • 参数:第一个参数ele是:要查找的那个元素

      ​ 第二个参数start:从哪里开始查找,默认从零开始找


  • 数组.lastIndexof(ele,start)

    • 作用:查找数组中某个元素的索引

    • 返回值:如果没找到就返回-1,如果找到了就返回该元素的索引值。

    • 参数:第一个参数ele是:要查找的那个元素

      ​ 第二个参数start:从哪里开始查找,默认从零开始找



1.8.数组排序


  • 数组.sort(fn)


    ;

    • 作用:按照指定规则进行排序

    • 参数:如果不写参数,默认是按照字符编码的顺序进行排序,如果写参数,参数fn是表示排序 规则的函数

    • 返回值:返回值就是拍好序的数组

    • 注意点:直接在原数组操作

    • 有参数:参数是表示排序规则的函数

    • 示例“

      arr.sort(function(a,b){
      
      	return a-b;
      
      })由小到大排序
      
      arr.sort(function(a,b){
      
      	return b-a;
      
      })由大到小排序
      



typeof 的返回值

  1. string
  2. number
  3. boolean
  4. undefined
  5. objcect
  6. function



数组的遍历



1.for循环

for(var i=0;i<arr.length;i++){
	console.log(arr[i])
}



2.for in 循环

for( var index in arr){
//固定写法,arr是要循环的数组,index是循环到的那个元素的索引
console.log("当前循环到的是第"+index+'个元素,元素的值是:'+arr[index])
}



3.forEach()循环

数组.forEach(function(value,index){
    要循环执行的函数,数组里面有多少个元素,该函数就执行多少次
    console.log("当前循环到的是第"+index+'个元素,元素的值是:'+value)
})
//参数:要循环执行的函数,函数有两个形参,第一个形参实循环到的那个数组元素的值,第二个形参实循环到的那个数组元素的索引
//注意点:不会改变原数组



4.map()循环

数组.map(function(value,index){
    要循环执行的函数,数组里面有多少个元素,该函数就执行多少次
	return value-1
})
//作用:循环数组
//参数:要循环执行的函数,函数有两个形参,第一个形参实循环到的那个数组元素的值,第二个形参实循环到的那个数组元  	素的索引
//返回值:整个map的返回值是每一次循环的函数的返回值的集合
//示例:
var arr = [23,45,43,78,23,12,46,28,97];
console.log(arr)
var newArr = arr.map(function(value,index){
    return value-1;
})
console.log(newArr)//newArr = [22,44,42,77,22,11,45,27,96]



5.fliter()循环

数组.fliter(function(value,index){
    //要循环执行的函数,数组里面有多少个元素,该函数就执行多少次
	//符合条件的返回true
    //不符合条件的返回false
   if(value>40){
       return console.log(true);
   }else{
       return false;
   }
})
//作用:过滤数组中符合条件的元素,返回值是新的数组



6.every()循环

数组.every(function(value,index){
    //要循环执行的函数,数组里面有多少个元素,该函数就执行多少次
})
//作用:判断数组中的每一个元素是否都符合条件,符合返回值true,不符合返回值false
//示例:
var arr = [1,15,26,48,45,25,14,44]
var res = arr.every(function(value,index){
    return value>30;
})
console.log(res)



7.some()循环

数组.some(function(value,index){
    //要循环执行的函数,数组里面有多少个元素,该函数就执行多少次
})
//作用:判断数组中的每一个元素是否有符合条件,符合返回值true,不符合返回值false
//示例:
var arr = [1,15,26,48,45,25,14,44]
var res = arr.every(function(value,index){
    return value>30;
})
console.log(res)



遍历对象



1.for in()

  • 主要用于遍历对象,可枚举属性,包括自有属性,继承自原型的属性
var obj = {"name":"tom","sex":"male"};
Object.defineProperty(obj, "age", {value:"18", enumerable:false});//增加不可枚举的属性age
Object.prototype.protoPer1 = function(){console.log("name is tom");};//通过原型链增加属性,为一个函数
Object.prototype.protoPer2 = 2;通过原型链增加属性,为一个整型值2
for(var key in obj){
console.log(key)//['name','sex','protoPer1','protoPer1']
}



2.Object.keys()

  • Object.keys主要用于遍历对象自有的可枚举属性,不包括继承自原型的属性和不可枚举的属性。

    var obj = {"name":"tom","sex":"male"};
     Object.defineProperty(obj, "age", {value:"18", enumerable:false});//增加不可枚举的属性age
     Object.prototype.protoPer1 = function(){console.log("name is tom");};//通过原型链增加属性,为一个函数
     Object.prototype.protoPer2 = 2;通过原型链增加属性,为一个整型值2
     console.log("Object.keys:")
     console.log(Object.keys(obj));//["name",'sex']
    



3.Object.getOwnPropertyNames()

  • Object.getOwnProperty主要用于返回对象的自有属性,包括可枚举和不可枚举的属性,不包括继承自原型的属性。

    var obj = {"name":"tom","sex":"male"};
     Object.defineProperty(obj, "age", {value:"18", enumerable:false});//增加不可枚举的属性age
     Object.prototype.protoPer1 = function(){console.log("name is tom");};//通过原型链增加属性,为一个函数
     Object.prototype.protoPer2 = 2;通过原型链增加属性,为一个整型值2
    console.log("Object.getOwnPropertyNames: ");
    console.log(Object.getOwnPropertyNames(obj));//["name","sex","age"]
    



正则表达式



1.正则表达式:

  • 定义字符的规则,也可定义输入字符串的规则。由普通的字符和元字符组成。
  • 通过构造函数定义正则表达式:

    var reg = new RegExp(/lucy/)

    或者

    var reg = new RegExp('lucy')
  • 通过字面量来定义正则表达式://里面都是字符串

    var reg = /lucy/



2.元字符:

  • \d 元字符表示0-9
  • \D 元字符表示非数字
  • \w 元字符表示单词字符:字母数字下划线
  • \W 元字符表示非单词字符:
  • \s 元字符表示空白字符
  • \S 元字符表示非空白字符
  • . 元字符表示除\n\r以外的任意字符(元字符用于查找单个字符,除了换行和行结束符)
  • \ 表示转义



3.标识符

  • g 表示全局去找
  • i 表示不区分大小写



4.字符串的方法

  • str.match(reg/字符) 字符串的方法

    • 找到一个或者多个字符
    • 返回值是找到的字符第一个字符的下标
var str = 'aasjdhhfiiasd46af454as6f4a5s465464f6a5s445454saf64a56s4d'
str.match(/[0-9]+/g)
  • str.search(reg/字符)

    • 参数可以是字符串或者正则表达式
    • 查找字符串中是否含有指定的字符
    • 返回值:如果找到就返回第一个的子串的下标,找不到返回-1
    • 只找第一个。g不起作用



5.test(‘要检索的字符串’)方法

  • 检索字符串中指定的值,返回值true和false
var reg = /lucy/;
console.log(reg.test("hello lucy"))//true



6.量词

  • 指定字符出现的次数

    • 指定出现n次,在要出现的字符后面添加{n}
    • 指定出现m到n次,在要出现的字符后面添加{m,n}
    • 指定出现n次以上,在要出现的字符后面添加{n,}
    • 指定出现1次或者1次以上,在要出现的字符后面添加+或者{1,}
    • 指定出现0次或者1次,在要出现的字符后面添加?或者{0,1}
    • 指定出现0次或者多次,在要出现的字符后面添加*或者{0,}
    • 精确匹配n:^n$
    • 以n开头:^n
    • 以n结尾:n$



7.方括号

  • [abc] 表示abc中的任意一个
  • [^abc] 表示不包含abc中的任意一个
  • [1-9] 表示1-9中的任意一个



面向对象案例



1.选项卡切换



1.1.css样式
<style>
    *{
        margin: 0;
        padding: 0;
    }
    .box{
        width: 400px;
        height: 300px;
        margin: 200px 0 0 800px;
        border: 1px solid #000;
    }
    .tits{
        width: 400px;
        height: 40px;

    }
    .tits li{
        width: 98px;
        height: 38px;
        float: left;
        border: 1px solid #000000;
        font-size: 20px;
        line-height: 38px;
        text-align: center;
        list-style: none;
    }
    .content{
        width: 400px;
        height: 260px;
        position: relative;

    }
    .content li{
        width: 400px;
        height: 260px;
        display: none;
        position: absolute;
        top: 0;
        left: 0;
        font-size: 40px;
        line-height: 260px;
        text-align: center;
        list-style: none;
    }
    .box .tits .titsShow{
        background: pink;
    }
    .box .content .contentShow{
        display: block;
    }
</style>


1.1.html结构
<div class="box">
    <ul class="tits ">
        <li class="titsShow">音乐</li>
        <li>新闻</li>
        <li>娱乐</li>
        <li>电影</li>
    </ul>
    <ul class="content">
        <li class="contentShow">音乐</li>
        <li>新闻</li>
        <li>娱乐</li>
        <li>电影</li>
    </ul>
</div>


1.3.javaScript代码
//1.面向过程的方法去写
<script>
    //获取元素
    var tits = document.querySelectorAll('.tits li');
    var cons = document.querySelectorAll('.content li');
    var prevIndex = 0;
    //给元素添加绑定事件
    for(var i = 0;i < tits.length;i++){
        tits[i].index=i;
        tits[i].onclick=function(){
            console.log('我被点击了')
            //给上一个元素清除leiming
            tits[prevIndex].className="";
            cons[prevIndex].className="";
            //给元素添加类名
            tits[this.index].className="titsShow";
            cons[this.index].className="contentShow";
            //更新全局的prevIndex
            prevIndex = this.index;
        }
    }
</script>

//2.面向对象的方法去写
把变量变成对象的属性,此时tish指向对象,对象上的原型上方法只有对象的实例才能调用,也就是说,原型方法上的this指向调用者。
(function(){
    //写一个切换函数
    function Tab (tits,cons){
        this.tits = tits;
        this.cons = cons;
        this.prevIndex = 0;
    }
    //写一个切换类名的函数
    Tab.prototype.setClass=function(dom,oClass){
        dom.className=oClass;
    }
    //事件处理机制
    Tab.prototype.bindEvent=function(){
        var _this=this;
        for(var i = 0;i<this.tits.length; i++){
            this.tits[i].index=i;
            this.tits[i].onclick =function(){
                _this.clickHandler(this.index) 
            }
        }
    }
    //点击事件
    Tab.prototype.clickHandler=function(index){
        //上次选中的元素的类名清空
        this.setClass(this.tits[this.prevIndex],'')
        this.setClass(this.cons[this.prevIndex],'')
        //给本次选中的元素添加类名
        this.setClass(this.tits[index],"titsShow");
        this.setClass(this.cons[index],"contentShow");
        //更新元素下标
        this.prevIndex=index;
    }
    //创建一个初始话函数,返回示例对象,方便链式调用
    Tab.prototype.init=function(){
        this.bindEvent()
        return  this
    }
    //创建一个工厂函数(创建实例化对象,不需要用户再new了)
    function factory (d,c){
        return new Tab(d,c).init()
    }
    window.$=factory;//对外暴露一个接口

})()
var tits = document.querySelectorAll('.tits li');
var cons = document.querySelectorAll('.content li');
$(tits,cons)



三大家族之offset、scroll、client



1.offset家族

  1. 元素.offsetWidth/Height //元素的宽高:content+padding+margin
  2. 元素.offsetTop/Left //元素距离最近的有定位的父元素的距离
  3. 元素.offsetParent //元素的距离最近的有定位的父元素



2.scroll家族

  1. 元素.scrollWith/Height //如果内容的宽度/高度,就等于内容的宽高

  2. 元素.scrollTop/Left //页面被卷曲的高度,有兼容问题

    解决办法:

    元素.scrollTopLeft = document.body.scrollTop/Left ||document.documentElement.scrollTop/Left



3.client家族

  1. 元素.clientWidth/Height 元素得宽高:content+padding

  2. 浏览器可视区域宽高:window.innerWidth/Height (有兼容问题)

    浏览器可视区域宽高:怪异模式:document.body.clientWidth

    ​ 标准模式 document.documentElement.clientWidth



4.在JQ中三大家族的使用


$("元素“).offset()

​ 语法:

  1. 不传递参数的时候就是读取 ,读到的元素相对于页面的位置关系,返回值是一个对象 { left: xxx, top: xxx }
  2. 传递一个对象就是写入 { left: xxx, top: xxx }


position()

​ 语法:

  1. 只读的方法,元素相对于定位父级的位置关系,得到的也是一个对象 { left: xxx, top: xxx }


scrollTop()

/

scrollLeft()

​ 语法:

  1. 不传递参数的时候就是获取卷去的高度/宽度
  2. 传递一个参数就是设置卷去的高度/宽度



event 对象

  • 存在兼容问题:


    var event = e ||window.event

  • 获取鼠标距离页面可是距离的X,Y


    event.clientX

    获取鼠标距离页面可视距离左侧的宽度


    event.clientY

    获取鼠标距离页面可视距离顶部的高度


    event.pageX

    获取鼠标距离页面左侧的宽度==

    event.clientX+window.scrollLeft

    (包括页面看的见的和看不见的)


    event.pageY

    获取鼠标距离页面顶部的高度==

    event.clientY+window.scrollTop

    (包括页面看的见的和看不见的)



BOM中的五大对象



1.window: 窗口对象 BOM核心



2.history:历史路径

  1. history.forword() //下一个页面
  2. history.back() //上一个页面
  3. history.go(index) //往前挑几个页面



3.loacltion:地址栏对象

  1. location.href //完整的地址
  2. location.protocol //协议
  3. location.port //端口号
  4. location.hostname //主机名称
  5. location.pathname //路径名称
  6. location.search // ?后面的数据部分



4.navigator:导航器对象

  1. navigator.appName //产品名称
  2. navigator.appVersion //产品版本号
  3. navigator.userAgent //用户代理信息
  4. navigator.platForm //系统平台信息



5.screen:屏幕对象

  1. screen.width //屏幕的宽度
  2. screen.height //屏幕的高度
  3. screen.availWidth //可用屏幕的宽度
  4. screen.availHeight //可用屏幕的高度



ES6常用API



1.变量定义



1.1.var 声明的变量
  • 在代码执行前会进行预解析
  • 同一个变量名可以重复定义
  • 只有全局作用域和函数作用域,没有块级作用域
  • 在函数内,函数的参数优先级高于变量


1.2.let 声明的变量
  • let 没有预解析

  • let 不能重复声明,在函数内部允许声明与形参相同的变量

  • let 有块级作用域

  • let 声明以后后期可以赋值

    var liArr = document.body.children[0].chidren;
    for(let i=0;i<liArr.length;i++){
    	liArr[i].onclick = function () {
            alert(i)
        }
    }
    


1.3.const 声明的变量
  • const 没有预解析
  • const 不能重复声明
  • const 有块级作用域
  • const 声明的时候要同时赋值,后期不能重复赋值(类似常量)
  • 变量名一般全字母大写



2.JSON



2.1.JSON.parse(string)
  • 把一个像json的字符串转变成json对象


2.2.JSON.stringify(json对象)
  • 把一个json对象转变成json字符串



3.箭头函数



3.1.ES5函数
  • 普通函数里的this指向调用者
var fn1 = function(){}//函数表达式
function fn2 (){}//函数声明
box.onclick = function (){}//匿名函数或者 时间处理函数
(function(){})()//自执行函数
1.改变this指向,.bind(this)
box.onclick = function (){
    console.log(this)
    setTimeout(function(){
    console.log(this)    
    }.bind(this),2000)
}


3.2.ES6语法提供了函数默认值
var sum = function (a=1,a=2){
    return a+b;
}
console.log(sum(0,0))


3.3.箭头函数
  • 箭头函数不会改变this指向,它内部的this指向上层结构的this,没有arguments参数
  • 箭头函数不能用new,作为构造函数来创建实力对象
let test1 = ()=>{}//箭头函数
setTimeout(()={},2000)
box.onclick = ()=>{}
(()=>{})()//自执行函数
//简写:
1.如果函数体上只有一句话,可以省略{}
let fn = ()=>console.log(1);
2.如果函数体上只有一句话,可以省略{},但如果这一句话是return,则return也可省略
let fn1 = ()=>666;
3.如果参数只有一个,且不需要在参数中设置默认值,可以省略()
let fn3 = a=>a;



4.参数打包



4.1.



5.箭头函数里的参数



5.1.



数组去重



1.for循环嵌套,利用splice去重

function newArr(arr){
    for(var i=0;i<arr.length;i++){
        for(var j=i+1;j<arr.length;j++){
            if(arr[i]==arr[j]){ 
            //如果第一个等于第二个,splice方法删除第二个
            arr.splice(j,1);
            j--;
            }
        }
    }
    return arr;
}

let a= m.map((item,index,array)=>{
 
    console.log(array)
 
})
console.log(a)
 



2.建新数组,利用indexOf去重

function newArr(array){ 
    //一个新的数组 
    var arrs = []; 
    //遍历当前数组 
    for(var i = 0; i < array.length; i++){ 
        //如果临时数组里没有当前数组的当前值,则把当前值push到新数组里面 
        if (arrs.indexOf(array[i]) == -1){ 
            arrs.push(array[i])
        }; 
    } 
    return arrs; 
}



3.ES6中利用Set,Array.from去重

function newArr(arr){
    return Array.from(new Set(arr))
}



4.ES6中利用Set,扩展运算符去重

function newArr(array){
    return arr=[new Set(array)]
}



阻止事件传播/阻止浏览器默认行为



1.事件捕获


event.stopPropagation()



2.事件冒泡


event.cancelBubble=false

低版本IE



3.阻止浏览器默认行为:火狐/谷歌


event.preventDefault()



4.阻止浏览器默认行为:低版本IE


event.returnValue=false



服务器+PHP+MYSQL



1.服务器



1.1.前端认知:
  • 前端

    • 把后端给的数据展示在页面上(列表页面)
    • 把前端的数据传递给后端, 让后端存储起来(注册)
  • 后端

    • 当前端需要数据的时候, 后端从数据库里面拿到数据给前端
    • 把前端传递来的数据存储在数据库里面
  • 数据库

    • 专门让 后端 进行数据的增删改查
  • 流程

    • 前端 -> 后端 -> 数据库 -> 后端 -> 前端
    • 注意:

      • 前端是不能操作数据库的
      • 前端相对数据库进行任何操作, 都要把信息告诉后端
      • 由后端进行数据库操作
      • 把操作的信息反馈给前端


1.2.服务器
  • 什么是服务器 ?

    • 就是一台在网络 “那一头” 的一台电脑,只不过运行了一些特殊的环境,运行了一个特殊的 “软件”。
  • 服务器的作用 ?

    • 当一台电脑运行了一个服务器环境以后,在这台电脑上, 就会由一个文件夹被对外开放了, 叫做

      服务器空间

      ,只要你在整个服务器空间(文件夹) 里面放上对应的 html 文件,其他的小伙伴就会根据网线找到你这台电脑, 找到对应的文件夹,就可以看到里面的页面了(只读的权限)。
    • 运行服务端代码,如果我们写一个后端代码, 那么需要在服务器环境下运行, 因为浏览器不支持后端代码的运行。
  • 了解:

    • http 传输协议, 浏览器会自动帮你添加 80 端口号
    • https 传输协议, 浏览器会自动帮你添加 443 端口号


1.3.集成环境
  • WAMP: windows + apache + mysql + php
  • MAMP: Mac OS + apache + mysql + php
  • LAMP: Linux + apache + mysql + php



2.PHP



2.1.php是 一个后端语言
  • 运行需要在 apache 服务器上运行
  • 我们要把 php 文件写在 WWW 目录里面
  • 在浏览器以 localhost 的形式运行
  • .php 代码写在一个 .php 后缀的文件里面
  • .html 后缀的文件不认识 php 代码的
  • php 文件不允许使用中文命名


2.2.php 里面的三种输出语法
  • echo 输出内容;
  • print_r(输出内容);
  • var_dump(输出内容);


2.3.三种输出语法的详细区别
  • echo

    • 只能输出基本数据类型, 复杂数据类型会报错
    • 遇到布尔值的时候, true 会输出 1, false 会输出空白内容
  • print_r()

    • 可以输出所有数据类型
    • 遇到布尔值的时候, true 会输出 1, false 会输出空白内容
  • var_dump()

    • 可以输出所有数据类型
    • 遇到布尔值会正常输出 true 输出 true, false 输出 false
    • 并且会带有数据的类型和数据的信息


2.4.php 里面的字符串
  • 在 js 里面 字符串的定义由两种

    • 单引号,双引号,

      这两个没有任何区别
  • 在 php 里面 字符串 定义也是两种方式(两种方式是有区别的)

    • 单引号: 就是普通字符串
    • 双引号: 是一个特殊字符串, 可以在字符串里面直接解析变量,类似jsES6的模板字符串


2.5.php 里面的字符串拼接
  • 就是把多个字符串连接在一起

    • 我们在 js 里面的时候, 使用 加号(+) 就能进行字符串拼接
    • 在 php 里面, 加号(+) 只能进行数学运算, 只有 点(.) 才能进行字符串拼接


2.6.索引型数组
  • 语法: $arr = array(数据1, 数据2, 数据3, …)

    • 按照索引下标进行排列
    • 如果向单独获取数组里面的某一个数据,数组名称[对应的索引]
    • 等价于 js 里面的数组


2.7.关联型数组
  • 语法: $arr = array(key1 => value1, key2 => value2);

    • 获取关联型数组里面某一项的值,数组名称[‘你要获取的属性名’]
    • 等价于 js 里面的对象
    • 注意:

      • 不管是 key 还是 value, 需要用引号包裹, 单引号也行, 双引号也行
      • 不可以不包裹, 如果不用引号包裹, 会被当作变量来使用(报错)
      • 中间用的是 =>, 不是 : 也不是 =
      • 数字和布尔值, 不需要引号包裹, 可以直接使用


2.8.php 转换 json 格式的两个方法
  • 把 php 的数据格式转换成 json 的数据格式


    • json_encode()

      简记pej
    • 语法: json_encode(要转换的 php 数据格式)
    • 返回值: 转换好的 json 数据格式
  • 把 json 数据格式转化成 php 的数据格式


    • json_decode()

      简记jdp
    • 语法: json_decode(要转换的 json 格式数据)
    • 返回值: 转换好的 php 格式数据


2.9.接受前端传过来的数据

  • $_REQUEST()

  • $_GET()

  • $_POST()


2.10.中文解析

  • header('content-type:text/html;charset=utf-8')



3.MYSQL



3.1.SQL语法
  1. sql 语句的语法规范(你可以不遵守, 建议你遵守)

    • sql 语句里面的关键字大写
    • 表名和字段名尽可能使用反引号(键盘 tab 键上面那个按钮 “)包裹
  2. sql 语句的语法规则(你必须遵守, 不然报错)

    • 当你写一些文本内容的时候, 需要使用 引号 包裹, 表示是一个 字符串
  3. 数据库增删改查


    • 增:INSERT关键字

      • ​ 一共两种语法:

        1. INSERT INTO

          表名

          VALUES(数据1, 数据2, 数据3, …);

          1. 按照你数据库里面字段的顺序插入的
          2. id 我们可以不写, 直接写 null, 会自动增长
        2. INSERT INTO

          表名

          (字段1, 字段2, …) VALUES(数据1, 数据2, …);

          1. 按照你书写的字段添加
          2. 值添加某些字段的内容, 剩下的稍后完善的时候在做

    • 删:DELETE关键字

      • DELETE FROM

        表名

        WHERE 条件

        • 要从哪一个表删除条件为什么的数据


    • 改:UPDATE关键字
      • UPDATE



        SET 字段=新值 WHERE 条件
      • UPDATE



        SET 字段=新值, 字段2=新值 WHERE 条件

    • 查:SELECT关键字

      1. SELECT * FROM


        • 查询这个表里面的所有数据
      2. SELECT * FROM



        WHERE 条件

        • 根据我们的条件查询数据库里面的数据
      3. SELECT * FROM



        WHERE 条件1 AND 条件2

        • 根据两个条件来查询, 两个条件必须都满足
      4. SELECT * FROM



        WHERE 条件1 OR 条件2

        • 根据两个条件来查询, 两个条件满足一个就可以了
      5. SELECT * FROM



        WHERE 字段 LIKE ‘%关键字%’

        • 查询数据里面指定字段包含某一个关键字的数据


3.2.MYSQL数据库的固定操作
  1. 和数据库进行连接


    • $link = mysqli_connect('IP地址', '数据库用户名', '数据库密码', '仓库名字');
  2. 设置字符编码


    • mysqli_set_charset(utf8");
  3. 执行操作


    • $res=mysqli_query('连接数据库的信息', '你要执行的 sql 语句');
  4. 解析结果


    • $rows=mysqli_fetch_all($res,1)
  5. 断开数据库连接


    • mysqli_close($link)



服务器同源策略/解决跨域请求



1.服务器同源策略

  • 同源策略,指的是浏览器对不同源的脚本或者文本的访问方式进行的限制。
  • 同源指两个页面具有相同的协议,主机(也常说域名),端口,三个要素缺一不可。
  • 同源策略就是为了保证网站的数据安全而存在。



2.URL构成:

  1. url:

    http://image.baidu.com:80/search/detail?ct=503316480&z=undefined#header
  2. http —- 超文本传输协议
  3. [image.baidu.com] —- 域名
  4. 80 —- 端口
  5. /search/detail —- 资源目录
  6. ct=503316480&z=undefined —- 发送到服务器的数据
  7. #header —- 锚点



3.跨域

  • 跨域是指在浏览器上进行非同源请求的行为



4.解决跨域问题的办法



1.jsonp方法
  • jsonp跨域就是利用script标签的跨域能力请求资源

  • 既然叫jsonp,显然目的还是json,而且是跨域获取

  • 利用js创建一个script标签,把json的url赋给script的scr属性,把这个script插入到页面里,让浏览器去跨域获取资源

  • script标签特性:src请求到的数据(字符串),会被当成js执行

  • callback是页面存在的回调方法,参数就是想得到的json

  • 回调方法要遵从服务端的约定一般是用 callback 或者 cb

  • 注意:jsonp针对get形式的请求



    1.1jsonp的封装
    //jsonp发送ajax请求
    function jsonp(options){
        // 把options.success函数声明为全局函数 'mycallback'
        window[options.callbackName] = options.success;
    
        // 判断参数,如果是字符串,直接赋值给data
        var data = '';
        if (typeof options.data === 'string'){
            data = options.data;
        }
        // 判断参数,如果是对象,把对象格式化成参数序列的字符串再赋值给data
        if (typeof options.data === 'object' && options.data !== null && options.data.constructor === Object){
            // 把{abc:123,ddd:777} 转成 'abc=123&ddd=777'
            for (var key in options.data){
                data += key+'='+options.data[key]+'&';
            }
            // data = 'abc=123&ddd=777&';
            data = data.substring(0,data.length-1);
        }
    
        // 创建script标签,并且给src属性赋值(数据地址、参数、参数值)
        var Script = document.createElement('script');
        Script.src = options.url+'?'+ options.cb +'='+options.callbackName+'&'+data;
        document.body.appendChild(Script);
    
        // script标签加载完成时,删除该标签
        Script.onload = function (){
            document.body.removeChild(Script);
        }
    }
    


    1.2.jQuery 发送jsonp请求
    $.ajax({
        type: "get", //jsonp只能发送get请求
        async: false,//不异步
        url: "http://flightQuery.com/jsonp/flightResult.aspx?code=CA1998",
        dataType: "jsonp",//这里吧标注jsonp,jQ就判断发送jsonp请求
        jsonp: "callback",//传递给请求处理程序或页面的,用以获得jsonp回调函数名的参数名                                 (一般默认为:callback)
        jsonpCallback:"flightHandler",//自定义的jsonp回调函数名称,默认为jQuery自动                                             生成的随机函数名,也可以写"?",jQuery会自动为你处理数据
        success: function(json){
            alert('您查询到航班信息:票价: ' + json.price + ' 元,余票: ' + json.tickets + ' 张。');
        },
        error: function(){
            alert('fail');
        }
    });
    
    


2.CORS 跨域资源共享(xhr2)
  • CORS是一个W3C标准,全称是”跨域资源共享”(Cross-origin resource sharing)

  • 它允许浏览器向跨源服务器,发出XMLHttpRequest请求,从而克服了AJAX只能同源使用的限制

  • 整个CORS通信过程,都是浏览器自动完成,不需要用户参与

  • 对于开发者来说,CORS通信与同源的AJAX通信没有差别,代码完全一样

  • 实现CORS通信的关键是服务端,只要服务端实现了CORS接口,就可以跨源通信

  • 示例:

    实现CORS并不难,只需服务端做一些设置即可:如
    <?php
    header("Access-Control-Allow-Origin:*"); // 允许任何来源
    注意:IE10以下不支持CORS
    


3.代理跨域
  • 在服务器上配置代理,然后请求代理标识符D:\phpstudy_pro\Extensions\Nginx1.15.11\conf\vhosts\localhost_80.conf

    # 配置代理
            # https://www.duitang.com/napi/vienna/feed/list/by_common/?start=0&limit=18
            # 当我们请求 http://localhost/dt 时,Nginx转发到			 		 https://www.duitang.com/napi/vienna/feed/list/by_common/
            location = /dt {
                proxy_pass https://www.duitang.com/napi/vienna/feed/list/by_common/;
            }
    



ajax



1.什么是ajax?

  • AJAX是再一种无需重新加载整个页面的情况下,也能够更新网页部分的技术(局部刷新)
  • AJAX是一个异步的代码,再程序中同步异步的区别就是,同步代码按照顺序执行,异步代码不按照顺序执行。



2.ajax的优点?

  • 页面无刷新更新数据:ajax最大的优点就是能够在不刷新网页的情况下与服务器通信维护数据;
  • 异步与服务器通信:ajax使用异步方式与服务器通信 ,不需要打断用户的操作,具有更加迅速的响应能力;
  • 前端和后端负载平衡:ajax可以把以前一些服务端负担的工作转嫁到客户端,减轻服务器和带宽的负担,节约空间和宽带租用成本;
  • 基于标准被广泛支持:ajax基本标准化的并被广泛支持的技术,不需要下载浏览器插件;
  • 界面与应用分离:ajax使WEB中的数据与呈现分离,有利于分工合作,提高效率。



3.ajax的缺点

  • ajax干掉了Back和History功能:即对浏览器机制的破坏,在动态页面的情况下,用户无法回到前面一个页面状态;
  • ajax有安全问题:ajax技术给用户带来了很好的用户体验的同时也带来了新的安全威胁,ajax技术就如同对企业数据建立了一个直接的通道;
  • 对搜索引擎支持较弱:对搜索引擎优化不太好;
  • 破坏程序的异常处理机制:像Ajax。dll,Ajaxpro.dll这些Ajax框架是会破坏程序的异常机制;
  • AJAX不能很好支持移动端设备;



4.如何使用ajax

  • 主流W3C标准浏览器都支持XMLHttpRequest对象

  • 低版本IE浏览器使用的是 ActiveXObject



    4.1.创建ajax对象
    var xhr = new XMLHttpRequest();//主流W3C标准浏览器
    //考虑兼容
    if(window.XMLHttpRequest){ // 非IE5 IE6
        var xhr=new XMLHttpRequest();
    }else{ // IE5 IE6
        var xhr=new ActiveXObject("Microsoft.XMLHTTP");
    };
    


    4.2.初始化ajax请求
    xhr.open(method,url,async);
    //参数说明:
    method:请求数据类型 get/post
    url:文件在服务器上的位置
    async: 可选,默认ture(异步),false(同步)
    


    4.3发送请求
    xhr.send(param);
    //参数说明:
    param:对于get请求,参数为null
    param:对于post请求,参数为发送到服务器的数据
    //为post请求时,需要在send()之前设置http请求头:作用模拟表单post来传递参数
    xhr.setRequestHeader("Content-type","application/x-www-form-urlencoded")
    //get/post区别
    1.语义化不一样
    	GET倾向于从服务器获取数据
        post倾向于从服务器提交数据
    2.传递参数的方式
    	GET请求直接在地址栏后边拼接
        post请求在请求体里面传递
    3.参数大小限制 
    	GET请求一般理论上不大于2KB
        post请求理论上没有上线
    4.缓存能力
    	GET会被浏览器主动缓存
        POST不会被浏览器主动缓存
    5.安全性能
    	GET请求相对安全性较低
        POST请求相对安全性较高
    get/post本质上都是tcp连接
    


    4.4请求-响应状态
    //readystate  属性存有XMLHttpRequest对象的状态,会从0-4发生变化;
    0:请求未初始化
    1:服务器连接已经建立
    2:请求已经接收
    3:请求处理中
    4:请求已经完成
    //当readystate改变时就会触发onreadystatechange事件
    //status:http请求状态码
    //下面是常见的Http请求状态码:
    200:请求成功
    301:网页被重定向到其他的url
    304:文件未被修改,使用缓存资源
    404:找不到此网页(指定的资源)
    500:服务器内部错误
    //当readyState为 4 且 status为 200 时,表示请求已完成,成功得到响应结果
    xhr.onreadystatechange=function (){
        if (xhr.readyState==4) { // 请求完成
            if (xhr.status==200) { //ok 成功
                alert( xhr.responseText ); // 得到响应结果
            } else{
                alert( xhr.status ); // 弹出失败的状态码
            };
        };
    }
    //xhr.responseText  获得文本形式的响应数据
    //xhr.responseXML  获得 XML 形式的响应数据
    



5.封装ajax



5.1封装ajax
//封装ajax请求
function ajax(options){
    1.创建XMLHttpRequest对象
    var xhr = new XMLHttpRequest();
    //判断传入的参数类型,处理一下data,变成字符串数据
    //如果data为对象
    var data = "";
    if(typeof options.data === "string"){
        data = options.data;
    }
    if(typeof options.data === "object" && options.data!==null && options.data.constructor === Object){
        //{abc:123, ddd:777}转变成'abc=123&ddd=777'
        for(var key in options.data){
            data += key+"="+options.data[key]+"&";
        }
        //data='abc=123&ddd=777&'
        data = data.substring(0,data.length-1)
        //data='abc=123&ddd=777'
    }
    //判断请求类型
    if(options.type.toLowerCase()==='get'){
        2.初始化一个请求
        xhr.open(options.type,options.url+"?"+data+"&_="+Date.now())
        3.发送一个请求
        xhr.send()
    }else if (options.type.toLowerCase()==='post'){
        2.初始化一个请求
        xhr.open(options.type,options.url)      
        //设置请求头
		xhr.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
        3.发送一个请求
		xhr.send(data)
    }els{
        alert('目前只支持 get和post 请求!')
    }
    4.请求-响应状态
    xhr.onreadystatechange = function () {
		if (xhr.readyState == 4) {
			if (xhr.status >= 200 && xhr.status < 300) {
				options.success(xhr.responseText)
			} else {
				options.error(xhr.status)
			}
		}
	}
}
//参数说明:
options:是一个参数对象
options ={
    type:"GET/POST", //请求的类型
    url:          , //请求的地址
    data:{
    	             //请求携带的参数,支持字符串类型,对象类型
	},
    success:function(){
        //请求成功的回调,要执行的内容
    }
    error:function(){
        //请求失败的回调,要执行的内容
    }
}


5.2.使用Promise封装ajax
function promiseAjax(options){
    return new Promise(function(resolve,reject){
        // 1.创建XMLHttpRequest对象(数据交互对象)
        var xhr = new XMLHttpRequest();//w3c标准
        // var xhr = new ActiveXObject('Microsoft.XMLHTTP');//IE 5 6

        var data = '';
        if (typeof options.data === 'string'){
            data = options.data;
        }
        if (typeof options.data === 'object' && options.data !== null && options.data.constructor === Object){
            // 把{abc:123,ddd:777} 转成 'abc=123&ddd=777'
            for (var key in options.data){
                data += key+'='+options.data[key]+'&';
            }
            // data = 'abc=123&ddd=777&';
            data = data.substring(0,data.length-1);
            // console.log(data);
        }
        // return;

        // 判断请求方式
        if (options.method.toLowerCase() === 'get'){
            xhr.open(options.method,options.url+'?'+data+'&_='+Date.now(),true);
            xhr.send(null);// get请求
        } else if (options.method.toLowerCase() === 'post'){
            xhr.open(options.method,options.url,true);
            // 作用是模拟表单post来传递参数
            xhr.setRequestHeader("Content-type","application/x-www-form-urlencoded");
            xhr.send(data);// post请求发送数据 
        } else {
            alert('目前只支持 get和post 请求!')
        }

        // 4.请求-响应 状态
        xhr.onreadystatechange = function (){
            // console.log(xhr.readyState);
            if (xhr.readyState == 4){//请求完成 (请求状态)
                if(xhr.status >= 200 && xhr.status < 300){// 得到响应数据 (响应状态)
                    resolve(xhr.responseText);
                } else{
                    reject(xhr.status);
                }
            }
        }
    });
}



Promise



1.简述



1.1概述
  • Promise是异步编程的一种解决方案,从语法上讲,Promise是一个对象,可以获取异步操作的消息


1.2.目的
  • 避免回调地狱的问题
  • Promise对象提供了简洁的API,使得控制异步操作更加容易


1.3.Promise的三种状态:
  • pendding //正在请求
  • rejected //失败
  • resolved //成功


1.4.基础用法:
new Promise(function(resolve,reject){ 

})


1.5.resolved,rejected函数:
  • 在异步事件状态pendding->resolved回调成功时,通过调用resolved函数返回结果;当异步操作失败时,回调用rejected函数显示错误信息。


1.6.then的用法
  • then中传了两个参数,第一个对应resolve的回调,第二个对应reject的回调

    p.then((data) => {
            console.log('resolved',data);
        },(err) => {
            console.log('rejected',err);
        }
    );
    


1.7.catch方法
  • 捕捉promise错误函数,和then函数参数中rejected作用一样,处理错误,由于Promise抛出错误具有冒泡性质,能够不断传递,会传到catch中,所以一般来说所有错误处理放在catch中,then中只处理成功的,同时catch还会捕捉resolved中抛出的异常

    p.then((data) => {
            console.log('resolved',data);
        })
        .catch((err) => {
            console.log('rejected',err);
    });
    


1.8.all方法/race方法
  • Promise.all([promise1,promise2])——参数是对象数组。以慢为准,等数组中所有的promise对象状态为resolved时,该对象就为resolved;只要数组中有任意一个promise对象状态为rejected,该对象就为rejected

  • race方法:Promise.race([promise1,promise2])——参数是对象数组。以快为准,数组中所有的promise对象,有一个先执行了何种状态,该对象就为何种状态,并执行相应函数

    let p = Promise.all([Promise1, Promise2])
    
    p.then((data) => {
        //都成功才表示成功
    })
    .catch((err) => {
        //有一个失败,则都失败
    });
    



async await



Localstorage



1.设置Localstorage的键值:



Localstorage.setItem('key''val');



2.获取Localstorage的值:



Localstorage.setItem('key');



3.获取key:



Localstorage.key(索引);



4.清除Localstorage:



localStorage.clear();



5.删除某一条Localstorage:



localStorage.removeItem('key');



6.json对象转json字符串:



JSON.stringify()



7.json字符串转成json对象:



JSON.parse()



闭包、原型/原型链、继承



1.闭包



1.1.官方解释
  • 一个拥有许多变量和绑定了这些变量的环境表达式(通常是一个函数),因而这些变量也是该表达式的一部分
  • 当一个函数能够记住并访问到其所在的词法作用域及作用域链,特别强调是在其定义的作用域外进行的访问,此时该函数和其上层执行上下文共同构成闭包。

    • 闭包就是指有权访问另一个函数作用域中的变量参数的函数。
    • 闭包就是能够读取其他函数内部变量(参数)的函数
    • 闭包可以理解成定义在一个函数内部的函数


1.2.特别需要明确几点
  • 闭包一定是函数对象
  • 闭包和词法作用域、作用域链、垃圾回收机制等息息相关
  • 函数内保持对上层作用域的引用
  • 当函数在其定义的作用域外进行访问时,才产生闭包
  • 闭包是由该函数和其上层执行上下文共同构成


1.3.闭包的应用
  • 在函数外读取函数内部的变量;

  • 让局部变量的值能够被保存下来;

  • 将模块的公有属性和方法暴露出来。

  • function fn1(){
        var n = 5;
        return function fn2() {
            n++;
            return n;
        }
    }
    var fn = fn1();
    console.log( fn() );
    console.log( fn() );
    console.log( fn() );
    


1.4.变量
  • 变量无非就是全局变量和局部变量
  • Javascript语言中,函数内部可以直接读取全局变量,在函数外部无法直接读取函数内的局部变量。


1.5.作用域的概念:
  • 通常来说,一段程序代码中所用到的名字并不总是有效可用的,而限定这个名字的可用性的代码范围就是这个名字的作用域。
  • 词法作用域:

    • 词法作用域,也叫静态作用域,它的作用域是指在词法分析阶段就确定了,不会改变。
    • 动态作用域,是在运行时根据程序的流程信息来动态确定的,而不是在写代码时进行静态确定的。
    • 主要区别:词法作用域是在写代码或者定义时确定的,而动态作用域是在运行时确定的。
    • 词法作用域关注函数在何处声明,而动态作用域关注函数从何处调用。
    • javascript 使用的是词法作用域



2.原型原型链

  • JavaScript是一种直译式脚本语言,是一种动态类型、弱类型、基于原型的语言。
  • 我们把JS中的对象分为

    普通对象



    函数对象


2.1.prototype(原型)
  • 每一个函数对象(Function.prototype除外)都有一个prototype属性(这个属性指向一个对象即原型)

  • prototype原型是函数的一个默认属性,在函数的创建过程中由JS编译器自动添加

    • 内置构造函数String、Number他们的原型指向一个普通对象,(Number{}和String{}),而Function的原型则指向函数对象function(){[native code]},这是原生代码。而这个函数对象(Function.prototype)是没有原型,即没有原型属性,所以他的prototype返回undefined。

    • var fn1 = function (){ };
      var fn2 = new Function();
      function fn3(){ };
      console.log(fn1.prototype);//{constructor:ƒ __proto__:Object}
      console.log(fn2.prototype);//{constructor:ƒ anonymous() __proto__:Object}
      console.log(fn3.prototype); // {constructor:ƒ fn3() __proto__:Object}
      //Object{} 这就是我们所说的原型,它是一个对象也叫原型对象
      // 为什么说 Function.prototype 除外呢?看代码:
      console.log(Number.prototype);//Number{constructor:ƒ Number() __proto__:Object}
      console.log(String.prototype);//String{constructor:ƒ String() __proto__:Object}
      console.log(Function.prototype);//ƒ () { [native code] }
      console.log(Function.prototype.prototype);// 结果看下图undefined
      
    • 可以看到内置构造函数Number、String等,它们的原型指向一个普通对象(Number{}和String{})

    • Function的原型则指向函数对象 function () { [native code] },这是原生代码!这个函数对象(Function.prototype)是没有原型属性的,所以它的prototype返回 undefined。

    • function Cat(){};
      Cat.prototype.name = '小白'; // 给原型对象添加属性
      Cat.prototype.color = 'black'; // 给原型对象添加属性
      Cat.prototype.sayHello = function (){ // 给原型对象添加方法
         console.log('大家好,我的名字叫'+this.name);
      }
      var cat1 = new Cat(); // 实例对象
      var obj = Cat.prototype;// 原型对象
      console.log(obj);//{name: "小白", color: "black", sayHello: ƒ, constructor: ƒ}
      console.log(cat1.constructor);//ƒ Cat(){}
      console.log(obj.constructor);//ƒ Cat(){}
      console.log(Cat.prototype === cat1.constructor.prototype);
      
    • 可以看到Cat这个构造函数,它的原型指向一个对象,即原型对象({name: “小白”, color: “black”, sayHello: ƒ, constructor: ƒ})

    • 这个原型对象的constructor(构造器)指向Cat构造函数

    • cat1实例对象的constructor(构造器)也指向Cat构造函数



2.2.constructor(构造器)
  • 每个对象都有一个隐藏属性constructor,该属性指向对象的构造函数(“类”)

  • 通过上面的代码我们可以看到,实例对象 cat1 和原型对象 obj 它们的构造器相同,都指向 Cat!我们换一种写法:

    • function Cat(){}
      Cat.prototype = {// 原型对象
         name: '小白',
         color: 'black',
         sayHello: function (){
             console.log('大家好,我的名字叫'+this.name);
         }
      }
      var cat1 = new Cat();
      console.log(Cat.prototype === cat1.constructor.prototype); //false
      console.log(Cat.prototype.constructor === Object); //true
      console.log(cat1.constructor === Object); //true
      
    • 此时 Cat.prototype 指向一个对象字面量方式定义的对象{},其构造器(constructor)指向的自然是根构造器 Object,所以 cat1 的构造器也指向根构造器 Object。

    • instanceof 运算符用于检测构造函数的 prototype 属性是否出现在某个实例对象的原型链上。



2.3.

_ _ proto _ _

(原型)
  • 每个对象都有一个隐藏属性

    _ _proto_ _

    即原型对象,用于指向创建他的构造函数的原型即原型对象 。

  • 也就是说: 实例.

    _ _proto_ _

    ===构造函数.prototype

  • 对象 通过_ _ proto _ _指向原型对象,函数对象 通过prototype指向原型对象

  • Object.prototype.jdk = 'abc123';
    Object.prototype.sayHi = function (){
       console.log('嗨~大家好');
    }
    var str = 'yoyo';
    str.sayHi(); // 嗨~大家好
    console.log(str.jdk); // 'abc123'
    
  • str 是怎么访问到 sayHi 方法和 jdk 属性的呢?

    • hasOwnProperty() 方法 ,用于判断某个属性是否为该对象自身的成员
    • 看看大致的访问过程:


      • console.log(str.hasOwnProperty('sayHi'))

        ;//false str自身没有sayHi方法

        console.log(str.__proto__.hasOwnProperty('sayHi'));

        //false 原型对象也没有sayHi方法

        console.log(str.__proto__.__proto__.hasOwnProperty('sayHi'))

        ;//true 原型的原型有sayHi方法str -> str._ _ proto _ _ -> str._ _ proto _ _ . _ _ proto _ _ 感觉到什么吗?
    • 我们来描述一下执行过程:


      • str.sayHi() --> 自身查找 --> 没有sayHi方法 -->
      • 查找上层原型

        str._ _ proto _ _ --> 指向 String.prototype对象 --> 没有sayHi方法 -->
      • 查找上层原型

        String.prototype._ _ proto _ _ --> 指向Object.prototype对象 --> 找到sayHi方法 --> 执行sayHi方法
  • var Person =function(name){
        this.name=name;
    };
    Person.prototype.getName = function(){
        console.log(this.name)
    };
    var p1 =new Person('jack');
    console.log(p1.__proto__===Person.prototype);//true
    console.log(p1.__proto__.__proto__===Object.prototype);//true
    console.log(p1.__proto__.__proto__.__proto__);null
    

    • p1

      —-

      __proto__

      —-

      Person.prototype

      —-

      __proto__

      —-

      Object.prototype

      —-

      __proto__

      —–null
    • 由上可知:原型链,就是在当前对象中如果自身没有该属性,则向上一层原型对象中寻找,一直到最外层(null)
    • 每个继承父函数的子函数的对象都包含一个内部属性

      _ _ proto _ _

      ,该属性包含一个指针,指向父函数的prototype,若父函数的原型对象的

      _ _ proto _ _

      属性为再上一层函数的原型,在此过程中就形成了原型链。



3.继承



3.1.构造函数继承
  • 原理:调用父类构造函数,并改变其中的this (bind、call、apply)

    unction Cat(n,c){ // 猫 类
       this.name = n;
       this.color = c;
       this.trait = function (){
           console.log('卖萌~');
       }
    }
    Cat.prototype.skill = function (){ // 原型上的属性方法
       console.log('抓老鼠');
    }
    // 需求:狗要卖萌,狗要多管闲事-抓老鼠
    function Dog(n,c,f){ // 狗 类
       this.food = f;
       Cat.call(this,n,c); // 狗冒充猫,访问猫的属性方法
    }
    var dog1 = new Dog('二哈','yellow','shi');// 实例对象
    console.log(dog1.name); // 二哈
    dog1.trait(); // 卖萌
    dog1.skill(); // 报错 dog1.skill is not a function
    

    我们看到这种继承方式有局限性,“父类”原型上的属性方法无法继承,所以二哈没有抓老鼠的技能



3.2.原型链继承
  • 原理:将原型对象链接到另一个对象实现继承(改变原型的指向)

    function Cat(n,c){ // 猫 类
       this.name = n;
       this.color = c;
       this.trait = function (){
           console.log('卖萌~');
       }
    }
    Cat.prototype.skill = function (){// 原型上的属性方法
       console.log('抓老鼠');
    }
    function Dog(n,c,f){ // 狗 类
       this.food = f;
    }
    Dog.prototype = new Cat(); // 把狗的原型指向猫的实例对象
    var dog1 = new Dog('二哈','yellow','shi');
    console.log(dog1.name); // undefined
    console.log(dog1.food); // shi
    dog1.trait(); // 卖萌~
    dog1.skill(); // 抓老鼠
    console.log(dog1.constructor); // Cat
    
    • 实例化对象的时候不能给“父类”传参,导致访问dog1.name没有值
    • 有句台词:‘人是人妈生的,妖是妖妈生的 ’ 现在 dog1.constructor 指向 Cat,意味着 二哈 是猫妈生的!很显然这不符合伦理,也不环保…

3.3.混合继承(组合继承)

function Cat(n,c){
   this.name = n;
   this.color = c;
   this.trait = function (){
       console.log('卖萌~');
   }
}
Cat.prototype.skill = function (){
   console.log('抓老鼠');
}
function Dog(n,c,f){
   this.food = f;
   Cat.call(this,n,c);// 对象冒充继承
}
Dog.prototype = Object.create(Cat.prototype);// 寄生继承
Dog.prototype.constructor=Dog;// 指正构造器
var dog1=new Dog('二哈','yellow','shi');
console.log(dog1.name);// 二哈
console.log(dog1.food);// shi
dog1.trait();// 卖萌~
dog1.skill();// 抓老鼠
console.log(dog1.constructor);// Dog
  • 两种方式结合可以实现相对比较完美的“继承”别忘了指正构造器(类型),不能认贼作父!



函数的this指向



1.this的指向

  1. this指向函数的调用对象

  2. this指事件的调用对象

  3. 在构造函数中this指向示例对象

  4. 再prototype原型的方法中,this指向示例对象、

  5. 找不到函数的调用的this指向window

  6. 箭头函数没有自己的this,它的this指向上下文中的this(即所处环境的this)

    function fn(x, y) {
            console.log('coming',this);
            console.log(x + y);   
     }
    
     let obj={
          name:'nick',
          hobby:'basketball'
     }
     // 调用函数,改变函数中的this
     fn.call(obj,5,7)   //第一个参数改变了this的指向,其他参数对应函数里的参数,立即执行=>call
     fn.apply(obj,[5,7])   //第一个参数改变了this的指向,第二个参数是个数组,立即执行=>apply
     let emit = fn.bind(obj,5,7)   //第一个参数改变了this的指向,其他参数对应函数里的参数,
     //但需调用再执行=>bind
     emit()
    



call、apply、bind

  • call、apply、bind都是Function.prototype的方法,所以每个函数都有call、apply、bind属性。
  • call、apply、bind的作用都可改变函数内部的this指向



1.call

  • call()的作用

    • 改变了原来函数的this指向
    • 绑定函数内部的this指向,this指向obj
    • 没有返回值,会执行当前函数。
    • 传参方式:call()里的第一个参数一个对象,后边参数是用逗号隔开的列表。


      • fn.call(obj,2,3,4,5)



2.apply

  • apply()的作用

    • 改变了原来函数的this指向
    • 绑定函数内部的this指向,this指向obj
    • 没有返回值,会执行当前函数。
    • 传参方式:apply()里只有两个参数,第一个参数是一个对象,第二个参数是一个数组


      • fn.apply(obj,[2,3,4,5])



3.bind

  • bind(obj)的作用

    • 改变了原来函数的this指向

    • 绑定函数内部的this指向,this指向obj

    • 返回值是调用bind方法的函数体本身,不会执行当前函数,要调用一下f()。

    • var obj={
          a:1,
          b:2
      }
      function fn(){
          console.log(this)
      }
      var f = fn.bind(obj)
      f()//{a:1,b:2}
      

  • 总结


    1. call、apply和bind都可以改变函数的this指向

    2. call、apply和bind第一个参数的是this要指向的对象

    3. call、apply和bind都可以后续为函数传参,apply是将参数并成一个数组,call和bind是将参数依次列出。

    4. call、apply都是直接调用,bind生成的this指向改变函数需要手动调用。



JQurey



1.

jQure

y的选择器


  • $(".box")

    通过类名

  • $("div")

    通过标签名

  • $("#box")

    通过id
  • 特殊选择器


    • $("li:first")

      获取li中的第一个

    • $("li:last")

      获取li中的最后一个

    • $("li:eq(3))

      获取li中索引是3的那一个

    • $("li:odd")

      获取li中索引是奇数的li

    • $("li:even")

      获取li中索引是偶数的li

  • 转换:


    • var box = document.querySelector('#box')

      ; // js对象

    • var $box = $('#box');

      // jq对象
    • JQ获取DOM对象,转domj元素,操作样式


      • $box[0].style.color = 'blue'

        ; // 转成 js 对象

      • $box.get(0).style.color = 'blue'

        ;// 转成 js 对象
    • JS获取的DOM对象,转JQ对象


      • $(box).css('color','red');

        // 转成 jq 对象



2.

jQurey

筛选器


  • first()

    • 用法:

      $(".box").first()
    • 含义:.box类名集合下的第一个

  • last()

    • 用法:

      $(".box").last()
    • 含义:.box类名集合下的最后一个

  • eq()

    • 用法:

      $(".box").eq(3)
    • 含义:.box类名集合下的索引值为3的那一个

  • next()

    • 用法:

      $('span').next()
    • 含义:.拿到span标签的下一个兄弟元素

  • nextAll()

    • 用法:

      $('span').nextAll()
    • 含义:.拿到span标签后边的所有元素

  • nextUntil()

    • 用法:

      $('span').nextUntil(.box)
    • 含义:.拿到span标签后边到.box元素的所有元素,不包含.box

  • prev()

    • 用法:

      $('span').prev()
    • 含义:.拿到span标签的上一个兄弟元素

  • prevAll()

    • 用法:

      $('span').preAll()
    • 含义:.拿到span标签前边的所有元素

  • prevUntil()

    • 用法:

      $('span').prevUntil(.box)
    • 含义:.拿到span标签后边到.box元素的所有元素,不包含.box

  • parent()

    • 用法:

      $('span').parent()
    • 含义:.找出span标签的父元素

  • parents()

    • 用法:

      $('span').parents()
    • 含义:.找出span标签的所有父元素,直到html元素为止

  • parentsUntil()

    • 用法:

      $('span').parentsUntil(选择器)
    • 含义:.找出span标签的所有父元素,直到

      选择器

      元素为止

  • children()

    • 用法:

      $('span').children()
    • 含义:.筛选出元素所有的子级元素
    • 用法:

      $('span').children(选择器)
    • 含义:.筛选出span元素中所有的符合

      选择器

      de 子级元素

  • sibilings()

    • 用法:

      $('span').sibilings()
    • 含义:.筛选出span标签的所有的兄弟级元素

  • find()

    • 用法:

      $('span').find(.box)
    • 含义:.筛选出span标签中所有子代元素里类名为

      .box

      的元素

      • 在一个元素的后代元素中查找对应选择器的元素
      • 在一个元素集合的每一个元素中, 查找后代元素

  • index()

    • 用法:

      $('span').index()
    • 含义:.拿到span在其父元素的索引值



3.

jQurey

操作文本内容


  • html()

    • 语法:

      $("div").html()
    • 不传参数的时候,就是获取元素内部的超文本内容
    • 传递参数的时候,就是设置元素的超文本内容

  • text()

    • 语法:

      $("div").text()
    • 不传参数的时候,就是获取元素内部的文本内容
    • 传递参数的时候,就是设置元素的文本内容

  • val()

    • 语法:

      $("div").val()
    • 不传参数的时候,就是获取

      input

      标签的

      value

    • 传递参数的时候,就是设置就

      input

      标签的

      value

  • 总结:


      • html()

        :只能获取第一个元素的超文本内容

      • text()

        :能获取元素集合内所有元素的文本内容合

      • val()

        :只能获取第一个元素的 value 值
    • 设置:


      • html()

        :给元素集合内所有的元素设置超文本内容

      • text()

        :给元素集合内所有的元素设置文本内容

      • val()

        :给元素集合内所有的元素设置

        value



4.

jQurey

操作元素类名


  • addClass()

    添加类名

    • 语法:

      $("span").addclass("box")
    • 注释:执行这个方法会给元素集合里面所有的元素添加上固定的类名,如果有就不添加了,没有才会添加

  • removeClass()

    移除类名

    • 语法:

      $('div').removeClass('box')
    • 注释:移除div集合中含有类名.box的div的雷鸣

  • toggleClass()

    切换类名

    • 语法:

      $('div').toggleClass('container')
    • 注释:执行这个方法会给所有元素加上这个类名,有的删除,没得加上

  • hasClass()

    判断有没有这个类名

    • 语法:

      $('div').hasClass('box')
    • 注释:会返回一个布尔值



5.

jQurey

操作元素的样式


  • css("样式名称")

    • 获取元素集合的第一个元素的样式值,不管是行内样式还是非行内样式都能获取

  • css("样式名称",'样式的值')

    • 设置元素的样式值, 元素集合能获取多少个元素就设置多少个元素
    • 设置的时候, 所有的单位都可以不写, 默认添加 px 为单位

  • css(对象)

    • css({

      width:100,

      height:100,

      })

    • 批量设置 css 样式

    • 给元素集合里面的所有元素, 批量设置样式



6.

jQurey

操作元素的属性


  • attr()


    attribute

    • attr(要读取的属性名),传递一个参数的时候是读取
    • attr(属性名, 属性值): 传递两个参数的时候是设置


    removeAttr()

    • 专门用来移除属性的


    attr 这套方法的注意:

    • 所有的属性都会显示在标签上(原生属性和自定义属性)
    • 不管你设置的是什么数据类型, 都会给你变成字符串
    • removeAttr 删除 attr 设置的属性, 有多少删除多少(针对自定义属性)

  • prop()


    property

    • prop(要读取的属性名): 传递一个参数的时候是读取
    • prop(属性名, 属性值): 传递两个参数的时候是设置


    removeProp()

    • 专门用来移除属性的


    prop 这套方法的注意:

    • 非原生属性, 不会显示在标签上, 但是你可以获取使用
    • 你存储的是什么数据类型, 获取的时候就是什么数据类型
    • removeProp 删除 prop 设置的属性, 有多少删除多少(针对自定义属性)
    • removeProp() 不能删除原生属性 id class style 这样的

  • data()

    • data(要读取的属性名): 传递一个参数的时候是读取
    • data(属性名, 属性值): 传递两个参数的时候是设置


    removeData()

    • 专门用来删除数据的


    data 这套方法的注意:

    • 和元素的原生属性没有关系, 可以设置 id, 但是和元素的 id 没关系
    • 就是在元素身上给你开辟一个地方, 存储一些数据
    • 你设置的是什么数据类型, 拿到的就是什么数据类型
    • removeData 删除 data 设置的属性
    • data() 方法也能读取写在标签上的 H5 标准自定义属性
    • 三个方法存储内容

      • attr 设置的自定义属性存储在标签身上
      • prop 设置的自定义属性存储在元素对象里面
      • data 设置的自定义属性存储在元素对象里面单独开辟的一个对象



7.

jQurey

绑定事件


  • on()


    • on('事件类型', 事件处理函数)

      • 给元素集合内所有的元素绑定一个事件

      • $('ul').on('click', function handlerA() { console.log('我是事件处理函数 ') })
        

    • on('事件类型', '事件委托', 事件处理函数)

      • 把 事件委托 位置的元素的事件 委托给了前面的元素集合

      • $('ul').on('click', 'li', function () {
              console.log('我被点击了, 事件委托')
            })
        

    • on('事件类型', 复杂数据类型, 事件处理函数)

      • 给每一个元素绑定一个事件, 复杂数据类型是触发事件的时候传递的参数

      • $('li').on('click', { name: 'Jack', age: 18 }, function (e) {
              console.log('我被点击了, li')
              console.log(e)
            })
        

    • on('事件类型', '事件委托', 任意数据类型, 事件处理函数)

      • 做一个事件委托的形式, 第三个参数位置的数据

      • 是触发事件的时候, 可以传递进去的数据

      • 给 li 做一个事件委托, 委托给了 ul
              每一个 li 点击的时候都能得到一个传递进去的数据叫做 hello world
            $('ul').on('click', 'li', 'hello world', function (e) {
              console.log('我又被点击了')
              console.log(e)
              console.log(this) // 就是你点击的那一个 li
            })
        

    • on(对象)

      • 给一个元素绑定多个事件的方式

      • 给 ul 同时绑定三个事件
              这个时候就不能传递参数了
              这个时候就不要贪图事件委托了
            $('ul').on({
              click: function () { console.log('点击事件') },
              mouseover: function () { console.log('移入事件') },
              mouseout: function () { console.log('移出事件') }
            })
        

    • off( event , selector , fnName )

      on()的反向操作,移除用on()绑定的事件


  • 事件绑定及移除


    • bind( )

      为每个匹配的元素绑定一个或多个事件处理函数语法:bind( event , fn ) //不能给未来元素添加事件

      • $("p").bind("click", function(){
            alert( $(this).text() );
        });
        
        $('h2').bind({
            mouseover: function (){
                alert('移上');
            },
            mouseout: function (){
                alert('移出');
            }
        })
        

    • unbind( )



      bind( )

      反向的操作,删除元素的一个或多个事件语法:

      unbind(event , fnName )



8.事件对象

  • 阻止冒泡/传播:e.stopPropagation() return false;
  • 阻止默认行为:e.preventDefault(); return false;
  • 事件类型:

    • e.type触发事件的元素:
    • e.target ( 原生DOM节点 )
    • 指示按了哪个键或按钮:e.which 1 2 3
    • 鼠标的相对坐标:e.clientX/Y e.pageX/Y
    • 事件发生时的时间戳:e.timeStamp(毫秒数)



9.

jQurey

的节点操作

  • 创建节点


    • $()

      或者

      jQuery()

      • () 里面传递一个 html 格式文本的时候就是创建节点
      • () 里面传递一个选择器的时候, 就是获取页面中的 DOM 元素
      • () 里面传递一个选择器的时候, 就是获取页面中的 DOM 元素
      • () 里面传递一个 html 格式文本的时候, 就是创建一个 DOM 元素
      • 例子:

        $('<div>我是一个创建出来的节点</div>')
  • 插入节点

    • 在页面元素内部插入

      • 语法:在后面插入


        1. 页面元素.append(要插入的元素)

        2. 要插入的元素.appendTo(页面元素)
      • 语法:在前面插入


        1. 页面元素.prepend(要插入的元素)

        2. 要插入的元素.prependTo(页面元素)
  • 删除节点

    • 语法:


      1. 页面元素.empty()

        -> 把自己变成空标签

      2. 页面元素.remove()

        -> 把自己移除


  • 替换节点
    • 语法:


      1. 页面元素.replaceWith(替换元素)

      2. 替换元素.replaceAll(页面元素)


  • 克隆节点
    • 语法:

      元素.clone()

      1. 第一个参数: 自己的事件是否克隆
      2. 第二个参数: 子节点的事件是否克隆(当第一个参数为 false 的时候, 第二个参数没有意义)

    ​ 注意:不管你是否传递参数, 都会把所有后代元素都克隆下来



10.

jQurey

获取元素的尺寸

  • 三套方法, 四种使用方式:


    • width()



      height()

      • 注释:获取元素的内容区域的尺寸(content)

    • innerWidth()



      innerHeight()

      • 注释:获取的元素的内容区域+padding区域的尺寸

    • outerWidth()



      outerHeight()

      • 注释:获取的元素的内容区域+padding区域+border的尺寸

    • outerWidth(true)



      outerHeight(true)

      • 注释:获取的元素的内容区域+padding区域+border+margin的尺寸



11.

jQurey

获取元素的位置


  • offset()

    • 语法:

      1. 不传递参数就是读取,读到的元素相对于页面的位置关系,返回值是一个对象 { left: xxx, top: xxx }
      2. 传递一个对象就是写入 { left: xxx, top: xxx }

  • position()

    • 语法:

      1. 只读的方法,元素相对于定位父级的位置关系,得到的也是一个对象 { left: xxx, top: xxx }



12.

jQurey

获取页面卷去的尺寸


  • scrollTop()

    /

    scrollLeft()

    • 语法:

      1. 不传递参数的时候就是获取卷去的高度/宽度
      2. 传递一个参数就是设置卷去的高度/宽度



13.

jQurey

的函数


  • ready()

    事件

    • 类似于 window.onload 事件
    • window.onload -> 会在页面所有资源加载完毕执行
    • ready() -> 会在页面 html 结构加载完毕后执行
    • 也叫做 jQuery 的入口函数
    • 有一个简写的形式

      $(function () {})

  • each()

    方法

    • 类似于

      forEach()

      , 遍历数组的

    • jQuery 的元素集合, 是一个 jQuery 数组, 不是一个数组, 不能使用 forEach()

    • $('div').each(function (index, item) {
         // index -> 就是索引
         // item -> 就是每一项
         console.log(index, item)
       })
      



14.

jQurey

的动画

  • 标准动画


    • show()

      显示

      • 语法:show(时间, 运动曲线, 运动结束的函数)

      • $('div').show(2000, 'linear', function () {
               console.log('显示结束')
             })
        

    • hide()

      隐藏

      • 语法:hide(时间, 运动曲线, 运动结束的函数)

      • $('div').hide(2000, 'linear', function () {
               console.log('隐藏结束')
             })
        

    • toggle()

      切换(如果是隐藏就显示, 如果是显示就隐藏)

      • 语法:toggle(时间, 运动曲线, 运动结束的函数)

      • $('div').toggle(2000, 'linear', function () {
               console.log('切换结束')
             })
        
  • 折叠动画


    • slideDown()

      -> 下滑显示

      • 语法: slideDown(时间, 运动曲线, 运动结束的函数)

      • $('div').slideDown(2000, 'linear', function () {
               console.log('下滑结束')
             })
        

    • slideUp()

      -> 上滑隐藏

      • 语法: slideUp(时间, 运动曲线, 运动结束的函数)

      • $('div').slideUp(2000, 'linear', () => console.log('上滑结束'))
        

    • slideToggle()

      -> 切换滑动显示和隐藏

      • 语法: slideToggle(时间, 运动曲线, 运动结束的函数)

      • $('div').slideToggle(2000, 'linear', function () {
               console.log('切换结束')
             })
        
  • 渐隐渐显动画


    • fadeIn()

      -> 渐渐的显示(贱贱的显示)

      • 语法: fadeIn(时间, 运动曲线, 运动结束的函数)

    • fadeOut()

      -> 渐渐的消失

      • 语法: fadeOut(时间, 运动曲线, 运动结束的函数)

    • fadeToggle()

      -> 渐渐的切换显示和消失’

      • 语法: fadeToggle(时间, 运动曲线, 运动结束的函数)

    • fadeTo()

      -> 去到一个你指定的透明度

      • 语法: fadeTo(时间, 你指定的透明度, 运动曲线, 运动结束的函数)
  • 综合动画


    • animate()

      • 基本上大部分的 css 样式都可以动画

      • transform 不行, 颜色不行

      • 语法: animate({}, 时间, 运动曲线, 运动结束的函数)

      • $('button').click(() => {
             $('div').animate({
               width: 300,
               height: 300,
               left: 30,
               top: 50,
               borderRadius: '50%',
               opacity: 0.5
             }, 2000, 'linear', () => console.log('运动结束'))
           })
        
  • 停止动画


    • stop()

      • 当这个函数触发的时候, 就会让运动立刻停下来
      • 你运动到哪一个位置了就停止在哪一个位置

    • finish()

      • 当这个函数触发的时候, 就会让运动立刻停下来
      • 不管你运动到了哪一个位置, 瞬间到达运动完成位置



15.$符冲突问题


  • noConflict()方法


    • jQuery

      中的

      noConflict( )

      方法的作用就是让

      jQuery

      放弃对



      使

      符的所有权当代码中调用该方法后,不可以使用































































      使








      来调用

      jQuery

      方法


      • $.noConflict( );

        • “$(‘#div’).click(…)`; //无效

        • jQuery(‘#div’).click(....)

          ; //有效

    • jQuery

      中允许我们自定义

      jQuery

      的别名


      • var jq=$.noConflict();


        • jq(‘#div’).click(....);

          //有效

        • jQuery(‘#div’).click(....);

          //有效

        • $(‘#div’).click(....);

          //无效 报错
    • 如何继续使用$符


      • $.noConflict( );

      • jQuery(function ($){    $(‘h1’).click( function (){ alert($(this).html( ) );});
        



16.

jQuery

扩展 ( 插件开发接口 )


  • $.extend()方法


    • jQuery.extend([boolean],target [,object1] [,objectN])

    • [boolean] 表示是否深拷贝,默认false 浅拷贝当提供两个或多个对象参数时,其他对象的属性将合并到目标对象。

    • var obj1 = {a: 1, b: 2, c: {d: 4, e: 5}};
      var obj2 = {c: {g: 7}, d: 8};
      $.extend(obj1,obj2); //浅拷贝
      $.extend(true,obj1,obj2); //深拷贝
      
      for (var key in obj2){ //浅拷贝
          obj1[key] = obj2[key];
      }
      
      var obj3 = JSON.stringify(obj2); //深拷贝
      
      Object.assign(obj1,obj2); //浅拷贝
      
      console.log( obj1.c === obj2.c );
      



17.

jQuery ajax


  • $.ajax( options )

    通过 HTTP 请求加载远程数据

    • url:请求的url地址

      type:请求类型(get/post…)

      cache:是否读取缓存,默认true

      data:要发送给服务器的数据,示例:”name=jack&age=19″string或Object{name:“jack”,age:“19”}

      async:默认true,为异步请求

      dataType:服务器返回的数据类型特殊的格式JQ会进行预解析和兼容性修复。可选择的值:“xml” , “html” , “script” , “json” , “text”,”jsonp”等

      timeout:设置超时(毫秒)

      success:请求成功的回调函数

      error:请求失败的回调函数

      complete:请求完成后的回调函数,无论成功与失败

      beforeSend:发送请求前可以修改XMLHttpRequest对象的函数,例如添加自定义 HTTP头。在beforeSend中如果返回false可以取消本次ajax请求。XMLHttpRequest对象是惟一的参数。

    • $('#login').click(function (){
          $.ajax({
              type:'get',
              url:'test.php',
              dataType:'json',
              cache:false, //不使用缓存
              success:function (json){
                  $('h1').html(json.name+json.sex+json.age);
              },
              error:function (){
                  alert('请求失败');
              }
          });
      })
      

  • serialize( )

    • 将一个form表单内的所有数据转换为可以发送给服务器的字符串示例

      • $("form").serialize()
        "name=小明&age=19&msg=abc"
        

  • $.get( url [, data] [, callback] [, dataType]);

    • url : 请求的URL

      data : 可选,发送至服务器的数据

      callback : 可选,请求完成时的回调函数

      dataType : 可选,参照$.ajax参数中的dataType

    • $.get(“act.php”,{user:“cainiao”,pass:123},function (data){
          alert(data.msg);
      },“json”);
      

  • $.post()

    • $.post 与 $.get 语法相同,唯一的不同就是请求是以post方式进行。

    • $.post(“act.php”,{user:“cainiao”,pass:123},function (data){
          alert(data.msg);
      }, ”json”);
      



18.

jsonp:

跨域请求

  • ipt.onkeyup=function (){
        $.ajax({
            type:'get',
            url:'http://suggestion.baidu.com/su?wd='+$('#ipt').val(),
            dataType:'jsonp',
            jsonp:'cb',
            // jsonpCallback:'mycallback',
            success:function (json){
                // $('#list').empty();
                $('#list').html('');
                for (var i = 0; i < json.s.length; i++) {
                    $('#list').append('<li>'+json.s[i]+'</li>');
                }
            }
        });
    }
    



swiper



1.引入

  • 引入css样式
<link rel="stylesheet" href="dist/css/swiper.min.css">
  • 引入script代码
 <script src="dist/js/swiper.min.js"></script>



2.HTML结构

//如果同一个页面要用几个轮播图,那么可以给.swiper-container这个div加上id选择器来区分
<div class="swiper-container">
    <div class="swiper-wrapper">
        <div class="swiper-slide">Slide 1</div>
        <div class="swiper-slide">Slide 2</div>
        <div class="swiper-slide">Slide 3</div>
    </div>
    <!-- 如果需要分页器 -->
    <div class="swiper-pagination"></div>
    
    <!-- 如果需要导航按钮 -->
    <div class="swiper-button-prev"></div>
    <div class="swiper-button-next"></div>
    
    <!-- 如果需要滚动条 -->
    <div class="swiper-scrollbar"></div>
</div>
//导航等组件可以放在container之外



3.script代码

<script>        
  var mySwiper = new Swiper ('.swiper-container', {
    direction: 'vertical', // 垂直切换选项
    loop: true, // 循环模式选项
    
      
      
      
    // 如果需要分页器
    pagination: {
      el: '.swiper-pagination',
    }, 
    // 如果需要前进后退按钮
    navigation: {
      nextEl: '.swiper-button-next',
      prevEl: '.swiper-button-prev',
    },
    // 如果需要滚动条
    scrollbar: {
      el: '.swiper-scrollbar',
    },
  })        
  </script>



github



1.github的操作


  • git bash here



    邮件要操作的文件夹


  • git config --list



    查看配置清单


  • git config --global user.name "你的用git户名"



    给git配置用户名


  • git config --global user.email "你的用git邮箱"


    给git配置用邮箱



2.github命令


  • cd



    进入文件夹


  • cd..



    返回上一层目录


  • mkdir



    创建项目


  • pwd



    显示当前工作目录的全路径


  • touch xx



    新建xx文件


  • rm



    删除文件


  • ls



    查看当前目录所有文件


  • clear



    清屏



3.创建本地仓库


  • git init


    • 创建本地仓库,会生成.git文件夹


  • git add .


    • 将本地仓库的数据传输到暂存区


    • git status


      查询工作区和暂存区数据工作状态

      • On branch master
        nothing to commit, working tree clean
        
        在你的工作master分支上,工作区和暂存区文件一样
        红色提示是工作区有更改,未提交到暂存区
        绿色提示是暂存区有更改
        

  • git commit -m '提交注释'


    • 将暂缓区的内容提交到本地仓库

  • git diff ‘工作区的文件名’


    • 查看工作区修改的文件的内容

  • git log

    /

    git reflog


    • 查看工作日志

  • git reset --hard HEAD^


    • 回复到上一个版本号

  • git reset --hard HEAD^^


    • 回复到倒数第二个版本号

  • git reset --hard "版本号"


    • 回复到指定的版本号



4.关联本地仓库和远程仓库


  • git remote add origin '地址'

  • git remote -v



    查看是否连接成功


  • git remote rm origin



    删除关联的地址


  • git push -u origin master



    第一次推送本地仓库到******github


  • git push



    以后推送本地仓库到******github



5.创建切换合并删除分支


  • git branch '分支名(不用加双引号)'



    创建分支


    git branch day1


  • git checkout '分支名'



    切换分支


  • git checkout -b '分支名



    创建切换分支


  • git push origin '分支名'



    推送到哪个分支上


  • git merge '分支名'



    合并某分支到当前分支


  • git branch -d '分支名'



    删除某分支

  • git branch –list 查看自己创建的分支



    分支的合并

    1.创建分支 git branch day1

    2.在当前的分支中修改内容后,

    在git add .

    git commit -m “first”

    git push origin day1 (创建好分支)



    切换到主分支(master)

    git checkout master

    在master进行分支的合并

    git merge day1

    然后在



6.更新/拉去

  • git fetch 更新远程代码到本地,不会自动merge
  • git pull 更新远程代码到本地,会自动合并merge
  • git pull origin 分支名 更新远程分支代码到本地



7.克隆项目


  • git clone '地址'



    克隆别人的项目到自己的电脑上



8.配置SSH


  1. cd ~/.ssh

    检查是否电脑又ssh

  2. ssh-keygen -t rsa -C 'github邮箱地址'
  3. 三次回车
  4. Enter file in which to save the key (/c/Users/lsh/.ssh/id_rsa) 去找id_rsa的文件
  5. 根据提示到C盘找(id_rsa.pub)pub后缀文件中的所有内容,去vscode复制内容
  6. 打开github 点击头像找setting (找到ssh and GPG keys)
  7. 找ssh ,复制进去。



9.设置git忽略文件

  1. 在工作区创建文件:.gitignore
  2. 在vscode打开,设置忽略文件列表 node_modules



nodeJs



1.node操作


  • win+r+cmd



    打开命令行终端


  • node -v

    或者

    node --version



    检查版本号


  • node '文件名'



    文件名不要写成

    node.js

  • cd..



    返回上级目录


  • dir


    查看目录

    ****

  • tree



    查看偶有文件夹和子文件夹里的内容


  • cd 文件夹名称



    进入那个文件夹


  • 盘符:



    切换盘符



  • 创建文件夹


    • mkdir 你要创建的文件夹名称

    • md 你要创建的文件夹名称


  • 删除文件夹


    • rd 你要删除的文件夹的名称



      只能删除空文件夹


    • rd /s /q 你要删除的文件夹名称



      强制删除文件夹


  • xcopy 你要复制的文件夹名 复制以后的文件夹名



    复制文件夹


  • echo 你要写入的内容>你指定的文件



    向文件里写入一些内容,完全覆盖式的写入


  • echo 你要写入的内容>>你指定的文件



    向文件里写入一些内容,追加


  • type 你要查看的文件名



    查看文本里的内容化


  • ren 你要修改的文件 你要改成什么名字



    给文本重命名


  • del 你要删除的文件名



    删除文件


  • copy 你要复制的文件名 复制以后的文件名



    复制文件


  • remove 你要移动的文件名 你要移动到哪一个目录


    移动文件名

  • cls



    清屏


  • ipconfig



    查看电脑ip


  • ping www.baidu.com -t



    测试网速


  • systeminfo



    查看电脑信息

  • nodejs 的特点

    • 是一个基于V8引擎的JavaScript运行环境
    • 单线程
    • 非阻塞I/O 也就是异步,通过回调函数,
    • 事件驱动



2.node模块化



2.1.内置模块
  • (核心模块包括 os(操作系统)、fs(文件系统)、http(网络系统)),安装node这个环境的时候就自带有的模块(js文件),不需要下载,导入进来使用就好。

  • fs(文件系统)

    • 专门来读取写入文件内容的

      * 	导入模块用`require()`方法
      1.	导入fs模块   `const fs = require('fs')`
      *	fs 模块的几个方法
      1.	`fs.readFile()` 专门用来异步读取文件的方式
      	语法:`fs.readFile('你要读取的文件路径',读取文件格式(选填),读取文件成功的回调函数)`
      	`fs.readFile('./test.txt','utf-8',function(err,data){
      	//函数是读取文件完成后执行的回调函数
      	//接受两个形参
      		err=>读取失败的时候的失败信息
      		data=>读取成功的时候的读取的内容
      			->读取的内容默认是buffer格式的字符串,我们看不懂,计算机看的懂
      			->如果想读取一个我们看的懂得文件,那么要在第二个参数设置'utf-8'
      	if(err){
      	 return 	console.log(err)
      	}
      	console.log(data)
      	})`
      
      2.`fs.readFileSync()` 专门用来同步读取文件的方式
      	语法:`fs.readFile('你要读取的文件路径',读取文件格式(选填))`
          `let data = fs.readFile('你要读取的文件路径','utf-8')`
      1.	`fs.writeFile()` 专门用来异步写入文件的方式,覆盖式的写入
      	语法:`fs.writeFile('你要写入的文件路径',你要写入的内容,读取文件成功的回调函数)`
          `fs.writeFile('./test.txt',你要写入的内容,function(){
      	console.log('写入成功了')
      	})`
      2.	`fs.writeFileSync()` 专门用来同步步写入文件的方式
      	语法:`fs.writeFile('你要写入的文件路径',你要写入的内容)`
          `fs.writeFileSync('./test.txt',你要写入的内容
          `console.log('写入成功了')
      1.	`fs.appendFile()` 专门用来异步写入文件的方式,追加式的写入
      	语法:`fs.appendFile('你要写入的文件路径',你要写入的内容,读取文件成功的回调函数)`
          `fs.appendFile('./test.txt',你要写入的内容,function(){
      	console.log('写入成功了')
      	})`
      


2.2.http内置模块
  • 这个模块是专门用来创建http服务的,只能支持http协议

  • 就是可以把电脑上的命令行窗口当成一个服务器来使用

    *	导入http模块
    	const http = require('http')
        导入fs模块
        const fs = require('fs')
    *	创建http服务
        const server = http.createServer(function(req,res){
            +这个函数是前端的每一个请求都会执行这个函数
            +只有我在监听这个端口号有请求过来的时候,就会执行
            +这个参数接收两个形参
            	-req 表示每次请求的信息
                	req.url	表示本次请求的地址
                -res 表示每次请求的响应
                	res.end()	表示本次给回的响应
          	+通过不同的url做不同的事情
        if(req.url==='./index.html'){
            fs.readFile('./index.html','utf-8',function(err,data){
                if(err) return console.log(err)
                //响应之前设置响应头
                res.setHeader('Content-Type','text/html;charset=utf-8')
                res.end(data)
            })
        }
        console.log('我执行了,表示有请求进来了')
        })
    *	监听一个端口号(端口号是0-65535,0-1023不推荐使用)
    	server.listen(8080,function(){
            console.log('监听8080端口成功')
        })
    *	代码写完以后,当你在终端运行这个文件的时候
    		+你的那个终端就是一个服务器了
    +你就可以打开浏览器去访问localhost:8080
    


2.3.自定义模块
  • 自定义模块就是在一个js文件里写入一些方法,然后要把js文件里的方法导出,外部才能接收。
  • 每个js文件里自带 module对象,每个module对象里自带exports对象,module.exports就是这个文件向外导出的内容,我们向外暴露该对象内容就可以了
funtion fn1(){
    console.log('我是a模块里的fn1方法')
}
function fn2(){
    console.log('我是a模块里的fn2方法')
}
module.exports.fn1 =fn1;
module.exports.fn2 =fn2;
  • 模块导入的方法

    • ·导入模块用

      require()

      方法
    • 在b文件里导入我们自定义的模块 文件名
  • 为什么浏览器里面不需要导出直接导入就行

    • 之所以你浏览器不用导出,是我因为我们的浏览器里有一个顶级对象window
    • 你写在全局的变量都是挂在window上的
    • 在一个html文件里,多个js文件公用一个window对象
  • 在node环境下

  • 我们没有真正意义上的全局对象

  • 所以我们需要在一个文件导入,一个文件导出的时候才能使用

  • 我们每个js都是独立模块,都会独立模块作用限制着

  • 在你写a.js文件里的内容,再写b.js文件里是使用不了的


  • 第三方模块



3.npm



3.1.什么是npm
  • 是node的生态系统的一部分
  • 包管理器:专门管理js相关的所有插件/类库/框架
  • 检查版本号

    npm --version

    或者

    node -v


3.2.npm的使用

  • npm install 包名

    (简写:

    npm i 包名

    • 下载js相关的所有插件/类库/框架
    • 需要在哪个文件夹里使用,就在哪个文件夹下开启下载命令
    • 执行完毕后,就会自动下载,并且在当前文件夹下会生成node_modules的文件夹
    • 这个文件夹里就是你下载的第三方包
    • 下载下来的内容一般去node_modules文件夹里的dist文件夹里找

  • npm install 包名@指定版本号

    (简写

    npm i 包名@指定版本号

    • 下载指定版本的包,npm默认下载最新的
    • 同名的包在 node_modules里面只能保留一个版本

  • npm init

    (j简写

    npm init -y

    ,所有项会走默认值,前提文件夹必须是英文名字)

    • 初始化项目
    • 就是给你生成一个package.json 文件,用来描述你当前的项目
    • 并且用dependencies记录下你使用npm下载了那些依赖

  • npm uninstall 包名

    (简写:

    npm unl 包名

    • 删除包

      • 直接手动删除,不会修改package.json文件
      • 使用指令删除,会修改package.json文件

  • npm install



    npm i

    • 会把当前文件夹下的package.json里的第三方插件都下载下来
    • 我们在传输项目的时候,不需要传递node_modules这个文件夹
    • 只需要把package.json保留,到别人电脑上执行

      npm install

  • npm update

    • 更新全部依赖包
    • 版本号小知识

      • x.y.z
      • x:当你做了不兼容的 API 修改。为 0 时一般表示处于开发阶段。
      • y:当你做了向下兼容的功能性新增。
      • z:当你做了向下兼容的问题修正。
    • package.json中^和~有啥区别?

      • ^ 锁定主版本,更新到最新的次版本+修订版
      • ~锁定主版本和次版本,更新到修订版

  • npm update 包名

    • 更新指定依赖包

  • npm config set registry http://registry.npm.taobao.org/

    • 不通过下载nrm,手动修改npm的下载地址



4.nrm



4.1.什么是nrm
  • nrm是国内的服务器,是国外npm的镜像源地址管理工具

  • npm install --global nrm

    (简写:

    npm i -g nrm

    • 使用npm下载一个全局的第三方依赖nrm
    • 安装完毕以后,在电脑上的任何一个地方就可以使用了
  • 检测nrm版本号

    nrm --version

    (简写

    nrm -v



4.2.nrm使用

  • nrm test

    • 检测所有可用的镜像源地址的网络延迟
    • 需要比较长的时间,因为要检测每一个镜像源地址
    • 需要等到最慢的哪个网络延迟测试出来以后才一起返回
    • 镜像源地址名称 —- 延迟

      • npm —- 3706ms 原始npm地址
      • yarn —- 710ms facebook家的地址
      • cnpm —- 220ms 自己国家的镜像地址
      • taobao —- 445ms taobao家的镜像地址
    • *代表你当前正在使用的

  • nrm use 镜像源地址名称

    • 切换你想要的镜像源地址 找延迟小一点的



5.gulp



5.1.什么是gulp
  • 前端自动化打包工具

  • 运行需要依赖node环境

    • 自动化打包,不需要手动做事,但是需要你手动编辑好一个步骤
    • 打包:就是把零散的东西给你结合在一起,对代码进行压缩/混淆/合并
    • 工具:就是帮我们完成这个事情的东西


  • 5.2.安装gulp

    • npm install --global gulp

      (简写:

      npm i -g gulp

      • 安装gulp指令

    • npm uninstall --global gulp

      (简写:

      npm un -g gulp

      • 卸载gulp指令

    • npm cache clear -f

      • 清除缓存


  • gulp配置打包
    • 需要手动写一个配置文件,告诉gulp按照我们的这个配置文件来打包

    • 每一个项目一个配置文件,每个项目打包的时候使用的都是当前的项目文件

    • gulp使用之前

        1. 先准备一个项目文件夹——————–我的整个项目文件夹

          -src/ ————————-我的所有原始代码

          ​ +pages/ ———————-放我所有的html文件

          ​ +css/ ———————–放我所有的css文件

          ​ +js/ ———————–放我所有的js文件

          ​ +images/ ———————–放我所有的图片

          ​ +lib/ ————————-放我所有的第三方 文件 (比如jquery swiper)

          -package.json ————————-用来记录我项目信息的描述的文件

        2. 使用

          npm init

          初始化一下项目

          ​ +因为我们的项目一定会用到很多第三方工具

          ​ +我就用npm下载第三方工具

          ​ +最好就是使用

          npm init

          给我生成一个package.json文件来记录一下我用了哪些包

          ​ +顺便也记录一下自己的项目

        ​ 3.自己手在项目的根目录创建一个叫

        gulpfile.js

        的文件

        ​ +名字必须是

        gulpfile.js

        ​ +这个文件里就用来书写我们项目的打包规则(也就是这个项目打包的配置文件 )

        ​ +使用gulp的时候会默认读取

        gulpfile.js

        的打包配置文件



    • gulpfile.js

      的打包配置文件规则

      • 借助一些gulp的API方法来帮助我们打包,所以先在项目文件夹里安装一个gulp,作为开发依赖
      • 项目里安装的gulp和node 全局安装的gulp区别

        • 项目里面安装的gulp(

          npm install gulp

          简写

          npm i gulp

          1. 一个第三方依赖包
          2. 也是一个node的第三方模块
          3. 也是也别人写好的一堆方法,放在了里面
          4. 用来给我提供一些API使用的
        • 全局安装的gulp(

          npm install --golbal gulp

          简写

          npm i -g gulp

          1. 是为我们的电脑增加一个可以使用gulp的能力
          2. 也就是可以再命令行

            gulp xx

            的指令,一台电脑安装一次,可以以后一直使用


      • gulpfile.js

        文件
      //1.导入gulp这个第三方模块的时候,会优先去内置模块寻找,如果内置模块里没有,那么就会自动去node-modules的文件里面查找,导入这个gulp以后,就可以使用gulp.xxx()的各种方法了
      const gulp =require('gulp')
      //2.导入gulp-cssmin这个第三方模块
      const cssmin = require('gulp-cssmin')
      //3.先写一个打包css的方法
      const cssHandler=()=>{
          //找到src目录下对的css目录下的所有后缀为.css的文件
          return gulp.src('./src/css/*.css')
          			//压缩css代码
          			.pipe(cssmin())
          			//压缩完毕的css代码放在dist文件夹里
          			.pipe(gulp.dest('./dist/css')) 
      }
      //4.最后导出我准备好的这个方法
      module.exports.css=cssHandler
      

    • gulp里面的一些方法

      • src()

        1. 用来找到你要打包的文件的
        2. src(‘你要打包的文件的地址’)
        3. 返回值是一个二进制流,就可以继续去调用别的方法
      • pipe()

        1. 用来帮你做事情的
        2. pipe(‘你要做的事情’)
        3. 返回值:又是一个二进制流,又可以接着调用别的方法
      • dest()

        1. 用来写入文件的
        2. dest(‘你要放的文件夹’)
        3. 你要把你已经压缩好的代码放在哪一个文件夹里
        4. 如果没有指定文件夹,会自动创建一个文件夹 放进去
    • parallel()

      1. 用来并行多个任务的
      2. gulp.parallel(你定义的任务1,你定义的任务2,…)
      3. 他会把几个任务都给你执行了
      4. 只要这个返回值一执行,就能把你准备好的几个任务同时开始执行
      • series()

        1. 用来逐个执行多个任务的
        2. gulp.series(你定义的任务1,你定义的任务2,…)
      1. 只要这个返回值一执行,就能把你准备好的几个任务逐个开始执行
      • watch()
      1. 监控src文件夹下的文件,只要已修改就执行对应的任务
      2. gulp.watchr(你要监控的文件目录,你要执行的任务)

    • 执行各种压缩代码的方法,都是第三方依赖包

      • 一个小问题

        1. 当我在项目文件夹里安装gulp以后,package.json文件就会记录我下载了gulp包
      1. 当我在项目文件夹里安装jQuery以后,也会在package.json文件记录我下载了jQuery包
      2. 但是我下载gulp仅仅是为了打包项目使用,打包完成后就不用了了;jQuery是我在项目里一直使用的第三方,
      3. 既然有区别,那就记录的时候分开记录,现在都是记录在dependencies里面
      4. 我们安装一些上线不需要的包的时候,就使用另外一套指令

      • npm install --save-dev 包名

        的指令(简写:

        npm i -D 包名



        1. npm install 包名

          的下载没有任何区别
      1. 唯一的区别就是在package.json里面的记录位置不一样了,现在记录在devdependencies里面

    • gulp-cssmin

      专门用来压缩css文件的,你需要下载导入

      1. 下载指令

        npm install --save-dev gulp-cssmin

        (简写:

        npm i -D gulp-cssmin

      2. 导入第三方模块:

        const cssmin = require('gulp-cssmin')
      3. 导出这个方法:

        module.exports.css=cssHandler
      4. cmd命令行 执行 gulp css,就会执行压缩

      • gulp-autoprefixer

        第三方模块是专门用来加前缀,解决浏览器兼容问题

        1. 下载指令

          npm install --save-dev gulp-autoprefixer

          (简写:

          npm i -D gulp-autoprefixer

        2. 导入第三方模块:

          const autoprefixer = require('gulp-autoprefixer')

        3. //1.导入gulp这个第三方模块的时候,会优先去内置模块寻找,如果内置模块里没有,那么就会自动去node-modules的文件里面查找,导入这个gulp以后,就可以使用gulp.xxx()的各种方法了
          const gulp =require('gulp')
          //2.导入gulp-cssmin这个第三方模块
          const cssmin = require('gulp-cssmin')
          //3.导入gulp-autoprefixer`这个第三方模块
           const  autoprefixer = require('gulp-autoprefixer')
          //4.先写一个打包css的方法
          const cssHandler=()=>{
              //找到src目录下对的css目录下的所有后缀为.css的文件
              return gulp.src('./src/css/*.css')
              			//给css代码加前缀
              			.pipe(autoprefixer({
          				browsers:['last 2 versions']
              			}))
              			//压缩css代码
              			.pipe(cssmin())
              			//压缩完毕的css代码放在dist文件夹里
              			.pipe(gulp.dest('./dist/css')) 
          }
          //5.最后导出我准备好的这个方法
          module.exports.css=cssHandler
          

      • gulp-uglify

        第三方模块是专门用来压缩js的

        1. 下载指令

          npm install --save-dev gulp-uglify

          (简写:

          npm i -D gulp-uglify

        2. 导入第三方模块:

          const uglify = require('gulp-uglify')
        3. 导出这个方法:

          module.exports.js=jsHandler
        4. 这个安装包不认识es6的语法,所以要用

          gulp-bable

          先把es6语法转换成es5语法

      • gulp-bable

        这个第三方模块是专门用来把es6语法转换成es5的语法

        1. 这个第三方包还依赖了另外两个第三方包

          @babel/core

          和@

          babel/preset-env

        2. 下载的时候需要下载三个包,导入的时候只要导入一个gulp-babel就可以了

        3. 下载指令

          npm install --save-dev gulp-bable @babel/core babel/preset-env

        4. 导入第三方模块:

          const bable = require('gulp-bable')

        5. //1.导入gulp这个第三方模块的时候,会优先去内置模块寻找,如果内置模块里没有,那么就会自动去node-modules的文件里面查找,导入这个gulp以后,就可以使用gulp.xxx()的各种方法了
          const gulp =require('gulp')
          //3.导入gulp-uglify这个第三方模块
          const  uglify = require('gulp-uglify')
          //4.先写一个打包js的方法
          const jsHandler=()=>{
              //找到src目录下对的js目录下的所有后缀为.js的文件
              return gulp.src('./src/js/*.js')
              			//es6转es5
              			.pipe(babel({
                  		prests:['@bable/env']
              			}))
              			.pipe(uglify())
              			//压缩完毕的js代码放在dist文件夹里
              			.pipe(gulp.dest('./dist/js')) 
          }
          //5.最后导出我准备好的这个方法
          module.exports.js=jsHandler
          
        6. cmd命令行 执行 gulp js,就会执行压缩


      • gulp-htmlmin

        专门用来压缩html文件的,你需要下载导入

        1. 下载指令

          npm install --save-dev gulp-htmlmin

          (简写:

          npm i -D gulp-htmlmin

        2. 导入第三方模块:

          const htmlmin = require('gulp-htmlmin')

        3. 导出这个方法:

          module.exports.html=htmlHandler

        4. cmd命令行 执行 gulp html,就会执行压缩

        5. //1.导入gulp这个第三方模块的时候,会优先去内置模块寻找,如果内置模块里没有,那么就会自动去node-modules的文件里面查找,导入这个gulp以后,就可以使用gulp.xxx()的各种方法了
          const gulp =require('gulp')
          //3.导入gulp-uglify这个第三方模块
          const  htmlmin = require('gulp-htmlmin')
          //4.先写一个打包js的方法
          const htmlHandler=()=>{
              //找到src目录下对的pages目录下的所有后缀为.html的文件
              return gulp.src('./src/html/*.html')
              			.pipe(htmlmin({
                  		removeAttributeQuotes:ture,//移除属性上的双引号
                  		removeComments:ture,//移除注释
                  		collapseBooleanAttributes:ture,//把值为布尔的属性简写
                  		collapseWhitespace:ture,//移除所有空格
                  		minifyCSS:true,//style里的css样式给去空格
                  		minifyJS:true,//script里的JS样式给去空格
              			}))
              			//压缩完毕的js代码放在dist文件夹里
              			.pipe(gulp.dest('./dist/js')) 
          }
          //5.最后导出我准备好的这个方法
          module.exports.html=htmlHandler
          
      • 书写一个移动img文件的方法

        1. 图片我们尽量不压缩,设计师给图片的时候是已经压缩好的

        2. 我们再压缩的话,图片就会在失帧的基础上压缩

        3. const imgHandler=()=>{
              //找到src目录下对的images目录下的所有后缀为**的文件
              return gulp.src('./src/images/**')
              			.pipe(gulp.dest('./dist/images')) 
          }
          //5.最后导出我准备好的这个方法
          module.exports.img=imgHandler
          
      • 书写一个移动lib文件夹的方法

        1. 第三方插件/框架放在lib文件夹下,不需要压缩 只需要移动就好了

        2. const libHandler=()=>{
              //找到src目录下对的lib目录下的所有后缀为**的文件
              return gulp.src('./src/lib/**')
              			.pipe(gulp.dest('./dist/lib')) 
          }
          //5.最后导出我准备好的这个方法
          module.exports.lib=libHandler
          
      • ​ 导出一个默认任务

        1. 当你在执行gulp default的时候,可以不写default
        2. 你在执行gulp这个指令,就是在执行default
        //第一种:导出默认任务,这个parallel是同时执行
        module.exports.default = gulp.parallel(cssHandler,jsHandler,htmlHandler,imgHandler,libHandler )
        //第二种:导出默认任务,这个series是逐个执行,在这里是先执行删除delHandler,再同时执行parallel()
        module.exports.default = gulp.series(
        	delHandler,
            gulp.parallel(cssHandler,jsHandler,htmlHandler,imgHandler,libHandler ),
            serverHandler,
            watchHandler
        )
        
        
      • 再书写一个任务自动删除dist文件夹里的东西

        1. 下载指令

          npm install --save-dev del

          (简写:

          npm i -D del

        2. const delHandler=()=>{
              //这个函数的目的是为了删除dist目录里的东西
              return del(['./dist'])
          }
          //5.最后导出我准备好的这个方法
          module.exports.del=delHandler
          
      • 在书写一个配置服务器的任务

        1. 下载指令

          npm install --save-dev gulp-webserver

          (简写:

          npm i -D gulp-webserver

        2. 这个是专门用来配置node服务器的

        3. 导入第三方模块:

          const webserver = require('gulp-webserver')

        4. 配置代理—webserver可以配置代理

          1. 直接在webserver的时候 添加一个配置项
        5. const  webserver = require('gulp-webserver')
          const serverHandler=()=>{
          	//要把页面在服务器上打开
              //打开的是dist目录里面我已经压缩好的页面
              //找到我要打开的页面的文件夹,把这个文件夹当做网站根目录
              return gulp.src('./dist')
              			.pipe(webserver({
                  		//需要一些配置项
                  		host:'localhost',//域名
                  		port:8080,//端口号
                  		open:'./pages/index.html',//默认打开的页面
                  		livereload:true,//-热重启-当dist里面的东西改变就自动刷新浏览器
                  		//所有的代理配置都是在proxies里面
                  		proxies:[
                  			{
                  			source:'/gx'//源 代理标识符
                  			target:'http//127.0.0.1/test.php'//目标地址
          					}
                          ]
             	 			}))
          }
          //5.最后导出我准备好的这个方法
          module.exports.server=serveHandler
          
        6. 自定义域名

          1. 如果你想要自定义域名,前提:建议别使用已经存在的域名
          2. 修改一下你电脑里的hosts文件

            1. window-我的电脑–C–windows –system32–drivers –etc–hosts
            2. 在最后添加 127.0.0.1 你自己定义的域名
      • 书写一个自动监控文件的任务

        const watchHandler=()=>{
            //这个函数的目的是为了监控src里的东西
            gulp.watch('./src/css/*.css',cssHandler)
            gulp.watch('./src/js/*.js',jsHandler)
            gulp.watch('./src/pages/*.html',htmlsHandler)
            gulp.watch('./src/images/**',imgHandler)
            gulp.watch('./src/lib/**',libHandler)
            
        }
        //5.最后导出我准备好的这个方法
        module.exports.watch=watchHandler
        
  • nodejs端口被占用的原因及处理问题

    • 首先打开cmd命令窗口,输入

      netstat -ano|findstr 8080
      
    • 此时可以获取8080端口对应的tcp信息,如下,TCP号是15528

    • 在cmd 输入 taskkill /f /t /im 15528 号,来关掉被占用的端口;此时可正常使用访问 8080 端口

      taskkill /f /t /im 15528 
      



6.再次学习node js



6.1.实时监听node环境下http服务的工具
下载指令 : $ npm install nodemon -g(简写 npm i nodemon -g)
  • nodemon 只在运行服务的代码时去使用。


6.2.http模块处理请求
  1. 获取get请求的参数
  • get请求的参数是在地址栏上
const http = require("http")
const server = http.creatServer((req,res)=>{
    let str = req.url.substring(2,req.url.length)
    let arr = str.split("&")
    let query = {}
    arr.forEach(item=>{
        let tmp = item.split("=")
        query[tmp[0]]=tmp[1]
    })
    console.log(query)
    res.setHeader('Content-type':'text/html';'charset=utf-8')
    res.write(`hello,${query.name}你好,你的年龄是${query.age}`)
    res.end()
})

​ 2.获取post的参数

  • post请求的参数是不在地址栏上,不能用req.url来获得

    //监听req的data事件(请求传输事件)
    	-data这个事件的回调函数是当请求发送时候触发,并且可能会触发多次,原因是当请求体很大的时候
    	-chuank 是每次触发这个事情时传递的一部分请求内容
        -如何才能把完整的请求体内容全部的到? 拼接chunk
    let raw =""
    req.on('data',(chunk)=>{
        raw+=chunk
        
        res.write('hello')
        res.end()
    })
    req.on('end'()=>{
    	console.log(raw)   
        let arr = raw.split("&")
        let result = {}
        arr.forEach(item=>{
            let tmp = item.split("=")
            result[tmp[0]]=tmp[1]
        })
        console.log(result)
        res.write(`hello,${query.name}你好,你的年龄是${query.age}`)
        res.end()
    })
    //监听req的end事件()
    	-这个end事件时当整个请求体传输完成时候触发的
    
    


6.3.模块化
  1. 不使用模块化的坏处

    1. 变量污染
    2. 代码复用性不高
    3. 代码可维护性不高
    4. 以来关系管理不方便
  2. 什么是模块化?

    1. 一个模块就是一个实现特定功能的文件,有了模块我们就可以更方便的使用别人的代码,要用什么功能就加载什么模块。
  3. 模块化带来的好处

    1. 避免变量污染
    2. 提供代码的复用率
    3. 提高代码的可维护性
    4. 依赖关系清晰
  4. 规范与实现

    1. NodeJs – CommonJs规范
    2. RequireJS – AMD规范
    3. SeaJS – CMD规范
  5. CommonJs规范

    • 每个文件就一个模块,有自己的作用域。在一个文件里面定义的变量、函数、类,都是私有的,对其它文件不可见。

    • CommonJS规范规定,每个模块内部,

      module

      变量代表当前模块。这个变量是一个对象,它的

      exports

      属性(即

      module.exports

      )是对外的接口。加载某个模块,其实就是加载该模块的

      module.exports

      属性。


    • require

      方法用于加载模块。

      • CommonJS模块的特点如下:所有代码都运行在模块作用域,不会污染全局作用域。
      • 模块可以多次加载,但是只会在第一次加载时运行一次,然后运行结果就被缓存了,以后再加载,就直接读取缓存结果。要想让模块再次运行,必须清除缓存。
      • 模块加载的顺序,按照其在代码中出现的顺序。
  6. module对象

    每个模块内部,都有一个

    module

    对象,代表当前模块。它有以下属性:

    • module.id 模块的识别符,通常是带有绝对路径的模块文件名。
    • module.filename 模块的文件名,带有绝对路径。
    • module.loaded 返回一个布尔值,表示模块是否已经完成加载。
    • module.parent 返回一个对象,表示调用该模块的模块。
    • module.children 返回一个数组,表示该模块要用到的其他模块。
    • module.exports 表示模块对外输出的值。
  7. module.exports


    • module.exports

      属性表示当前模块对外输出的接口,其他文件加载该模块,实际上就是读取

      module.exports
  8. exports

    • 每个模块还提供有一个

      exports

      变量,指向

      module.exports

      。这等于在每个模块头部,有一行隐藏的如下代码:

      var exports = module.exports;
      
    • 造成的结果是,在对外暴露模块接口时,可以直接向

      exports

      添加属性和方法。

      var name = '张三';
      exports.name = name;
      exports.sayHi = () => {
        console.log(`Hello, My Name is ${name}`);
      }
      
    • 注意,不能直接将exports变量指向一个值,因为这样等于切断了

      exports



      module.exports

      的联系。

      // a.js 切断了与module.exports的联系
      exports = function(x) {console.log(x)};
      // b.js hello方法没有被暴露,因为module.exports重新赋值了
      exports.hello = function() {
        return 'hello';
      };
      module.exports = 'Hello world';
      
    • 如果你觉得,

      exports



      module.exports

      之间的区别很难分清,一个简单的处理方法,就是放弃使用

      exports

      ,只使用

      module.exports



6.4require 命令
  • 如果指定的模块文件没有发现,Node会尝试为文件名添加**.js、.json、.node**后,再去搜索。.js件会以文本格式的JavaScript脚本文件解析,.json文件会以JSON格式的文本文件解析,.node文件会以编译后的二进制文件解析。

  • require

    发现参数字符串指向一个目录以后,会自动查看该目录的

    package.json

    文件,然后加载

    main

    字段指定的入口文件。如果

    package.json

    文件没有

    main

    字段,或者根本就没有

    package.json

    文件,则会加载

    该目录下的index.js 文件 或者 index.json 文件 或者 index.node 文件



6.5一些内置模块
  1. url模块(快过时了)


    • url.parse(urlString,[,parseQueryString])

      • 主要是对url地址做解析
      • 参数 加ture 的时候可以的到参数的对象

    • url.format()

      • 把解析后的url对象解析成url字符串
  2. new URL

    • 实例化一个URL对象,返回的是一个新标准的url对象
    • new URL(url)

      • 主要是对url地址做解析

    • new URL(url).searchParams.get('age'))

      • 获取url的参数的age的值

    • new URL(url).toString())

      • 把解析后的url对象解析成url字符串
  3. querystring 查询字符串模块

    • 对于一个查询字符串,解析成查询对象


    • querystring.parse(str,[,sep[,eq]])

      • sep规定了键值对之间的分隔符是什么默认是&
      • eq规定了键值之间的分隔符是什么,默认是=
      const querystring = require('querystring')
      const str = 'key1=value1&key2=value2'
      querystring.parse(str)
      

    • querystring.stringify(str,[,sep[,eq]])

      • sep规定了键值对之间的分隔符是什么默认是&
      • eq规定了键值之间的分隔符是什么,默认是=
      const querystring = require('querystring')
      const obj = {key1:'value1',key2:'value2'}
      const str = querystring.stringify(obj,"@","-")
      console.log(str)
      
  4. path模块

    • 专门用来处理路径有关的方法,


    • path.resolve('./day01-homework','./utils/index.js')

      • 结合成一个绝对路径返回
      const path = require('path')
      const filePath=path.resolve('./day01-homework','./utils/index.js')
      console.log(filePath)
      

    • path.join('./day01-homework','./utils/index.js')

      • 仅仅是把路径拼接起来

        const path = require('path')
        const filePath=path.join('./day01-homework','./utils/index.js')
        console.log(filePath)
        

    • path.join()



      path.resolve()

      有什么区别?

      • 返回值不同,

        path.resolve

        总是返回一个绝对路径,而

        path.join

        只是简单的将路径拼接。
      • 对于以

        /

        开始的路径片段,

        path.join

        只是简单的将该路径片段进行拼接,而

        path.resolve

        将以

        /

        开始的路径片段作为根目录,在此之前的路径将会被丢弃

  5. __dirname



    __filename


    • __dirname:

      当前模块的目录名的绝对路径

    • __filename:

      当前模块的文件名



7.node–小爬虫

  • 网络爬虫(又称为网页蜘蛛,网络机器人,在FOAF社区中间,更经常的称为网页追逐者),是一种按照一定的规则,自动地抓取万维网信息的程序或者脚本。另外一些不常使用的名字还有蚂蚁、自动索引、模拟程序或者蠕虫。

  • 基于 https 模块实现爬取拉勾网职位分类信息


  • cheerio

    第三方模块

    1. 安装模块,简单理解为是使用在服务器端的 jquery。保留了 jquery 选择器的相关功能,去掉了 DOM 操作功能。

      $ npm install cheerio
      
    2. 引入

      const cheerio = require('cheerio')
      
    3. 装载

      const $ = cheerio.load('<h2 class="title">Hello world</h2>')
      
    4. 使用相应的API

      console.log($("h2"))
      $("h2.")addClass("hello")
      console.log($.html)
      
  • 小爬虫代码

var https = require('https');

var cheerio = require('cheerio');

var url = 'https://www.lagou.com/';


https.get(url, function(res) {

  var html = '';

  res.on('data', function(chunk) {

    html += chunk;

  });


  res.on('end', function() {

    findMenu(html);

  })

})


function findMenu(htmlStr) {

  var $ = cheerio.load(htmlStr);

  var $menuMain = $('.menu_main');

  var result = [];


  $menuMain.each(function(i, item) {

    var obj = {};

    var h2Text = $(item).find('h2').text();

    h2Text = h2Text.trim();

    obj.name = h2Text;

    obj.subName = [];

    var $as = $(item).find('a');

    $as.each(function(i, item) {

      var aText = $(item).text().trim();

      obj.subName.push(aText);

    })


    result.push(obj);

  })


  console.log(result);

}



8.express框架

  1. 前言

    • 基于 Node.js 平台,快速、开放、极简的 Web 开发框架 。
  2. 框架的作用

    • 框架可以帮助省略掉一些基本的相同底层代码的反复书写,只需调用框架的方法就可以实现你想要的功能。
  3. node 相关框架

    1. express
    2. koa
    3. egg
    4. thinkjs
    5. adonisjs
    6. nestjs
  4. 安装指令,express是在项目文件夹下安装

    $ npm install express
    
  5. 路由


    • 路由

      是指确定应用程序如何响应客户端(浏览器)对特定端点的请求,该特定端点是URL(或路径)和特定的HTTP请求方式(GET、POST等)。
    • 每个路由可以具有一个或多个处理程序函数,这些函数在路由匹配时执行。



sass



1.世界上最成熟、最稳定、最强大的专业级CSS扩展语言!


  • sass

    是一个

    css

    的预编译工具
  • 也就是能够

    更优雅

    的书写

    css

    • 可以定义变量
    • 可以定义函数
    • 可以有if语句,可以有for循环语句

  • sass

    写出来的东西

    浏览器不认识

    ,cass可以写 css代码。
  • 依旧是要转换成

    css

    在浏览器中运行
  • 这个时候就需要一个工具来帮我们做



2.和css区别

  • css文件后缀是.css
  • sass文件后缀是.sass或者.scss



3.sass和scss文件区别

  • 在.scss文件里面和写css语法基本一致

  • h1 {
        width: 100px;
        height: 200px;
    }
    
  • 在.sass文件里面没有大括号和分号,全部依靠缩进

  • h1
    	width: 100px
    	height: 200px
    
  • 这两个文件被编译成css文件是一样的



4.

sass

安装卸载

  • # 安装全局 sass 环境
    $ npm i -g  sass
    #卸载
    $ npm un -g sass
    
    



5.sass 编译

  • sass单文件编译

    • 你先写好.scss或者.sass后缀的文件
    • 输入指令

      sass 要编译的文件名 编译后的文件名
    • 每次需要改sass都要重新编译一下
  • sass单文件实时编译

    • 你先写好.scss或者.sass后缀的文件
    • 输入指令

      sass --watch 要编译的文件:编译后的文件名
    • 如果sass有修改,sass实时编译



6.sass常用语法



6.1.sass变量
$width = 400px;
$height = 200px;
h1{
	width:$width;
	height:$height
	background-color:#ccc;
}


6.2.sass注释
  • /* */sass和css都认识的注释
  • // 只有sass认识的注释,不会被编译到css文件中。


6.3.嵌套语法
  • 在Sass中,你可以像俄罗斯套娃那样在规则块中嵌套规则块。Sass允许将一套 CSS 样式嵌套进另一套样式中,内层的样式将它外层的选择器作为父选择器。
#box{
    width:100px;
    height:100px;
    h1{
        text-align:center;
    }
    span{
        font-size:16px;
        a{
            color:blue
        }
    }
}
//编译后
#box {
    width: 100px;
    height: 100px;
}
#box h1 {
    text-align: center;
}
#box span {
    font-size: 16px;
}
#box span a {
    color: blue;
}


6.4.父选择器标识符&
  • 指向父选择器,


6.5.@import
  • 在css里

    • 在CSS里面 link是页面结构和样式同时加载,@import会等页面结构加载完成后,再加载css样式。
  • 在sass里

    • sass的@import规则在生成css文件时就把相关文件导入进来。@import “sidebar”;这条命令将把sidebar.scss文件中所有样式添加到当前样式表中。


6.6.混合器(宏)@mixin
  • 可以通过混合器让大段样式重用,@include 引入使用

    @mixin no-bullets {
    	width:200px;
    	height:200px;
    	border:1px solid #ccc
    }
    #box1 {
    	@include no-bullets;
    	background-color:#fff;
    }
    #box2 {
    	@include no-bullets;
    	background-color:#000;
    }
    #box3 {
    	@include no-bullets;
    	background-color:#bbb;
    }
    
  • 可以传参的混合器 @mixin name (){}

    @mixin no-bullets ($width,$height) {
    	width:$width;
    	height:$height;
    	border:1px solid #ccc
    }
    #box1 {
    	@include no-bullets(200,400);
    }
    #box2 {
    	@include no-bullets(300,600);
    }
    #box3 {
    	@include no-bullets(300,800);
    }
    


6.7.继承 @extend+选择器
#box{
    width:100px;
    height:100px;
    h1{
        text-align:center;
    }
    span{
        font-size:16px;
        a{
            color:blue
        }
    }
}
#box2{
	@extend #box;
}


6.8.颜色函数



  • c

    o

    l

    o

    r

    color要改变的颜色,






    c


    o


    l


    o


    r


























    amount取值范围是0~100%

    lighten($color, $amount) //颜色变浅函数;
    darken($color, $amount) //颜色变深函数;
    


6.9. sass逻辑结构

  • @if

    当 @if 的表达式返回值不是 false 或者 null 时,条件成立,输出 {} 内的代码:

    p {
        @if 1 + 1 == 2 { border: 1px solid; }
        @if 5 < 3 { border: 2px dotted; }
        @if null { border: 3px double; }
    }
    // 编译为
    p {
        border: 1px solid;
    }
    

  • @for

    @for 指令可以在限制的范围内重复输出格式,每次按要求(变量的值)对输出结果做出变动。

    //第一种写法
    @for $i from 1 through 3 {//循环三次
        
        .item-#{$i} { width: 2em * $i; }
    }
    //相当于
    .item-1{width:2em}
    .item-2{width:4em}
    .item-3{width:6em}
    
    //第二种写法
    @for $i from 1 to 3 {//循环三次
        
        .item-#{$i} { width: 2em * $i; }
    }
    //相当于
    .item-1{width:2em}
    .item-2{width:4em}
    .item-3{width:6em}
    

  • function

    Sass支持自定义函数,并能在任何属性值或Sass script中使用

    $grid-width: 40px;
    $gutter-width: 10px;
    @function grid-width($n) {
        @return $n * $grid-width + ($n - 1) * $gutter-width;
    }
    #sidebar1 { width: grid-width(5); }
    #sidebar2 { width: grid-width(4); }
    // 编译为
    #sidebar {
        width: 240px;
    }
    



7.gulp-sass安装失败解决办法

1.安装gulp-sass需要依赖,node-sass

指令 : npm install node-sass

2.node-sass 安装完成后,gulp-sass 的依赖问题也就解决了,然后跳出去 node_modules 目录继续安装 gulp

指令 : npm install gulp-sass --save-dev



版权声明:本文为weixin_43353869原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。