前端学习ybybyb

常用的语义化标签:

头部导航栏
区块(有语义化的div)
主要区域主要内容侧边栏
底部...这些标签可以在页面中使用多次Video(视频)Audio(音频)使用它们可以很方便的在页面中嵌入音频和视频,不用在去使用flash和其他浏览器插件

视频播放:

背景:Chrome浏览器中发起资源请求的有6个线程;但是只有1个线程负责渲染页面——称为UI主线程——浏览器中所有的代码只能由一个线程来执行。问题:若浏览器加载了一个很耗时的JS文件(可能影响DOM树结构),浏览器必须等待该文件执行完成才会继续执行后续的代码(HTML/CSS/JS等)——如果一个JS文件要执行10s(可能有很深的循环/递归等科学计算/解密),会发生什么?——执行耗时JS任务过程中,会暂停页面中一切内容的渲染以及事件的处理。解决方案:H5新特性——WebWorkerWorker的本质:就是一个执行指定任务的独立线程;且该线程可以与UI主线程进行消息数据传递。使用方法:HTML文件中:varw=newWorker('js/x.js')w.postMessage('发送给Worker线程的消息');w.onmessage=function(e){e.data;//来自Worker线程的消息}JS文件中:onmessage=function(e){vardata=e.data;//接收UI线程的消息//执行耗时任务....postMessage(result);//给UI线程发送消息}注意:Worker任务不允许直接操作DOM树,也不允许使用任何的BOM对象!需要的数据只能由UI主线程来传递,处理的结果也必须交由UI线程来显示。

方法1:F12F1设置禁用JS

方法2:F12元素事件帧监听删除复制事件

方法3:找到HTML中存放内容的段落,找到父级,添加一个id或者class,然后在控制台打印console.log(document.getElementById('自建ID').innerText)

优先级:!important>行内样式>内链样式>外部引入(!important可直接添加在css样式中)后代选择器>子类选择器;为同种选择器时,哪个的描述多哪个优先级高。id相当于身份证号;class相当于小名。

.main{height:calc(100%-121px);}注意减号两边需要有空格!!!

break语句“跳出”循环。直接跳出不再执行后边的循环continue语句“跳过”循环中的一个迭代。后边的循环继续执行

方法对数组的每个元素执行一次给定的函数。

只传入一个函数作为参数

letarr=['a','b','c','d']arr.forEach(myfun);functionmyfun(item,index){console.log(item,index)}//'a'0//'b'1//'c'2//'d'3

varobj={name:'lishuo',age:22}console.log(Object.entries(obj))//['name','lishuo']//['age',22]//返回为数组varobj={name:'lishuo',age:22}for(const[key,value]ofObject.entries(obj)){console.log(`${key}:${value}`);}//name:lishuo//age:22//返回为字符串

varconstantize=(obj)=>{Object.freeze(obj);//冻结对象Object.keys(obj).forEach((key,i)=>{//冻结对象内的属性if(typeofobj[key]==='object'){constantize(obj[key]);}});};

在开发过程中,部分代码会被重复使用,函数可把代码封装起来重复使用函数语法:function函数名(形参){代码段}调用:函数名(实参)如果实参个数多于形参,形参将按照顺序依次接收实参,剩余的值不被接收如果实参个数少于形参,形参将按照顺序依次接收实参,多于的形参接收不到实参,默认值为undefined//函数中的return语句的两个作用:1.函数中通过return关键字指定返回值2.结束当前函数,不在继续向下执行代码//注意:return后的语句不再执行3.如果没有指定返回值,则函数默认返回值为undefinedarguments对象//函数中的arguments对象:(它的行为就像数组)当不确定有多少个参数传递的时候,可以用arguments来获取,在js中,arguments实际上它是当前函数的一个内置对象,所有的函数都有一个内置的arguments对象,arguments对象中储存了传递的所有实参//(当实参是否大于形参,实参都会储存在arguments中)//arguments对象特点:1.arguments的展示形式是一个伪数组,具有数组的特点,但是不可以使用数组的方法,因此可以进行遍历2.伪数组的特点(数组的特点)具有length属性按照索引方式存储数据不具有数组的push,pop等方法

计时器为window对象下的

vara=1varfn=nullvarfn=setInterval(function(){//执行方法console.log(10)a++if(a==10){clearInterval(fn)}},1000)//间隔1s//计时器中重复操作不能调用函数,写函数变量名(变量内存中储存着函数操作)//计时器创建前先初始化计时器例:left.onclick=zd//不能写=函数名()函数变量名内就存储着函数内容varx=0functionzd(){x++if(x==img_.length){x=0}img.src=img_[x]//console.log(x)}setInterval(zd,1000)//计时器重复操作写函数变量名

它可以用来调用所有者对象作为参数的方法。

通过call(),您能够使用属于另一个对象的方法

call(obj,参数列表)call方法传入两个参数,第一个为对象(必写)。若没有对象传入,写法为call(null,参数列表)

varperson={fullName:function(){returnthis.firstName+""+this.lastName;}}varperson1={firstName:"Bill",lastName:"Gates"}varperson2={firstName:"Steve",lastName:"Jobs"}varx=person.fullName.call(person2);//调用fullName,传入的参数为person2console.log(x);//SteveJobs

apply()方法与call()方法非常相似

同样必须传入两个参数apply(obj,参数数组)若只传数组,则写法为:apply(null,array)

不同之处是:call()方法分别接受参数。apply()方法接受数组形式的参数。如果要使用数组而不是参数列表,则apply()方法非常方便

varperson={fullName:function(){returnthis.firstName+""+this.lastName;}}varperson1={firstName:"Bill",lastName:"Gates"}varx=person.fullName.apply(person1);console.log(x);//BillGates//apply()方法接受数组中的参数varperson={fullName:function(city,country){returnthis.firstName+""+this.lastName+","+city+","+country;}}varperson1={firstName:"Bill",lastName:"Gates"}varx=person.fullName.apply(person1,["Seatle","USA"]);//apply()用数组传递参数console.log(x);//BillGates,Seatle,USA//call()方法不用数组传递参数varperson={fullName:function(city,country){returnthis.firstName+""+this.lastName+","+city+","+country;}}varperson1={firstName:"Bill",lastName:"Gates"}varperson2={firstName:"Steve",lastName:"Jobs"}varx=person.fullName.call(person1,"Seatle","USA");//call()不用数组传递参数console.log(x);//BillGates,Seatle,USA

如何获取我们的节点

//.cheildren获取子元素集合只能识别元素

//找节点也可以通过父节点里面的标签方法、.children方法、.parentNode方法(.document只用写一次)

一般的,节点至少拥有nodeType(节点类型),nodeName(节点明称),和nodeValue(节点值)这三个基本属性

元素节点nodeType为1

属性节点nodeType为2

文本节点nodeType为3,文字,空格,换行等

获取子节点:节点.childNodes(标准)一般不使用(兼容性问题)

返回指定节点的子节点的集合,该节点位及时更新的集合(包括注释,文本,元素都会返回)

返回节点下所有子元素节点,其他不返回(只返回元素)

动态添加节点:

父级节点.appendChild('子节点')添加在父节点列表末尾

vara=document.createElement('div')a.innerHTML='haizi5'a.className='ppp'//添加属性还是用JS原本添加属性的方法father.appendChild(a)

父节点.insertBefore(子节点)添加在父节点列表任意位置(括号内添加两个参数)(添加节点名,添加在哪个子元素节点前)

varfather=document.getElementsByClassName('father')[0]//获取父元素vara=document.createElement('div')//动态创建子元素a.innerHTML='haizi5'father.insertBefore(a,father.children[2])//将子元素插入在父元素中,插入位置为第3个子元素前

给页面动态添加一个元素话需要3步奏

1.创建一个节点

2.找到父级节点

3.将元素插入父级节点

删除节点:

node.removeChild(节点)删除选中节点

父节点名.removeChild(要删除的子节点名)

//获取://没加Element获取的子节点都包含注释节点等.childNodes(数组)//获取子元素(所有元素,包括文本节点和注释节点).parentNode//获取父元素.chlidren(数组)//获取子元素(返回数组,只返回标签节点)(常用).firstElementChild//获取子元素第一个标签节点.firstChild//获取第一个节点(包括注释节点).lastElementChild//获取最后一个标签节点.nextElementSibling//获取当前标签节点的下一个兄弟标签节点.previousElementSibling//获取当前标签节点的上一个兄弟标签节点

input框获取其中内容不能用innerHTML和innerText只能用value

onmousecover

onmouseenter

如何设置自定义属性:

1.直接在标签中设置:例:

2.在JS中设置:例:节点名.setAttribute('属性名',属性值)//注意区分对象的添加属性和自定义属性

3.在JS中设置:节点名.dataset.属性名=属性值(这种设置方法为默认在属性名前添加data-)可能存在兼容性问题

用自定义方法设置标签自带的属性名,可以覆盖原本的属性

调用自定义属性:1.节点名.getAttribute('自定义属性名')

2.当自定义属性符合H5命名规范后,可以用节点名.dataset.自定义属性名(不用加data-)来获取例:现有自定义属性data-index='5'

调用:节点名.dataset,index

BOM就是浏览器窗口对象模型,顶点对象就是window,Bom包含了Dom

为了解决单线程的这个问题,利用多核CPU的计算能力,HTML5提出WebWorker标准,允许JavaScript脚本创建多个线程。于是,JS中出现了同步和异步

同步任务:同步任务都在主线程上执行,形成一个执行栈异步任务:js的异步任务事通过回调函数实现的。一般而言,异步任务有以下三种类型:

①普通事件:如click,resize等

②资源加载:如load,error等

③定时器:包括setInterval,setTimeout等

执行顺序:①先执行执行栈中的同步任务②异步任务(回调函数)放入任务队列中③一旦执行栈中的所有同步任务执行完毕,系统就会按次序读取任务队列中的异步任务,于是被读取的异步任务结束等待状态,进入执行栈,开始执行。④由于主线程不断的重复获得任务,执行任务,再获取任务,再执行,所以这种机制被称为“事件循环”(eventloop)。

举例:

节点.offsetParent//返回作为该元素带有定位的父级元素,如果父级元素都没有定位则返回body节点.offsetTop//返回元素相对带有定位父元素上方的偏移节点.offsetLeft//返回元素相对带有定位父元素左边框的偏移节点.offsetWidth//返回自身包括padding、边框、内容区的宽度,返回数值不带单位节点.offsetHeight//返回自身包括padding、边框、内容区的高度,返回数值不带单位

offset与style的区别offsetstyleoffset可以得到任意样式表中的样式值style只能得到行内样式表中的样式值(通过CSS写的样式获取不到)offset系列获取的数值没有单位style获取的是带有单位的字符串offsetWidth包含padding+border+widthstyle.width获得不包含padding和borderoffsetWidth等属性是只读属性,只能获取不能赋值style.width可读写所以,offset用来获取,style用来更改值

滚动条在滚动时会触发onscroll事件浏览器的高(或宽)度不足以显示整个页面时,会自动出现滚动条。当滚动条向下滚动时,页面上面被隐藏掉的高度,我们就称为页面被卷去的头部页面被卷去的头部:可以通过window.pageYOffset获得如果是被卷去的左侧window.pageXOffset例:点击按钮回到页面顶端

document.addEventListener('scroll',function(){//bt为回到顶端的按钮创建scroll事件if(window.pageYOffset>=500){//如果页面被卷去500(px)bt.style.display='block'//显示bt按钮setTimeout(function(){bt.style.opacity='1'//利用异步使得按钮有渐显效果},0);}else{bt.style.opacity='0'//如果页面没有被卷去500(px)setTimeout(function(){bt.style.display='none'//隐藏按钮},0);}})bt.onclick=function(){//给按钮创建单击事件varitem=setInterval(function(){//创建计时器每10ms滚动距离-50使得页面有逐渐上滚的效果if(window.pageYOffset>0){varY=window.pageYOffsetY-=50window.scroll(0,Y)//X轴为0Y轴实时变化}else{clearInterval(item)//当被卷去距离为0时关闭计时器}},10)}

functiongetScroll(){//解决兼容性问题return{left:window.pageXOffset||document.documentElement.scrollLeft||document.body.scrollLeft||0,top:window.pageYOffset||document.documentElement.scrollTop||document.body.scrollTop||0};}调用时getScroll()

在普通函数中this指向了widow对象

Functionxx(){console.Log(this)}xx()调用后的这里的this指向widowcall、apply和bind是Function对象自带的三个方法,这三个方法的主要作用是改变函数中的this指向

call()方法和apply()方法作用:改变函数的this指向相同点:这两个方法的作用是一样的不同点:接收参数的方式不同(根据接收参数情况使用两种方法)

call()方法第一个参数和apply()方法的一样,但是传递给函数的参数必须列举出来。

apply()方法接收两个参数,一个是函数运行的作用域(this),另一个是参数数组。

bind()方法接收的参数与call一样但是调用方式不一样

//方法使用方式:函数.call(设置指向的对象,参数1,参数2...)//call方法内第一个参数为this的指向方向,后面为函数需要传入的参数(用逗号隔开)函数.apply(设置指向的对象,[参数1,参数2...])//apply方法第一个参数为this指向的方向,后面函数需要传入的参数以数组的形式写函数.bind(设置指向的对象,参数1,参数2...)()//注意:

bind方法是ES5新增的一个方法,传参和call方法一致。与call、apply方法的区别是,call和apply方法会对目标函数进行自动执行,会返回一个新的函数。call和apply无法在事件绑定函数中使用。而bind弥补了这个缺陷,在实现改变函数this的同时又不会自动执行目标函数,因此可以完美的解决上述问题

节点.cloneNode()

//值为空或false为浅拷贝只复制节点本身,不复制节点内的子节点

//值为true为深拷贝复制节点以及节点内的所有子节点

给元素添加事件,称为注册事件或者绑定事件,注册事件有两种方式:传统方式和方法监听注册方式两种传统绑定事件方式:

1.

///标签内绑定functionindex(){console.log(1)}2.node.onclick=function(){//JS中绑定console.log(1)}传统事件绑定特点:注册事件的唯一性同一个元素同一个事件只能设置一个处理函数,最后注册的处理函数将会覆盖前边注册的处理函数

监听方法注册方式:addEventListener()特点:同一个元素同一个事件可以注册多个监听器按照注册顺序依次执行

传统方式默认只触发冒泡阶段,监听事件可以通过调整参数触发捕获阶段

//写法:节点名.addEventListener(type,listener,uesCapture)//将监听器注册到目标节点身上,对象触发指定事件时,就会执行处理函数//该方法的三个参数:1.type:事件类型;类型字符串,比如click,mouseover,//注意这里没on2.listener:事件处理函数,事件发生时我们会调用的函数3.uesCapture:可选参数,是一个布尔值。默认是false,false/true:false为冒泡/ture为捕获,参数是true,表示在捕获阶段调用事件处理程序;如果是false,表示在冒泡阶段调用事件处理程序//有兼容性问题IE9//IE9前的事件监听方法:(了解)//节点.attachEvent(EventNameWithOn,callback)//EventNameWithOn:事件类型必须加on//callback:事件处理函数,当目标被触发时执行

删除传统绑定事件:node.onclick=null

删除监听事件的方式:1.removeEventlistener节点.removeEventlistener(type,listener,useCapture)(主要)2.dataEvent节点.dataEvent(eventNameWithOn,callback)(IE9以下使用)

varbtn2=document.getElementById("btn2");/*匿名函数*/24btn2.addEventListener("click",function(){//添加事件25alert(123);26removeEventListener("click",function(){//解除监听事件27alert(123)28},false)29},false)

事件流描述的是从页面中接收事件的顺序。事件发生时会在元素节点之间按照特定的顺序传播,这个传播的过程叫做DOM事件流

DOM事件流分为三个阶段,分别为:

捕获阶段:事件从Document节点自上而下向目标节点传播的阶段;

目标阶段:真正的目标节点正在处理事件的阶段;

冒泡阶段:事件从目标节点自下而上向Document节点传播的阶段。

1.也就是你说当我们点击的时候,是从上到下进行监听的,首先接收点击事件,然后查看我们的document有没有绑定事件,没绑定的话继续向下寻找,经过了html,body,再继续向下查找直到找到我们的添加了点击事件的这个元素,这个阶段叫捕获阶段2.然后找到了点击事件绑定的具体的元素节点(比如具体的某个div)这个阶段叫目标阶段3.到达目标之后还没有结束,他会继续向上执行,也就是继续向上进行执行我们的点击事件。这个阶段叫冒泡阶段

注意:1.js代码中只能执行捕获阶段或者冒泡阶段的其中一个阶段2.onclick和attachEvent只能得到冒泡阶段

event对象代表事件的状态也就是在触发的事件的函数里面我们会接收到一个event对象,这个对象有我们需要的一些参数,比如说我们需要知道此事件作用到谁身上了,就可以通过event的属性target来获取到(IE暂且不谈)

Node.onclick=function(event){//我们把这里的形参叫做事件对象//括号内可以设置任意形参代替}在这里这个event是个形参,系统自动帮我们设置成为事件对象所以我们就不需要传递实参给它在我们创建事件的时候系统就会自动帮我们创建这个事件对象,并且呢会依次传递给事件监听器(事件处理函数)IE9以下不识别,IE9以下需要从window.event中获取

事件对象属性方法:e.target//返回触发事件对象(标准)e.srcElement//返回触发事件对象(非标准,IE6-8使用)e.type//返回事件类型比如clickmouseover不带one.cancleBubble//阻止冒泡(非标准IE6-8使用)e.returnValue//阻止默认事件例如a标签不跳转(非标准IE6-8使用)e.preventDefault()//阻止默认事件(标准)e.stopPropagation()//阻止冒泡(标准)

e.target获取的是事件的触发元素,我们的实事件中还存在this这个关键字,两者的区别是,e.target是点谁触发指向谁,this是谁调用就指向谁

兼容性问题:在标准情况下浏览器传递的参数,只需要我们定义形参event就可以获取到在ie9以下需要window.event中获取兼容性处理就是e=e||window.event

例:在选项卡中,利用事件对象的target来找到当前点击的li,因为点击li,事件会冒泡到ul上,ul有注册事件,就会触发事件监听器,仅操作了一次DOM,提高了程序的性能。

e.stopPropagation()正常浏览器可以使用

window.event.cancelBubble=falseie9以下可以使用

//兼容性处理If(e){e.stopPropagation()}else{window.event.cancelBubble=false}

不是每个子节点单独设置事件监听器,而是事件监听器设置在其父节点上,然后利用冒泡原理影响设置每个子节点。只操作了一次DOM,提高了程序的性能

例:在选项卡中,利用事件对象的target来找到当前点击的li,因为点击li,事件会冒泡到ul上,ul有注册事件,就会触发事件监听器。只操作了一次DOM,提高了程序性能。

onmousemove\onmouseenter\onmouseleave\...

oncontextmenu鼠标右键点击事件document.oncontextmenu=function(e){禁用鼠标右键returnfalse}onselectstart鼠标选中内容事件document.onselectstart=function(e){禁止选中内容returnfalse}//使用return方法有弊端,return后面的代码不会再被执行鼠标的事件对象:e.clirntX//返回鼠标相对于浏览器窗口可视区的X坐标e.clientY//返回鼠标相对于浏览器窗口可视区的Y坐标e.pageX//返回鼠标相对于文档页的X坐标,IE9+支持(常用)e.pageY//__e.screenX//返回鼠标相对于电脑屏幕的X坐标e.screenY//__

键盘事件的对象keycode

onkeyup按键松开是触发

onkeydown按键按下时触发

onkeypress按键被按下并松开是触发

但是这里必须绑定给document文档对象

键盘事件的对象:keycode

document.onkeydown=function(e){//绑定键盘事件console.log(e.keyCode)//每点击一个键,找到这个键的keyCodeif(e.keyCode==13){//如果点击enter键,打印1console.log(1)}}

window.onload=function(){//JS入口函数//在这里写JS}

functionrandomcolor(){vararr=[0,1,2,3,4,5,6,7,8,9,'A','B','C','D','E']//设置数组,在此选择元素插入arr_vararr_=[]//设置颜色数组for(vari=0;i<6;i++){//设置6位循环vara=Math.floor(Math.random()*16)//设置0-16的随机数arr_.push(arr[a])//将下标位0-16的arr元素插入arr_中}varcolor='#'+arr_.join('')//将颜色数组字符串拼接,形成随机颜色return(color)//返回随机颜色}返回一个a1到a2之间的随机数functionfn(a1,a2){varnum=Math.floor(Math.random()*(a2-a1+1)+a1)return(num)}//若需要多个,则在其中添加for循环即可

数量:

css:

.quantity-input{float:left;margin:10px10px0px0px;}.quantity-inputinput{width:40px;height:30px;margin:0px;}.ys{}.quantity-input.num{width:50px;}js:

$(".pius").click(function(){//数量+按钮varx=$(this).index(".pius")varnum=$(".num").eq(x).val();num=parseInt(num)+1;$(".num").eq(x).val(num);varoprice=$(".m-money_a").eq(x).text()*num;$(".sale-money_a").eq(x).html(oprice);})$(".minus").click(function(){//数量-按钮varx=$(this).index(".minus")varnum=$(".num").eq(x).val();num=parseInt(num)-1;if(num<1){num=1;alert("数量已经为最低")}$(".num").eq(x).val(num);varoprice=$(".m-money_a").eq(x).text()*num;$(".sale-money_a").eq(x).html(oprice);})

将下段js引入至body中

将JS引入进body中

body{margin:0;overflow:hidden;}a{position:fixed;display:inline-block;margin-left:calc(50vw-70px);font-size:20px;z-index:1;color:white;}

DelaunayWaveAnimationscript.js

html

document.querySelectorAll('.switchinput').forEach(radio=>{radio.addEventListener('change',()=>{document.body.dataset.switch=radio.value;})})css

bootstrap(响应式)animateElementvantuiAmazeui

移动端浏览器兼容性较好,不需要考虑以前JS的兼容性问题,可以放心的使用原生JS书写效果,但是移动端也有自己独特的地方。比如触屏事件touch(也称触摸事件),Android和IOS都有。touch对象代表一个触摸点。触摸点可能是一根手指,也可能是多跟手指。触屏事件可响应用户手指(或触控笔)对屏幕或者触控板操作。触摸事件touchstart:手指触摸到屏幕会触发touchmove:当手指在屏幕上移动时,会触发touchend:当手指离开屏幕时,会触发

触摸事件对象(TouchEvent)TouchEvent是一类描述手指在触摸平面(触摸屏、触摸板等)的状态变化的事件。这类事件用于描述一个或多个触点,使开发者可以检测触点的移动,触点的增加和减少,等等e.touches正在触摸屏幕的所有手指的列表e.targetTouches正在触摸当前dom元素的手指列表e.changedTouches原来有现在没有或者原来没有现在有的手指列表当我们手指离开屏幕时,就没有了touches和targetTouches列表但是会有changedTouches因为我们一半都是触摸元素,所以最经常使用的时targetTouches

前端常用的框架有Bootstrap前端三大框架Angular、react、vue他们非一个级别。Vue是框架,bootstrap是基于jQuery的组建库只是统称为框架

//bootstrap制作五列时的方法:12栅格底层原理是利用媒体查询//在css中加入此媒体查询//在使用时使用.col-zdlg-2-5类名控制即可

移动端click事件会有300ms的延时,原因是移动端屏幕默认双击会缩放(doubletaptozoom)页面1.禁用缩放。浏览器禁用默认的双击缩放行为并且去掉300ms的点击延迟

\2.使用插件。fastclick插件解决300ms延迟。

document.addEventListener('DOMContentLoaded',function(){

//等页面文档加载完成不需要等所有的资源//

FastClick.attach(document.body);

});

本地存储特性:1、数据存储在用户浏览器中2、设置、读取方便、甚至页面刷新不丢失数据3、容量较大,sessionStorage约5M、localStorage约20M4、只能存储字符串,可以将对象JSON.stringify()编码后存储

window.sessionStorage1.生命周期为关闭浏览器窗口2.在同一个页面下可以共享数据3.以键值对的形式进行存储sessionStorage.setItem('key',value)存数据//键值均为字符串sessionStorage.getItem('key')取数据sessionStorage.removeItem('key')删除单独的sessionStorage.clear()删除所有的

window.localStorage1.生命周期为永久生效,除非手动删除,否则关闭页面也会存在2.可以多页面共享(同一浏览器可以共享)3.以键值对的形式存储数据localStorage.setItem('key',value)存数据localStorage.getItem('key')取数据localStorage.removeItem('key')删除单独的localStorage.clear()删除所有的

JSON.stringify(data)//将对象编码为字符串,方可存入缓存JSON.parse()//从缓存中获取字符串对象,用此方法转换为正常对象使用//parseInt()函数解析字符串并返回整数。JQ方法sessionStorage.setItem('key',value)存数据//key为缓存中的名字,注意要用字符串清空缓存

localStorage.clear();

将对象转换为字符串:

vardata={//设置一个对象name:11,passowrd:123}vara=JSON.stringify(data)//将对象转换为字符串console.log(a)//转换为字符串后可以储存到本地缓存中varb=JSON.parse(a)//将字符串转回对象console.log(b)//从本地缓存中读取后,使用此方法变回对象

第一种:利用缓存传参(如上)第二种:利用a标签跳转传参

JQuery对象的本质:利用$对DOM对象包装后产生的对象

两个对象的相互转化:jQuery对象转换为DOM对象1$(‘span’)[0]下标的方式2$(‘span’)get(index)索引的方式

$(function(){$('.cont').click(function(){console.log(this)//this指向DOM对象而不是JQuery对象})console.log($('#cont')[0])//JQuery对象转换为DOM对象})

入口函数第一种$(function(){//...此处是页面DOM加载完成的入口})

入口函数第二种$(document).ready(function(){//...此处是页面DOM加载完成的入口})

这里的“$”可以换成jQuery等待DOM结构渲染完毕即可执行内部代码,不用等待所有外部资源加载完成,jQuery帮我们完成了封装相当于DOMContentLoaded不同于原声的load事件是等页面文档,外部的js文件,css文件,图片加载完毕才执行内部代码更推荐使用第一种方式

JQuery入口函数与JS入口函数的区别1.JavaScript的入口函数比jQuery的入口函数早一些

2.jQuery的入口函数不会覆盖原有的入口函数,而会进行添加javascript的入口函数执行的比jQuery的晚,且会进行覆盖3.jQuery执行较早的好处例如淘宝,京东这类大网站,图片等资源较多,若要等待全部加载就会导致代码执行很缓慢,因此文档树加载完成再执行代码执行会比较快些

id选择器$(‘#id’)获取指定id元素//此处全部与css选择器相同class选择器$(‘.calss’)匹配指定类名的所有元素标签选择器$(‘div’)获取标签名为div的同一类元素全选选择器$(‘*’)匹配所有元素并集选择器$(‘div,li,span’)选取多个元素交集选择器$(‘li.current’)交集元素子代选择器$(‘ul>li’)子集选择器后代选择器$(‘ulli’)后代选择器

寻找父元素parent()//返回被选元素的直接父元素parents()//返回被选元素的所有祖先元素,它一路向上直到文档的根元素()parentsUntil()//返回介于两元素之间的所有祖先元素

$(document).ready(function(){$("span").parentsUntil("div");//返回介于

元素之间的所有祖先元素});

寻找子元素children()//返回被选元素的所有直接子元素find()//返回被选元素的后代元素,一路向下直到最后一个后代

$("div").children("p");//返回所有

元素,并且它们是

的直接子元素$("div").find("span");//返回属于
后代的所有元素$("div").find("*");//返回
的所有后代

寻找同胞siblings()//返回被选元素的所有同胞元素(可选参数来过滤同胞,不包含自己)next()//返回下一个同胞元素(该方法只返回一个参数)nextAll()//返回被选元素的所有跟随的同胞元素nextUntil()//返回介于两个给定参数之间的所有跟随的同胞元素prev()prevAll()prevUntil()//以上三个方法的工作方式与上面的方法类似,只不过方向相反而已:它们返回的是前面的同胞元素

过滤first()//返回被选元素的首个元素last()//返回被选元素的最后一个元素eq()//返回被选元素中带有指定索引号的元素find()//返回

filter()//方法允许您规定一个标准。不匹配这个标准的元素会被从集合中删除,匹配的元素会被返回not()//返回不匹配标准的所有元素odd()//返回奇数项元素even()//返回偶数元素

$("divp").first().css("background-color","yellow");//返回首个div标签中p标签$("p").eq(1).css("background-color","yellow");//返回p标签的第二个(index==1)$("p").filter(".url").css("background-color","yellow");//返回p标签中类名为url的所有元素$("p").not(".url").css("background-color","yellow");//返回不带有类名"url"的所有

元素

//方法一设置单个css样式$('div').css('属性名','属性值')//方法二设置多个css样式$('div').css({//css括号内为一个对象'属性名':'属性值','属性名':'属性值',})参数只写属性名,则是返回属性值

$(this).css(''color'');

添加类$(“div”).addClass(''current'');移除类$(“div”).removeClass(''current'');切换类$(“div”).toggleClass(''current'');检查类$(“div”).hasClass(''current'');//检查是否含有类名current返回值为布尔

JQ操作类与JS操作className的区别原生JS中className会覆盖元素原先里面的类名jQuery里面类操作只是对指定类进行操作,不影响原先的类名

显示隐藏show()//显示hide()//隐藏toggle()//切换

hide([speed],[easing],[fn])//参数可以全部省略无动画直接显示//speed三种速度预设值"slow""normal""fast"也可以直接写毫秒1000//easing用来指定切换效果默认"swing"可用"linear"//fn回调函数动画结束时执行toggle([speed],[easing],[fn])//参数可以全部省略,无动画显示

滑动slideDown()//下滑slideUp()//上滑slideToggle()//切换

slideToggle([speed],[easing],[fn])//参数可以全部省略无动画直接显示//speed三种速度预设值"slow""normal""fast"也可以直接写毫秒1000//easing(Optional)用来指定切换效果默认"swing"可用"linear"//fn回调函数动画结束时执行

淡入淡出fadeIn()//淡入fadeOut()//淡出fadeToggle()//切换fadeTo()//可设置透明度(1000,.5)

动画animate()

animate(css,[speed],[easing],[fn])//css:想要更改的样式属性,以对象形式传递,必须写。属性名可以不用带引号,如果是复合属性则需要采取驼峰命名法borderLeft。其余参数都可以省略{height:’500px’,fontSize:’30px’}//css写法(px可以省略)//speed:三种预定速度之一的字符串(“slow”,“normal”,or“fast”)或表示动画时长的毫秒数值(如:1000)//easing:(Optional)用来指定切换效果,默认是“swing”,可用参数“linear”//fn回调函数

each()方法规定为每个匹配元素规定运行的函数$(selector).each(function(index,element))function(index,element):index为下标e为事件对象(也可以用"this"选择器)

返回false可用于及早停止循环

stop()方法用于在动画或效果完成前对它们进行停止.stop()"停止"会停止当前活动的动画,但允许已排队的动画向前执行.stop(true)"停止所有"停止当前活动的动画,并清空动画队列;因此元素上的所有动画都会停止.stop(true,true)"停止但要完成"会立即完成当前活动的动画,然后停下来

在动画后可添加回调函数,在动画运行完成后可执行回调函数

$("button").click(function(){$("p").hide(1000,function(){//回调函数,在动画结束后运行alert("Theparagraphisnowhidden");});});

hover(function(){},function(){})第一个函数为鼠标移上触发的函数(相当于mouseenter)第二个函数为鼠标移出触发的函数(相当于mouseleave)如果只写一个函数,则鼠标经过和离开都会触发

.hover()方法相当于鼠标移入与鼠标移出事件的合体

设置或获取元素固有属性prop()//只能操作自带属性设置或获取元素自定义属性attr()//可以操作自带属性和自定义属性移除属性removeProp()

data()方法可以在指定的元素上存取数据,并不会修改DOM元素结构。一旦页面刷新,之前存放的数据都将被移除用于设置获取自定义属性

.data('name')//返回name属性值.data('name','value')//给被选元素添加name属性值为value(附加数据).data()//以对象的方式返回所有存储的属性与属性值

只能读取HTML5自定义属性data-index,得到的是数字型

针对元素的内容的值操作普通元素内容.html()(相当于原生.innderHtml).html()//获取元素的内容.html("内容")//设置元素的内容普通文本元素内容.text()(相当于原生.innerText).text()//获取元素的文本内容.text("文本内容")//设置元素的文本内容

针对表单值得操作表单的值val()(相当于原生.value).val()//获取表单的值.val("内容")//设置表单的值

//text的回调函数$("#test1").text(function(i,origText){//i为index,origText为原来的文本return"Oldtext:"+origText+"Newtext:Helloworld!(index:"+i+")";//return返回的内容为要更改的内容.text("内容")});

当元素的值发生改变时,会发生change事件该事件仅适用于表单元素change()函数触发change事件,或规定当发生change事件时运行的函数

//change()$(".field").change(function(){$(this).css("background-color","#FFFFCC");});

.each()方法遍历匹配的每一个元素,主要是DOM处理,each每一个里面的回调函数有两个参数,index为每个元素的索引,demEle是DOM元素对象,不是JQ对象,所以想要使用JQ方法,需要转换为JQ对象

$("div").each(function(index,domEle){xxx;})//domEle当前DOM元素,可以使用this选择器.each(object,function(index,element){xxx;})//object为遍历的对象returnfalse可以提早种终止循环

创建元素语法:$("

")动态创建了一个div

插入对象内部添加(父子关系添加).append("内容")//将内容放入匹配元素内部的最后面(类似原生appendChind).preprnd("内容")//将内容放入匹配元素内部的最前面

外部添加(兄弟关系添加).after("内容")//将内容放在匹配元素的后面.before("内容")//吧内容放在陪陪元素的前面

删除元素.remove()//删除自己.empty()//删除匹配元素集合的所有子节点.html("")//清空匹配的元素内容//.empty()和.html("")作用等价,都可以删除元素里面的内容,只不过html还可以设置内容

width()/height()//获取元素的宽高(只有width和height)innerWidth()/innerHeight()//获取宽高(包含padding)outerWidth()/outerHeight()//获取宽高(包含padding、border)outerWidth(true)/outerHeight(true)//获取宽高(含padding、border、margin)以上参数为空,获取相应值,返回数字型如果参数为数字,则为修改相应值参数可不写单位

offset()position()scrollTop()/scrollLeft()

offset()//设置或获取元素偏移offset()方法设置或返回元素相对于文档的偏移坐标,跟父级没有关系该方法有两个属性offset().top获取距离文档顶部的距离,offset().left同理设置元素偏移:offset({top:10,left:30})

position()获取元素偏移position()用于返回被选元素相对于带有定位的父级偏移坐标,如果父级都没有定位则以文档为准该方法有两个属性topleft。position().top用于获取举例定位父级顶部的距离,position().left同理该方法只能获取

scrollTop()/scrollLeft()设置或获取元素被卷去的部分scrollTop()设置或返回被选元素被卷去的头部不跟参数是获取,参数为不带单位的数字为设置

on()方法在匹配元素(单个或多个)上绑定一个或多个事件的处理函数element.on(events,[selector],fn)events:一个或多个用空格分隔的事件类型(例:clickkeydown)selector:元素的子元素选择器fn:回调函数,即绑定在元素身上的侦听函数

如果有的事件只想触发一次,可以使用one()来绑定事件

//on方法优势1:可以绑定多个事件,多个事件处理程序$(“div”).on({mouseover:function(){},mouseout:function(){},click:function(){}});//如果事件处理程序相同$(“div”).on(“mouseovermouseout”,function(){$(this).toggleClass(“current”);})//on()方法优势2:事件委托$('ul').on('click','li',function(){alert('helloworld!');});//传入子集为事件委托//不传入事件对象在此前在此之前有bind(),live()delegate()等方法来处理事件绑定或者事件委派,最新版本的请用on()//on()方法优势3:给动态创建的元素绑定事件$("div").append($("

我是动态创建的p

"));$("div").on("click","p",function(){alert("俺可以给动态生成的元素绑定事件")});off()解绑事件off()方法可以移除通过on()方法添加的事件处理程序$("p").off()//解绑p元素所有事件处理程序$("p").off("click")//解绑p元素上面的点击事件后面的foo是侦听函数名$("ul").off("click","li")//解绑事件委托

$("p").on("click",function(){//绑定p的click事件console.log('Hi');});//第一种简写形式的自动触发:$("p").click()//$("p")为一个对象,.click为对象内的属性,属性值为console.log('Hi');后加()触发click//第二种利用trigger()方法触发$("p").trigger("click")//第三种自动触发方式:$("p").triggerHandler("click")//第三种自动触发模式//triggerHandler模式不会触发元素的默认行为,这是和前面两种的区别

$().on(events,[selector],function(event){})

//阻止默认行为:$().preventDefault()//或者returnfalse//阻止冒泡:$().stopPropagation()

$.extend([deep],target,object1,[objextN])deep:true为深拷贝,false为浅拷贝target:要拷贝的目标对象object1:待拷贝到第一个对象的对象

浅拷贝目标对象引用的被拷贝的对象地址,修改的目标会影响被拷贝对象深拷贝,完全克隆,修改目标对象不会影响被拷贝对象

jQuery使用$作为标示符,随着jQuery的流行,其他js库也会用这$作为标识符,这样一起使用会引起冲突.jQuery变量规定新的名称:$.noConflict()varxx=$.noConflict();将此段代码粘贴在引入的JQ中来改变JQ的符号

重点:瀑布流插件图片懒加载插件

修饰符iignore-不区分大小写gglobal-全局匹配mmultiline-多行匹配使边界字符^和$匹配每一行的开头和结尾,记住是多行,而不是整个字符串的开头和结尾

/a/g//全局匹配a/a/gi//全局匹配a不区分大小写元字符

/[0-9]+///是否有0-9的数字(+代表可以有很多个数字)/a///是否有a

AJAX=AsynchronousJavaScriptandXML(异步的JavaScript和XML)现为JS和JSON优点是在不重新加载整个页面的情况下,可以与服务器交换数据并更新部分网页内容以JS为底层,JQ封装了AJAX方法

在没有AJAX前使用表单传递数据,但是表单不能实现异步。会跳转

前端与服务器之间存在跨域问题,服务器之间不存在跨域问题

$.ajax()方法

type:

1.'get'(查看)会向数据库发索取数据的请求,从而来获取信息。只是用来查询一下数据,不会修改、增加数据,不会影响资源的内容,即该请求不会产生副作用。无论进行多少次操作,结果都是一样的2.’put‘(更新)向服务器端发送数据的,从而改变信息.用来修改数据的内容,但是不会增加数据的种类等,也就是说无论进行多少次PUT操作,其结果并没有不同3.'post'(创建)向服务器端发送数据的,但是该请求会改变数据的种类等资源,会创建新的内容。几乎目前所有的提交操作都是用POST请求的4.'delete'(删除)删除某一个资源的$.ajax({//AJAX方法,内为对象type:'get',//AJAX类型,此处为获取(共有四种类型,常用两种)默认geturl:'1.json',//获取地址data:{},//传递参数dataType:"json",async:true,//是否异步success:function(res){//成功获取后执行函数console.log(res);//res为获取到的数据对象,需要逐层找到需要使用的信息},error:function(res){//获取失败后执行函数console.log(res);//打印res可以获得详细的错误详情}})$.get()和$.post()是简易写法,高层的实现,在调用他们的时候,会运行底层封装好的$.ajax

$.get()方法-从指定的资源请求数据(基本用于取回数据,可能返回缓存数据)$.get()方法通过HTTPGET请求从服务器上请求数据

$("button").click(function(){$.get("demo_test.php",function(data,status){//get()的第一个参数为请求的地址第二个是回调函数alert("数据:"+data+"\n状态:"+status);//函数内的data存有被请求页面的内容status存有请求的状态});});$.post()方法-向指定的资源提交要处理的数据(也可用于获取数据,但post不会缓存数据,且常用于联通请求一起发送数据)$.post()方法通过HTTPPOST请求向服务器提交数据

get请求方式:

functionajax(){//创建核心对象xhr=null;if(window.XMLHttpRequest){//新版本浏览器可以直接创建对象,判断此浏览器有没有此对象xhr=newXMLHttpRequest();//创建对象}elseif(window.ActiveXObject){//IE5或IE6没有XMLHttpRequest对象xhr=newActiveXObject("Microsoft.XMLHTTP");}//编写回调函数xhr.onreadystatechange=function(){if(xhr.readyState==4&&xhr.status==200){//readystate判断XMLHttpRequest状态(4为请求完成且响应就绪)xhr.status:获取当前服务器的响应状态200=>成功console.log(xhr.responseText)//打印获取的数据}}//设置open请求方式和请求路径xhr.open("get","/Ajax/ajaxuserId=10",true);//一个URL还传递了数据,true为异步//send发送xhr.send();}

post请求方式

functionajax(){//创建核心对象xhr=null;if(window.XMLHttpRequest){//新版本浏览器可以直接创建对象,判断此浏览器有没有此对象xhr=newXMLHttpRequest();//创建对象}elseif(window.ActiveXObject){//IE5或IE6没有XMLHttpRequest对象xhr=newActiveXObject("Microsoft.XMLHTTP");}//编写回调函数xhr.onreadystatechange=function(){if(xhr.readyState==4&&xhr.status==200){//readystate判断XMLHttpRequest状态(4为请求完成且响应就绪)xhr.status:获取当前服务器的响应状态200=>成功console.log(xhr.responseText)//打印获取的数据}}//open设置请求方式和请求路径xhr.open("post","/Ajax/ajax2",true)//一个servlettrue为异步//设置请求头(POST)xhr.setRequestHeader("Content-Type","application/x-www-form-urlencoded")//send发送xhr.send("userId=10");}

readystate:存有XMLHttpRequest的状态。从0到4发生变化0:请求未初始化1:服务器已建立2:请求已接收3:请求处理中4:请求已完成,且响应已就绪

status:200:'OK'404:未找到页面405:请求方式不正确500:服务器内部错误403:禁止请求

封装好的原生ajax方法:

functionajax(url){//创建XMLHttpRequest对象,新版本浏览器直接创建,IE5IE6创建ActiveXObject对象varxhr=window.XMLHttpRequestnewXMLHttpRequest():ActiveXObject("microsoft.XMLHttp")xhr.open("get",url,true);xhr.send();//发送请求xhr.onreadystatechange=()=>{if(xhr.readyState==4){//返回存有XMLHttpRequest的状态if(xhr.status==200){//返回状态码vardata=xhr.responseText;returndata;}}}}

ES6是JavaScript语言的下一代标准,使得JavaScript语言可以用来编写复杂的大型应用程序,成为企业级开发语言。

constbox=document.querySelector(".box");letid=1;lettitle="腾讯新闻";letstr="";str=`

  • ${title}

`;box.innerHTML=str;字符串的遍历接口字符串可以被for...of循环遍历

varstr='foo';for(letxofstr){console.log(x)}//"f"//"o"//"o"除了遍历字符串,这个遍历器最大的优点是可以识别大于0xFFFF的码点,传统的for循环无法识别这样的码点

repeat方法返回一个新字符串,表示将原字符串重复n次

'x'.repeat(3)//"xxx"'hello'.repeat(2)//"hellohello"'na'.repeat(0)//""padStart(),padEnd()补全字符串ES2017引入了字符串补全长度的功能。如果某个字符串不够指定长度,会在头部或尾部补全。padStart()用于头部补全,padEnd()用于尾部补全第一个参数为字符串的最大长度第二个参数为补全字符串的字符第二个参数为空时默认用空格补全字符串

'x'.padStart(5,'ab')//'ababx''x'.padStart(4,'ab')//'abax'//在开头补全'x'.padEnd(5,'ab')//'xabab''x'.padEnd(4,'ab')//'xaba'//在末尾补全//如果原字符串的长度,等于或大于最大长度,则字符串补全不生效,返回原字符串。'xxx'.padStart(2,'ab')//'xxx''xxx'.padEnd(2,'ab')//'xxx'//padStart()的常见用途是为数值补全指定位数。下面代码生成10位的数值字符串。'1'.padStart(10,'0')//"0000000001"'12'.padStart(10,'0')//"0000000012"'123456'.padStart(10,'0')//"0000123456"//另一个用途是提示字符串格式。'12'.padStart(10,'YYYY-MM-DD')//"YYYY-MM-12"'09-12'.padStart(10,'YYYY-MM-DD')//"YYYY-09-12"trim()清除字符串空格consts='abc';s.trim()//"abc"清除所有空格s.trimStart()//"abc"清除前端空格s.trimEnd()//"abc"清除后端空格

Math.trunc方法用于去除一个数的小数部分,返回整数部分

Math.trunc(4.1)//4Math.trunc('123.456')//123Math.trunc(false)//0//对于空值和无法截取整数的值,返回NaNMath.trunc('foo');//NaNMath.sign方法用来判断一个数到底是正数、负数、还是零。对于非数值,会先将其转换为数值

//参数为正数,返回+1;Math.sign(-5)//-1//参数为负数,返回-1;//参数为0,返回0;//参数为-0,返回-0;//其他值,返回NaN

//1.带参数默认值的函数//es5写法//functionadd(a,b){//a=a||2;//b=b||6;//returna+b;//}//es6functionadd(a=1,b=6){returna+b;}console.log(add(3))//9a=3(赋值);b=6(默认)console.log(add(3,3))//2.默认的表达式也可以是一个函数functionadd(a,b=getVal(2)){//a=10returna+b;}functiongetVal(val){returnval+5;}console.log(add(10))//17ES6引入rest参数(形式为...变量名),用于获取函数的多余参数,这样就不需要使用arguments对象了。rest参数搭配的变量是一个数组,该变量将多余的参数放入数组中

//3.剩余参数(剩余运算符)(有三个点...和紧跟着的参数指定...keys)//4.扩展运算符constMaxNum=Math.max(50,20);console.log(MaxNum);//es5处理数组中的最大值,使用applyconstarr=[1,2,4,7,100,40];//constmaxNum=Math.max(arr);会报错哦constmaxNum=Math.max.apply(null,arr);console.log(maxNum);//es6扩展运算符console.log(Math.max(...arr));

//5.es6中使用箭头函数//letadd=function(a,b){//returna+b;//}//两个参数//letadd=(a,b)=>{//returna+b;//}//letadd=(a,b)=>(a+b);//letadd=(a,b)=>a+b;//console.log(add(2,3))//一个参数//letadd=val=>val//console.log(add(5))//5letadd=val=>(val+5)console.log(add(10))//15//无参数//letfn=()=>{//return"haha";//}//letfn=()=>"haha";//letfn=()=>"haha"+123;//console.log(fn())letgetObj=(id)=>{return{id:id,name:"张三"}}//简单写法,一定要加();//letgetObj=(id)=>({id:id,name:"张三"})console.log(getObj(2))箭头函数的this指向箭头函数体内的this对象,就是定义该函数时所在的作用域指向的对象,而不是调用时所在的作用域指向的对象。

varname='window';varA={name:'A',sayHello:()=>{console.log(this.name)}}A.sayHello();//输出的是window//"定义该函数所在的作用域指向的对象”,作用域是指函数内部,这里的箭头函数,也就是sayHello,所在的作用域其实是最外层的js环境,因为没有其他函数包裹;然后最外层的js环境指向的对象是winodw对象,所以这里的this指向的是window对象若要绑定A对象:varname='window';varA={name:'A',sayHello:function(){vars=()=>console.log(this.name)returns//返回箭头函数s}}varsayHello=A.sayHello();sayHello();//输出AvarB={name:'B';}sayHello.call(B);//不管是谁调用,this指向都是AsayHello.call();//还是A

扩展运算符(spread)是三个点(...)。它好比rest参数的逆运算,将一个数组转为用逗号分隔的参数序列该运算符主要用于函数调用(传递参数)只有函数调用时,扩展运算符才可以放在圆括号中,否则会报错替代函数的apply方法

console.log(...[1,2,3])//123console.log(1,...[2,3,4],5)//12345[...document.querySelectorAll('div')]//[

,
,
]functionadd2(...args){console.log(args);//['a','b','c']console.log(arguments);//Arguments(3)['a','b','c',callee:(...),Symbol(Symbol.iterator):]}add2("a","b","c");letarr=[1,2,3,4,5,6,7,8,9]letmax=Math.max(...arr)//此处如果传入arr将会报错console.log(max)//9//参数接收的arguments为伪数组,而...keys为真正的数组扩展运算符可以用来合并数组(两种方法都是浅拷贝)constarr1=['a','b'];constarr2=['c'];constarr3=['d','e'];//ES5的合并数组arr1.concat(arr2,arr3);//['a','b','c','d','e']//ES6的合并数组[...arr1,...arr2,...arr3]//['a','b','c','d','e']扩展运算符与解构赋值结合const[first,...rest]=[1,2,3,4,5];first//1rest//[2,3,4,5]const[first,...rest]=[];first//undefinedrest//[]const[first,...rest]=["foo"];first//"foo"rest//[]如果将扩展运算符用于数组赋值,只能放在参数的最后一位,否则会报错

const[...butLast,last]=[1,2,3,4,5];//报错const[first,...middle,last]=[1,2,3,4,5];//报错将字符串转为数组[...'hello']//["h","e","l","l","o"]

数组的空位指,数组的某一个位置没有任何值。比如,Array构造函数返回的数组都是空位

Array(3)//[,,,]ES5不识别空位ES6将空位转为undefind扩展运算符(...)也会将空位转为undefinedcopyWithin()会连空位一起拷贝for...of循环也会遍历空位。

Array.from方法用于将两类对象转为真正的数组:类似数组的对象(array-likeobject)和可遍历(iterable)的对象(包括ES6新增的数据结构Set和Map)。

letarrayLike={'0':'a','1':'b','2':'c',length:3};//ES5的写法vararr1=[].slice.call(arrayLike);//['a','b','c']//ES6的写法letarr2=Array.from(arrayLike);//['a','b','c']//NodeList对象letps=document.querySelectorAll('p');//获取所有的p标签Array.from(ps).filter(p=>{//from转换为数组filter将不符合要求的p元素从数组中去除returnp.textContent.length>100;});//arguments对象functionfoo(){varargs=Array.from(arguments);//将参数存储的伪数组转换为真正的数组}//将字符串转换为数组Array.from('hello')//更建议使用{...str}的方法//['h','e','l','l','o']

Array.copyWithin(target,start=0,end=this.length)//target(必需):从该位置开始替换数据。如果为负值,表示倒数。//start(可选):从该位置开始读取数据,默认为0。如果为负值,表示从末尾开始计算。//end(可选):到该位置前停止读取数据,默认等于数组长度。如果为负值,表示从末尾开始计算。

数组实例的find方法,用于找出第一个符合条件的数组成员。它的参数是一个回调函数,所有数组成员依次执行该回调函数,直到找出第一个返回值为true的成员,然后返回该成员。如果没有符合条件的成员,则返回undefined。

[1,4,-5,10].find((n)=>n<0)//-5find方法的回调函数可以接受三个参数,依次为当前的值、当前的位置和原数组。

[1,5,10,15].find(function(value,index,arr){returnvalue>9;})//10

数组实例的findIndex方法的用法与find方法非常类似,返回第一个符合条件的数组成员的位置,如果所有成员都不符合条件,则返回-1

fill方法使用给定值,填充一个数组。数组中已有的元素,会被全部抹去。

['a','b','c'].fill(7)//[7,7,7]newArray(3).fill(7)//[7,7,7]fill方法还可以接受第二个和第三个参数,用于指定填充的起始位置和结束位置。

['a','b','c'].fill(7,1,2)//['a',7,'c']注意,如果填充的类型为对象,那么被赋值的是同一个内存地址的对象,而不是深拷贝对象。

传入一个值时

[1,2,3].includes(2)//true[1,2,3].includes(4)//false[1,2,NaN].includes(NaN)//true该方法的第二个参数表示搜索的起始位置,默认为0。如果第二个参数为负数,则表示倒数的位置,如果这时它大于数组长度(比如第二个参数为-4,但数组长度为3),则会重置为从0开始。

[1,2,3].includes(3,3);//false[1,2,3].includes(3,-1);//true从倒数第一位开始找

用于将嵌套的数组“拉平”,变成一维的数组。该方法返回一个新数组,对原数据没有影响。

[1,2,[3,4]].flat()//[1,2,3,4]默认只会“拉平”一层,如果想要“拉平”多层的嵌套数组,可以将flat()方法的参数写成一个整数,表示想要拉平的层数,默认为1。

[1,2,[3,[4,5]]].flat()//[1,2,3,[4,5]][1,2,[3,[4,5]]].flat(2)//[1,2,3,4,5]如果不管有多少层嵌套,都要转成一维数组,可以用Infinity关键字作为参数。

[1,[2,[3]]].flat(Infinity)//[1,2,3]如果原数组有空位,flat()方法会跳过空位。

[1,2,,4,5].flat()//[1,2,4,5]

entries(),keys()和values()——用于遍历数组。它们都返回一个遍历器对象可以用for...of循环进行遍历,唯一的区别是keys()是对键名的遍历、values()是对键值的遍历,entries()是对键值对的遍历。

entries()

for(letindexof['a','b'].keys()){console.log(index);}//0//1for(letelemof['a','b'].values()){console.log(elem);}//'a'//'b'for(let[index,elem]of['a','b'].entries()){console.log(index,elem);}//0"a"//1"b"

在大括号里面,直接写入变量和函数,作为对象的属性和方法。

旧方法定义对象属性:

//方法一obj.foo=true;//方法二obj['a'+'bc']=123;//方法三varobj={foo:true,abc:123};允许字面量定义对象时,用方法二(表达式)作为对象的属性名,即把表达式放在方括号内。

letpropKey='foo';letobj={[propKey]:true,//foo:true['a'+'bc']:123,//abc:123['h'+'ello'](){//hello:function(){}return'hi';}};注意,属性名表达式如果是一个对象,默认情况下会自动将对象转为字符串[objectObject],这一点要特别小心。

constkeyA={a:1};constkeyB={b:2};constmyObject={[keyA]:'valueA',[keyB]:'valueB'};myObject//Object{[objectObject]:"valueB"}

constperson={sayName(){console.log('hello!');},};person.sayName.name//"sayName"

this关键字总是指向函数所在的当前对象,ES6又新增了另一个类似的关键字super,指向当前对象的原型对象。

对象的扩展运算符(...)用于取出参数对象的所有可遍历属性,拷贝到当前对象之中。

letz={a:3,b:4};letn={...z};n//{a:3,b:4}由于数组是特殊的对象,所以对象的扩展运算符也可以用于数组。

letfoo={...['a','b','c']};foo//{0:"a",1:"b",2:"c"}

解构赋值

let{x,y,...z}={x:1,y:2,a:3,b:4};x//1y//2z//{a:3,b:4}//解构赋值要求等号右边是一个对象,所以如果等号右边是undefined或null,就会报错,因为它们无法转为对象。//解构赋值必须是最后一个参数,否则会报错。//解构赋值为浅拷贝!

它用来比较两个值是否严格相等,与严格比较运算符(===)的行为基本一致。

+0===-0//trueNaN===NaN//falseObject.is(+0,-0)//falseObject.is(NaN,NaN)//true

将源对象(source)的所有可枚举属性,复制到目标对象(target)。

consttarget={a:1};constsource1={b:2};constsource2={c:3};Object.assign(target,source1,source2);target//{a:1,b:2,c:3}第一个参数是目标对象,后面的参数都是源对象。注意,如果目标对象与源对象有同名属性,或多个源对象有同名属性,则后面的属性会覆盖前面的属性。如果该参数不是对象,则会先转成对象,然后返回。

剩余操作符:...

写法属于“模式匹配”,只要等号两边的模式相同,左边的变量就会被赋予对应的值

let[foo,[[bar],baz]]=[1,[[2],3]];foo//1bar//2baz//3let[,,third]=["foo","bar","baz"];third//"baz"let[x,,y]=[1,2,3];x//1y//3let[head,...tail]=[1,2,3,4];head//1tail//[2,3,4]let[x,y,...z]=['a'];x//"a"y//undefinedz//[]//不完全解构let[x,y]=[1,2,3];x//1y//2let[a,[b],d]=[1,[2,3],4];a//1b//2d//4解构赋值允许默认值

let[foo=true]=[];foo//truelet[x,y='b']=['a'];//x='a',y='b'let[x,y='b']=['a',undefined];//x='a',y='b'//注意,ES6内部使用严格相等运算符(===),判断一个位置是否有值。所以,只有当一个数组成员严格等于undefined,默认值才会生效//上面代码中,如果一个数组成员是null,默认值就不会生效,因为null不严格等于undefined例:let[x=1]=[undefined];x//1let[x=1]=[null];x//null

对象的解构与数组有一个重要的不同。数组的元素是按次序排列的,变量的取值由它的位置决定;而对象的属性没有次序,变量必须与属性同名,才能取到正确的值

let{bar,foo}={foo:'aaa',bar:'bbb'};foo//"aaa"bar//"bbb"let{baz}={foo:'aaa',bar:'bbb'};baz//undefined//对象的解构赋值的内部机制,是先找到同名属性,然后再赋给对应的变量。真正被赋值的是后者,而不是前者。let{foo:baz}={foo:'aaa',bar:'bbb'};baz//"aaa"//上面代码中,foo是匹配的模式,baz才是变量。真正被赋值的是变量baz,而不是模式foo。//与数组一样,解构也可以用于嵌套结构的对象letobj={p:['Hello',{y:'World'}]};let{p:[x,{y}]}=obj;x//"Hello"y//"World"//默认值var{x=3}={};x//3var{x,y=5}={x:1};x//1y//5var{x:y=3}={};y//3var{x:y=3}={x:5};y//5

//错误的写法letx;{x}={x:1};//SyntaxError:syntaxerror上面代码的写法会报错,因为JavaScript引擎会将{x}理解成一个代码块,从而发生语法错误。只有不将大括号写在行首,避免JavaScript将其解释为代码块,才能解决这个问题

//正确的写法letx;({x}={x:1});

字符串也可以解构赋值。这是因为此时,字符串被转换成了一个类似数组的对象。类似数组的对象都有一个length属性,因此还可以对这个属性解构赋值。

const[a,b,c,d,e]='hello';a//"h"b//"e"c//"l"d//"l"e//"o"let{length:len}='hello';len//5

JavaScript标准中规定对象的key只能是String或Symbol类型,区别在于String类型的key可以重复而Symbol类型的key是唯一的。Symbol的本质是表示一个唯一标识。每次创建一个Symbol,它所代表的值都不可能重复

constsym=Symbol();constsym=Symbol('cat');//传入一个字符串参数(descriptor)用于描述该Symbol:console.log(sym)//Symbol(cat)最大的用途就是用来定义对象的私有属性

constname=Symbol("name");constname2=Symbol("name");console.log(name===name2);//false//其内存地址不相同Symbol属性无法正常遍历不易操作,因此不常用

获取Symbol属性可以使用特定的方法Object.getOwnPropertySymbols()

varObj={}vara=Symbol("a");Obj[a]='123'varobjectSymbols=Object.getOwnPropertySymbols(Obj);console.log(objectSymbols.length)//1console.log(objectSymbols)//[Symbol(a)]

获取Symbol属性也可以使用反射

constname=Symbol("name");constage=Symbol("age");letperson={[name]:"张三",[age]:"10",sex:"男"};letkk=Reflect.ownKeys(person);//遍历键console.log(kk);//Array(3)["sex",Symbol(name),Symbol(age)]for(leti=0;i

Promise,简单说就是一个容器,里面保存着某个未来才会结束的事件(通常是一个异步操作)的结果

Promise对象的特点:

1.对象的状态不受外界影响。Promise对象代表一个异步操作,有三种状态:pending(进行中)、fulfilled(已成功)和rejected(已失败)。只有异步操作的结果,可以决定当前是哪一种状态,任何其他操作都无法改变这个状态。

2.一旦状态改变,就不会再变,任何时候都可以得到这个结果。Promise对象的状态改变,只有两种情况:进行中到已成功、进行中到已失败。只要这两种情况发生,状态就凝固了,不会再改变。

Promise对象的缺点:1.无法取消Promise一旦新建它就会立即执行,无法中途取消。2.如果不设置回调函数,Promise内部抛出的错误,不会反应到外部。3.当处于pending(进行中)状态时,无法得知目前进展到哪一个阶段(刚刚开始还是即将完成)。

ES6规定,Promise对象是一个构造函数,用来生成Promise实例。

//创建promise对象varmyFirstPromise=newPromise(function(resolve,reject){//当异步代码执行成功时,我们才会调用resolve(...),当异步代码失败时就会调用reject(...)//在本例中,我们使用setTimeout(...)来模拟异步代码,实际编码时可能是XHR请求或是HTML5的一些API方法.setTimeout(function(){resolve("成功!");//代码正常执行!},250);});myFirstPromise.then(function(successMessage){//successMessage的值是上面调用resolve(...)方法传入的值.//successMessage参数不一定非要是字符串类型,这里只是举个例子document.write("Yay!"+successMessage);});//创建promise对象letp=newPromise((resolve,reject)=>{setTimeout(()=>{//模拟异步操作reject('失败');resolve('成功')},2000);})p.then((res)=>{console.log(res);//成功})对于已经实例化过的promise对象可以调用promise.then()方法,传递resolve和reject方法作为回调。

then()方法返回一个Promise。它最多需要有两个参数:Promise的成功和失败情况的回调函数。

then方法可以链式操作

constpromise1=newPromise((resolve,reject)=>{resolve('Success!');//成功时返回reject('error!');//失败时返回});promise1.then((value)=>{//接收返回值console.log(value);//expectedoutput:"Success!"});语法:promise.then(onCompleted,onRejected);参数:

resolve()方法可以把任何对象转化成Promise对象

letp=Promise.resolve("啊哈哈");letp=newPromise(resolve=>resolve("foo"));p.then((res)=>{console.log(res);})Promise.resolve('foo')//等价于newPromise(resolve=>resolve('foo'))如果参数是Promise实例,那么Promise.resolve将不做任何修改、原封不动地返回这个实例。

参数是一个thenable对象,(thenable对象指的是具有then方法的对象),会将这个对象转为Promise对象,然后就立即执行thenable对象的then方法。

参数不是具有then方法的对象,或根本就不是对象,方法返回一个新的Promise对象,状态为resolved。

不带有任何参数,方法允许调用时不带参数,直接返回一个resolved状态的Promise对象。

返回一个新的Promise实例,该实例的状态为rejected。

constp=Promise.reject('出错了');//等同于constp=newPromise((resolve,reject)=>reject('出错了'))p.then(null,function(s){console.log(s)});//出错了注意,Promise.reject()方法的参数,会原封不动地作为reject的理由,变成后续方法的参数。这一点与Promise.resolve方法不一致。

用于将多个Promise实例,包装成一个新的Promise实例。

constp=Promise.all([p1,p2,p3]);//p1p2p3都是promise实例//如果不是,就会先调用下面讲到的Promise.resolve方法,将参数转为Promise实例,再进一步处理。另外,Promise.all()方法的参数可以不是数组,但必须具有Iterator接口,且返回的每个成员都是Promise实例。p的状态由p1、p2、p3决定,分成两种情况:(1)只有p1、p2、p3的状态都变成fulfilled(成功),p的状态才会变成fulfilled,此时p1、p2、p3的返回值组成一个数组,传递给p的回调函数。

(2)只要p1、p2、p3之中有一个被rejected(失败),p的状态就变成rejected,此时第一个被reject的实例的返回值,会传递给p的回调函数。

注意,如果作为参数的Promise实例,自己定义了catch方法,那么它一旦被rejected,并不会触发Promise.all()的catch方法。(执行自己的catch)

Promise.prototype.catch()方法是.then(null,rejection)或.then(undefined,rejection)的别名,用于指定发生错误时的回调函数。

getJSON('/posts.json').then(function(posts){//...}).catch(function(error){//处理getJSON和前一个回调函数运行时发生的错误console.log('发生错误!',error);});上面代码中,getJSON()方法返回一个Promise对象,如果该对象状态变为resolved,则会调用then()方法指定的回调函数;如果异步操作抛出错误,状态就会变为rejected,就会调用catch()方法指定的回调函数,处理这个错误。另外,then()方法指定的回调函数,如果运行中抛出错误,也会被catch()方法捕获。

Promise.race()方法同样是将多个Promise实例,包装成一个新的Promise实例。

上面代码中,只要p1、p2、p3之中有一个实例率先改变状态,p的状态就跟着改变。那个率先改变的Promise实例的返回值,就传递给p的回调函数。

constp=Promise.race([fetch('/resource-that-may-take-a-while'),newPromise(function(resolve,reject){setTimeout(()=>reject(newError('requesttimeout')),5000)})]);p.then(console.log).catch(console.error);//如果5秒之内fetch方法无法返回结果,变量p的状态就会变为rejected,从而触发catch方法指定的回调函数。

表示无重复数值的有序列表,不是键值对的形式存储

varset=newSet();set.add(666);set.add("哈哈");set.add("张三");set.add("张三");set.add("张三");set.add("张三");console.log(set);//666哈哈张三console.log(set.has(666));//是否有666trueconsole.log(set.delete(222));//删除集合中的222false集合中没有222set集合中键就是值值就是键所以一般不用forEach遍历

set.forEach((v,k)=>{console.log(k,v);})//666666//哈哈哈哈//张三张三可以使用for...of遍历

for(constvofset){console.log(v);}//666//哈哈//张三因为set集合为没有重复数值的有序列表,所以可以用来数组去重

letarr=[1,1,2,2,3,4,5,6,7,7]letset=newSet(arr)//将数组转为set集合console.log(set)//此时打印的set集合已经没有重复vararr1=[...set]//将set集合转为数组console.log(arr1)//打印去重后的新数组

Map集合是键值对的有序列表,键和值是任意类型

lethaha=newMap();//存值haha.set("name","张三");haha.set("age",10);console.log(haha);//Map(2){'name'=>'张三','age'=>10}console.log(haha.get("name"));//张三获取nameconsole.log(haha.has("name"));//true是否有nameconsole.log(haha.delete("name"));//true删除name键值对其他写法

letm=newMap([["a",1],["b",2]]);console.log(m);//Map(2){'a'=>1,'b'=>2}

用于对象,for...of用于所有可迭代对象

for...in语句用于对象的属性进行循环操作。其语法如下:for(vark(变量名)in对象名字){//变量==对象中所有的属性名console.log(对象名[k])//在此执行代码,ls[k]为属性值}varobj={a:1,b:2,c:3};for(varpropinobj){console.log("obj."+prop+"="+obj[prop]);}

constarray1=['a','b','c'];for(constelementofarray1){console.log(element);}//a//b//c

现在有数组、对象、Map、Set、四种数据组合,他们还可以互相嵌套。需要一个统一的接口机制,来处理所有的数据结构遍历器(Iterator)就是这样一种机制

Iterator的作用有三个:一是为各种数据结构,提供一个统一的、简便的访问接口;二是使得数据结构的成员能够按某种次序排列;三是ES6创造了一种新的遍历命令for...of循环,Iterator接口主要供for...of消费

vararr=['a','b','c']letit=arr[Symbol.iterator]();//人为创建迭代器console.log(it.next());//创建迭代器后可以异步迭代console.log(it.next());console.log(it.next());//注意:迭代器要用第三方变量接,不然每一次调用next()都相当于第一次调用注意:有迭代器Iterator才能使用迭代上面的代码人为创建了一个迭代器下面的keys()values()entries()方法使用后自动创建了迭代器。可以直接迭代

1.迭代器是一个接口,能快捷的访问数据,通过Symbol.iterator来创建迭代器,通过迭代器的next()方法来获取迭代之后的结果.2.迭代器是用于遍历数据结构的指针(数据库的游标)

keys()values()entries()方法的使用:

letarr=[666,222,33,55];letit=arr.keys();//使用keys()后数组有可迭代的接口(Interator接口),可以用来迭代console.log(it);console.log(it.next());//迭代letit=arr.values();//使用values()后数组有可迭代的接口,可以用来迭代console.log(it);console.log(it.netx());//迭代letit=arr.entries();//使用entries()后数组有可迭代的接口,可以用来迭代console.log(it);console.log(it.next());//迭代

Object.keys()方法会返回一个由一个给定对象的自身可枚举属性组成的数组,数组中属性名的排列顺序和正常循环遍历该对象时返回的顺序一致

generator函数,可以通过yield关键字键函数挂起(让函数停留在当前的位置)为了改变执行流提供了可能,同时为了做异步编程提供了可能

genertor函数没有执行器,需要next()方法来调用。generator函数的返回值是Iterator(迭代器)

1.function后面函数名之前有一个*2.只能在函数内部使用yield表达式,让函数挂起

function*fun(){console.log(111);//执行第一次yield1;//停止1为next()方法返回的valueconsole.log(222);//执行第二次yield2;//再次停止console.log(333);//执行第三次}//调用的时候返回一个类似迭代器对象,可以调用next()方法//generator函数分段执行的,yield是暂停执行,然而next()是恢复执行varit=fun()//要用第三方变量接函数,不然每一次直接调用都为第一次调用console.log(it.next());//111{value:1,done:false}console.log(it.next());//222{value:2,done:false}console.log(it.next());//333{value:undefined,done:true}//value为yield返回的值done为函数是否运行结束调用时利用next()传参

function*fun2(){console.log("start");letx=yield'第一次暂停';console.log("第二个next传递的参数为:"+x);lety=yield'第二次暂停';console.log("第三个next传递的参数为::"+y);}letit=fun2();console.log(it.next());//start{value:'第一次暂停',done:false}console.log(it.next(10));//第二个next传递的参数为:10{value:'第二次暂停',done:false}console.log(it.next(30));//第三个next传递的参数为::30{value:undefined,done:true}//注意:x不是yield的返回值next将参数传递给yield后赋给x使用场景:为不具备Interator接口的对象提供了遍历操作

当页面未加载时展示UI加载完成后展示另一个UI

async函数实际上就是Generator函数的语法糖(语法的简易写法)

async函数就是将Generator函数的星号(*)替换成async,将yield替换成await,仅此而已。

例:

asyncfunctionfun(){//varerr=newError('出现错误');//throwerr;returnawait"你好async";}varp=fun()p.then(res=>{console.log(res);//若没有错误,在此打印}).catch(err=>{//若出现错误,被catch捕捉console.log(err);//在此打印错误})例:

functiontimeout(ms){returnnewPromise((resolve)=>{//resolve在此处传递的是Promise是否执行成功//varerr=newError('运行出现错误')//throwerr;//当出现错误的时候,停止在下端await不继续执行setTimeout(resolve,ms);});}asyncfunctionasyncPrint(value,ms){awaittimeout(ms);//await在此做了同步化处理。若没有await使其等待,则会先执行打印console.log(value);}asyncPrint('helloworld',2000);async函数内部return语句返回的值,会成为then方法回调函数的参数。

async函数内部抛出错误,会导致返回的Promise对象变为reject状态。抛出的错误对象会被catch方法回调函数接收到。

正常情况下,await命令后面是一个Promise对象,返回该对象的结果。如果不是Promise对象,就直接返回对应的值。上面代码中,await命令的参数是数值"你好async",这时等同于return"你好async"。

async函数返回的Promise对象,必须等到内部所有await命令后面的Promise对象执行完,才会发生状态改变,除非遇到return语句或者抛出错误。也就是说,只有async函数内部的异步操作执行完,才会执行then方法指定的回调函数。`

async函数对Generator函数的改进,体现在以下四点:

async函数返回一个Promise对象,可以使用then方法添加回调函数。当函数执行的时候,一旦遇到await就会先返回,等到异步操作完成,再接着执行函数体内后面的语句。

functionPerson(name,age){this.name=name;//所有被构造函数创建的对象都会有的属性this.age=age;}Person.prototype.say=function(){//通过原型链,可以给所有被创建的对象添加方法console.log(`你好我是${this.name}`);}letxm=newPerson("小明",10);xm.say()functionPerson(name,age){this.name=name;this.age=age;this.say=function(){console.log(`你好我是${this.name}`);//通过this创建的say方法只是构造函数拥有,构造函数创建的对象不拥有}}letxm=newPerson("小明",10);xm.say()

classStudent{constructor(name,age){this.name=name;this.age=age;}say(){console.log(`你好我是${this.name}`);}skill(){console.log(`${this.name}会打乒乓球`);}}letzs=newStudent("张三",30)//通过类创建的对象,可以直接使用say()skill()方法letls=newStudent("李四",30)zs.say();ls.skill();

使用关键字extends继承

super关键字用于访问和调用一个对象的父对象上的函数。

在构造函数中使用时,super关键字将单独出现,并且必须在使用this关键字之前使用。super关键字也可以用来调用父对象上的函数。

一个模块就是一个独立的JS文件ES6的模块功能主要由两个命令构成:esport暴漏(抛出)、import()

在需要被暴漏的模块中:

letname="李四";letage=10;letadd=(a,b)=>{returna+b;}constcontent={name:"张三",age:10,add(a=0,b=0){returna+b;}}//暴露(抛出)export{name,age,add}//export{content}在引入模块的文件内:注意:在引入模块的文件内,script标签的type=‘module’不然会报错

//第一种写法import{content,name}from"./modules/Module1.js";console.log(name);//李四//第二种写法import*asffrom'./modules/Module1.js'//任意命名f,暴漏的所有数据都在f对象内//引用可以这样写:console.log(f.name)//李四注意:需要暴露什么写什么,需要接收什么写什么

ES5中请求模块用require

exportdefault命令,为模块指定默认输出。

constname="张三";constage=18;constobj={name:"大豆"}export{name,age,sayName,Person,obj}exportdefaultobj//此为默认输出在引入模块的文件内:

import*asffrom'./modules/Module2.js'//f为自定义命名//console.log(f)//f内为export暴漏的所有数据importafrom'./modules/Module2.js'//a为自定义命名console.log(a)//a内为默认暴漏的数据

INSERTINTOuser(user_name,user_phone,user_psw)VALUES('康新洋','18220550304','123456')插入在user表中插入的键为user_name,user_phone,user_pwd插入的值为...

SELECT*FROM`user`SELECT*FROMuserWHEREuser_name='苏倩文'SELECT*FROM`user`WHEREid=5select*fromuserwherephone=变量oremail=变量select*fromuserwhere(phone=变量oremail=变量)andpassword=变量查询名为user的数据库查询user库中user_name为苏倩文的查询user库中id为5的

DELETEFROMuserWHEREid=6DELETEFROMuserWHEREuser_name='赵阳'更新(更改)UPDATE`user`SET`user_phone`='18220550308'WHEREuser_name='茹小龙'设置新的手机号在user_name为如小龙的数据下

需要安装Node环境。

在浏览器打开输入localhost:端口号或IP地址:端口号

此处为查询操作if(req.url==="favicon.ico"){return};//阻止重复请求(放在服务器下)

//请求mysql模块constmysql=require('mysql')//mysql模块不是内置模块,在git中输入npminstallmysql--save下载模块//创建链接(与sql)constconnection=mysql.createConnection({//地址host:'localhost',//sql的用户名密码user:'root',password:'root',//数据库名database:'web2137',multipleStatements:true//支持执行多条sql语句})//链接connection.connect();//sql查询语句letsql='select*fromuser'//查询connection.query(sql,(error,result)=>{if(error){throwerror;}console.log(result);//process.exit(1);//关闭服务器代码})//运行此文件前先打开阿帕奇与sql数据库//运行此文件在git中输入://node文件名//运行此文件为nodeselect_node.js//运行服务器后需要关闭服务器JS代码为process.exit(1);//或在git中ctrl+c关闭服务器在git中输入npminstallmysql--save下载模块mysql(npm为外网)在git中输入cnpminstallmysql--save下载模块mysql(cnpm为国内网站)

sql模块中的end()方法为结束数据库操作

varapp={name:'app',version:'1.0.0',sayName:function(name){console.log(this.name);}}module.exports=app;//将app暴漏,可以调用模块//调用方法varapp=require('./app.js');app.sayName('hello');//hello封装的db数据库模块

constmysql=require('mysql');module.exports=(sql,callback)=>{constdb=mysql.createConnection({host:'localhost',user:'root',password:'root',database:'web2137'});db.connect();db.query(sql,callback);db.end();};

get:

尝试后发现,数据库的增删改查只是其中的sql语句发生了改变,所以将其余部分做个封装

封装部分:

constmysql=require('mysql');module.exports=(sql,callback)=>{constdb=mysql.createConnection({host:'localhost',user:'root',password:'root',database:'web2137'});db.connect();db.query(sql,callback);db.end();};引用部分:

首先创建一个基础框架,同时参考菜鸟express安装教程与express官网安装教程安装

路由决定了由谁(指定脚本)去响应客户端请求。在HTTP请求中,我们可以通过路由提取出请求的URL以及GET/POST参数。

Express提供了内置的中间件express.static来设置静态文件如:图片,CSS,JavaScript等。

app.use('/public',express.static('public'));///public为静态文件的访问路径

get接口中res.query为所有传入的数据

constexpress=require('express');constapp=express();app.use('/public',express.static('public'));app.get('/',(req,res)=>{letdata={name:'aaa'}//res.end('123');//res.send(data);res.json(data);})app.get('/list',(req,res)=>{res.end('list');})//接口app.get('/huoqu',(req,res)=>{//接口地址为/huoqu//letdata=req.queryletuser_name=req.query.user_name;letuser_psw=req.query.user_psw;letdata={user_name:user_name,user_psw:user_psw}res.send(data);});app.listen(3000);console.log(666);传输网页为

post接口中res,body为所有传入的数据

constexpress=require('express');constapp=express();//初始化express对象app.use('/public',express.static('public'));//静态文件地址varbodyParser=require('body-parser');//引入编码模块//创建application/x-www-form-urlencoded编码解析varurlencodedParser=bodyParser.urlencoded({extended:false})//post接口app.post('/denglu',urlencodedParser,function(req,res){res.send({code:1,msg:'登陆成功',user_name:req.body.user_name,user_psw:req.body.user_psw});//输出JSON格式//varresponse={//"first_name":req.body.first_name,//"last_name":req.body.last_name//};//console.log(response);//res.end(JSON.stringify(response));})app.listen(3000);console.log(666);html部分

npminstall-gnodemon//安装nodemonindex.js//热启动index.js

//解决跨域问题app.all("/*",function(req,res,next){//跨域处理res.header("Access-Control-Allow-Origin","*");res.header("Access-Control-Allow-Headers","X-Requested-With");res.header("Access-Control-Allow-Methods","PUT,POST,GET,DELETE,OPTIONS");res.header("X-Powered-By",'3.2.1');res.header("Content-Type","application/json;charset=utf-8");next();//执行下一个路由})放在app.js文件内所有的路由都不会跨域放在单独的路由文件内,只有该文件内的路由不会跨域

app.use((req,res,next)=>{//设置请求头res.set({'Access-Control-Allow-Credentials':true,'Access-Control-Max-Age':1728000,'Access-Control-Allow-Origin':req.headers.origin||'*','Access-Control-Allow-Headers':'X-Requested-With,Content-Type','Access-Control-Allow-Methods':'PUT,POST,GET,DELETE,OPTIONS','Content-Type':'application/json;charset=utf-8'})req.method==='OPTIONS'res.status(204).end():next()})

新创建的模块(maileConfig.js)内nodemailer模块需要下载

index.js接口部分

Vue2.0安装vue-cli

查看vue.js的版本——vue-V(注意后面的V是大写的,需要安装完cue-cli脚手架之后才能查看的到)安装最新vue.js——npminstallvueg

mode:(类型)默认值:"hash"(浏览器环境)|"abstract"(Node.js环境)可选值:"hash"|"history"|"abstract"

匹配路由环境:hash:使用URLhash值来作路由。支持所有浏览器,包括不支持HTML5HistoryApi的浏览器。history:依赖HTML5HistoryAPI和服务器配置(下面介绍HTML5History模式)abstract:支持所有JavaScript运行环境,如Node.js服务器端。如果发现没有浏览器的API,路由会自动强制进入这个模式。

HTML5History模式vue-router默认hash模式——使用URL的hash来模拟一个完整的URL,于是当URL改变时,页面不会重新加载。

如果不想要很丑的hash,我们可以用路由的history模式,这种模式充分利用history.pushStateAPI来完成URL跳转而无须重新加载页面。

所以呢,你要在服务端增加一个覆盖所有情况的候选资源:如果URL匹配不到任何静态资源,则应该返回同一个index.html页面,这个页面就是你app依赖的页面。

在src的router的index.js中

importVuefrom'vue'importRouterfrom'vue-router'importfatherfrom'@/components/father'Vue.use(Router)exportdefaultnewRouter({mode:'history',//添加此句去除#routes:[{path:'/',name:'father',component:father}]})

可以视为一个载体,显示当前的路由

MVVM表示的是Model-View-ViewModel`

Model:模型层,负责处理业务逻辑以及和服务器端进行交互View:视图层,负责将数据模型转化为UI展示出来,可以简单的理解为HTML页面ViewModel:视图模型层,用来连接Model和View,是Model和View之间的通信桥梁

Vue对象接下来的改动全部在以上指定的le:div内,div外部不受影响。

vue对象内的this指向这个vue对象

varvm=newVue({el:'#vue_det',//此vue对象控制此节点data:{//用于定义属性site:"菜鸟教程",url:"www.runoob.com",alexa:"10000"},methods:{//此内为函数details:function(){returnthis.site+"-学的不仅是技术,更是梦想!";}}})

数据绑定最常见的形式就是使用{{...}}(双大括号)的文本插值:

methods:{myclick(e){console.log(e.target.getAttribute('data-index'))}},

v-text不识别标签{{}}同样不识别标签

v-if是动态向DOM树添加或删除DOM元素v-show是更改标签的css样式display设置为none

编译区别:

v-if切换有一个局部编译/卸载的过程,切换过程中适合销毁和重建内部的事件监听和子组件v-show就是在控制css

编译条件:

v-if初始值为false,就不会编译了v-show都会编译,初始值为false,只是将dispaly设为none,但它也编译了

性能:

因为v-if不断在销毁创建,v-show只编译一次,所以v-show性能更好

用法:

v-if更灵活如果你的页面不想让其他程序员看到就用v-if,它不会在页面中显示。

简写形式::

v-for遍历时必须添加唯一属性key

遍历数组指令语法:v-for="数组的每一项in数组"v-for="iteminstudents"v-for='(v,index)in数组'v为数组中的每一项index为下标

遍历对象指令语法:v-for="(v,k)inperson"v为对象属性的值k为对象属性的值person为对象名

    姓名:{{item.name}}年龄:{{item.age}}性别:{{item.sex}}
{{k}}:{{v}}

循环的嵌套

    {{k}}:{{v}}

{{ms}}

信息不存在
1">哈哈

{{students}}

没有同学

{{ms}}

{{ms}}

{{ms}}

{{ms}}

注意:使用v-cloak时,vue的引入必须在css前,因为vue语句在css中用到了

{{ms2}}

{{ms}}

{{ms}}

{{ms}}

{{ms}}

{{t}}

在method中存放被调用的方法

举例:购物车的结算功能

{{msg}}

{{fanzhuan}}

模板必须设置type,id

hello:{{msg}}

vue中template标签的妙用

需求:div用v-for做了列表循环,现在想要span也一起循环

{{item.id}}--{{index}}
{{item.text}}利用template标签解决

{{item.text}}--{{index}}
{{item.text}}template的作用是模板占位符,可帮助我们包裹元素,但在循环过程当中,template不会被渲染到页面上

vue组件定义1.组件(Component)是Vue.js最强大的功能之一2.组件可以扩展HTML元素,封装可重用代码3.在较高层面上,组件是自定义元素,Vue.js的编译器为他添加特殊功能4.某些情况下,组件也可以表现用js特性进行了扩展的原生的HTML元素5.所有的Vue组件同时也都是Vue实例,所以可以接受相同的选项对象(除了一些根级特有的选项),并提供相同的生命周期钩子函数

vue组件的功能

Vue组件封装过程1.首先,使用Vue.extend()创建一个组件2.然后,使用Vue.component()方法注册组件3.接着,如果子组件需要数据,可以在props中接收定义4.最后,子组件修改好数据之后,想把数据传递给父组件,可以使用emit()方法

一:js当中创建组件

二:pemplate标签中创建组件

我是组件

三:在新的script中创建组件

我是一个组件

这是头部组件

标签是Vue框架自定义的标签,它的用途就是可以动态绑定我们的组件,根据数据的不同更换不同的组件

用法:渲染一个"元组件"为动态组件。依is的值,来决定哪个组件被渲染

prop是子组件用来接受父组件传递过来的数据的一个自定义属性。

注意:自定义属性放在在实例化vue对象前需要给Vue对象

{{name}}

Vue的八个生命周期/对应的钩子函数

{{msg}}更新销毁

使用vm.$watch('监听的数据',function(){})来监听

监听的数据发生变化,则会调用回调函数

监听只能监听data中的普通数据不能监听data中的对象

{{name}}

{{student}}

变一下

而深度监听可以监听data中的对象使用vm.$watch('被监听的对象',function(){},{deep:true})来监听

{{name}}

{{student}}

变一下

用Vue.filter('过滤的变量',function(val){return})来过滤

过滤器设置后会自动执行

过滤器必须有return(过滤器中存在判断,return需要在判断外)

{{shuzi|a}}

{{dateTime|date}}

Vue自带服务器,服务器之间不会跨域,所以要配置代理,可以避免跨域

Axios是一个基于Promise的HTTP库,可以用在浏览器和node.js中。

axios使用前需要引入

npminstall--saveaxiosvue-axios将以下代码按顺序引入到入口文件中routers>index.js

importVuefrom'vue'importaxiosfrom'axios'importVueAxiosfrom'vue-axios'Vue.use(VueAxios,axios)按照以下方式进行使用:

axios.get("api",{//get请求params:{//传递的参数type:'参数1',key:"参数2",},}).then((response)=>{//获取数据console.log(response);}).catch((err)=>{//错误捕捉console.log(err);throwerr;});},

axioscdn:

当api存在跨域时,在config文件中的index.js文件中设置代理在proxyTable对象内写代理

axios使用时写法为:

this.$router.push('/son')跳转页面

Home跳转页面(v-bind)

this.$router.push({path:"/son",query:{'msg':this.msg},});携带参数跳转

举例:跳转前传参的页面

接收参数的页面:

使用子组件时将值传递给子组件

子组件利用props接收数据

子组件:利用this.$emit("change",this.msgs)传递数据子组件:

父组件:@change="con"con(d){}

1.创建一个公共的bus.js文件(实例化vue对象)

importVuefrom'vue'exportdefaultnewVue()2.组件A的代码块:

3.组件B中的代码块:

1.在main.js中

Vue.prototype.$bus=newVue()//$bus是原型对象上的实例2.在传递参数的组件中

methods:{chuandi(){this.$bus.$emit("busfunction",this.name)},}3.在接收参数的组件中(在生命周期钩子中)

mounted(){this.$bus.$on("busfunction",(a)=>{//dosomething});},4.在接受参数的组件中(在生命周期钩子中)

使用$bus的时候在接受bus的组件中别忘了再beforDestroy函数中销毁bus,不销毁的话会一直叠加的调用这个方法

beforeDestroy(){this.$bus.$off("busfunction");},

Vuex是一个专为Vue.js应用程序开发的状态管理模式。它采用集中式存储管理应用的所有组件的状态,并以相应的规则保证状态以一种可预测的方式发生变化。

试想一下,如果在一个项目开发中频繁的使用组件传参的方式来同步data中的值,一旦项目变得很庞大,管理和维护这些值将是相当棘手的工作。为此,Vue为这些被多个组件频繁使用的值提供了一个统一管理的工具——VueX。在具有VueX的Vue项目中,我们只需要把这些值定义在VueX中,即可在整个Vue项目的组件中使用。

Vuex是专门为Vue.js设计的状态管理库,以利用Vue.js的细粒度数据响应机制来进行高效的状态更新。

安装(其余安装方式在官网)npminstallvuex--save

配置

在项目的根目录下新增一个store文件夹在文件夹内创建index.js此时的项目src文件夹内应当为:

│App.vue(跟文件)│main.js(入口文件)│├─assets(图片)│logo.png│├─components(组件)│HelloWorld.vue│├─router(接口)│index.js│└─store(vuex仓库)index.js

初始化store下的index.js中的vuex

importVuefrom'vue'importVuexfrom'vuex'//引入vuex//挂载VuexVue.use(Vuex)//创建VueX对象conststore=newVuex.Store({state:{//state属性存放的键值对就是所要管理的状态name:'helloVueX'}})exportdefaultstore//暴露抛出

将store挂载到当前项目的Vue实例中main.js

importVuefrom'vue'importAppfrom'./App'importrouterfrom'./router'importstorefrom'./store'Vue.config.productionTip=false/*eslint-disableno-new*/newVue({el:'#app',router,store,//store:store和router一样,将我们创建的Vuex实例挂载到这个vue实例中render:h=>h(App)})

使用:

在各个组件中使用:{{$store.state.name}}$store指向Vuex对象

在组件的方法中使用:this.$store.state.namethis指向Vue$store指向Vuex

methods:{add(){console.log(this.$store.state.name)}},注意,请不要在此处更改state中的状态的值,后文中将会说明

getters:{nameInfo(state){return"姓名:"+state.name},fullInfo(state,getters){returngetters.nameInfo+'年龄:'+state.age}}组件中调用:

{{$store.getters.nameInfo}}

在组件的methods中调用:

this.$store.getters.fullInfo

我们在两秒中后执行2节中的edit`方法

由于setTimeout是异步操作,所以需要使用actions

actions:{aEdit(context,payload){setTimeout(()=>{context.commit('edit',payload)},2000)}}在组件中调用:

this.$store.dispatch('aEdit',{age:15})改进:

由于是异步操作,所以我们可以为我们的异步操作封装为一个Promise对象

aEdit(context,payload){returnnewPromise((resolve,reject)=>{setTimeout(()=>{context.commit('edit',payload)resolve()},2000)})}

如果把整个store都放在index.js中是不合理的,所以需要拆分。比较合适的目录格式如下:

store:.│actions.js│getters.js│index.js│mutations.js│mutations_type.js##该项为存放mutaions方法常量的文件,按需要可加入│└─modulesAstore.js对应的内容存放在对应的文件中,和以前一样,在index.js中存放并导出store。state中的数据尽量放在index.js中。而modules中的Astore局部模块状态如果多的话也可以进行细分。

修改一:build>utils.js(修改publicPath:"../../",这样写是处理打包后找不到静态文件的问题)

//ExtractCSSwhenthatoptionisspecified//(whichisthecaseduringproductionbuild)if(options.extract){returnExtractTextPlugin.extract({use:loaders,fallback:'vue-style-loader',publicPath:'../../'//这里是要添加的代码})}else{return['vue-style-loader'].concat(loaders)}

修改二:config>index.js(修改assetsPublicPath:'./',修改目的是为了解决js找不到的问题)

build:{//Templateforindex.htmlindex:path.resolve(__dirname,'../dist/index.html'),//PathsassetsRoot:path.resolve(__dirname,'../dist'),assetsSubDirectory:'static',assetsPublicPath:'./',//在这里修改/***SourceMaps*/productionSourceMap:true,

然后执行npmrunbuild打包

打包后的文件为:dist

打包后打开阿帕奇服务器,将包放进服务器文件夹下的WWW目录中,服务器地址为localhost页面地址为localhost/包名

在打包好的文件中如果页面出不来,将router(路由)中的index.js的mode从history改为hash(去除链接中的#用mode:'history')

如果打包好的页面中无法跳转,检查跳转用的是否为Vue规定的跳转方法router-link:to或者this.$router.push("");不能用a标签跳转

购物车功能

安装

npmistallelement-ui--save在main.js写入以下内容

importVuefrom'vue';importElementUIfrom'element-ui';import'element-ui/lib/theme-chalk/index.css';importAppfrom'./App.vue';Vue.use(ElementUI);newVue({el:'#app',render:h=>h(App)});注意:样式文件需要单独引入。

全局配置:在引入Element时,可以传入一个全局配置对象。该对象目前支持size与zIndex字段。size用于改变组件的默认尺寸,zIndex设置弹框的初始z-index(默认值:2000)。按照引入Element的方式,具体操作如下:

importVuefrom'vue';importElementfrom'element-ui';Vue.use(Element,{size:'small',zIndex:3000});

element-ui改变样式时在css中加/deep/

有时在vue中请求地址为线上地址的img时会遇到img无法显示的问题

在src中这样写:require("地址")

注意:如果你绘制出来的图像是扭曲的,尝试用width和height属性为明确规定宽高,而不是使用CSS。

constcanvas=document.getElementById('canvas');//获取canvas元素constctx=canvas.getContext('2d');//获取这个元素的context——图像稍后将在此被渲染,接口完成实际的绘制ctx.fillStyle='green';//fillStyle属性让长方形变成绿色ctx.fillRect(10,10,150,100);//fillRect()方法将它的左上角放在(10,10),把它的大小设置成宽150高100。

rect(x,y,width,height)绘制一个左上角坐标为(x,y),宽高为width以及height的矩形。

.fillRect(x,y,width,height)绘制一个填充的矩形.strokeRect(x,y,width,height)绘制一个矩形的边框.clearRect(x,y,width,height)清除指定矩形区域,让清除部分完全透明。.fillStyle=''填充颜色color、rgb、rgba、#000

以上的函数绘制之后会马上显现在canvas上,即时生效。不同于路径函数

functiondraw(){varcanvas=document.getElementById('canvas');if(canvas.getContext){varctx=canvas.getContext('2d');ctx.fillRect(25,25,100,100);ctx.clearRect(45,45,60,60);ctx.strokeRect(50,50,50,50);}}

.clearRect(x,y,width,height)清除指定矩形区域,让清除部分完全透明。

beginPath()新建一条路径,生成之后,图形绘制命令被指向到路径上生成路径。closePath()闭合路径之后图形绘制命令又重新指向到上下文中。stroke()通过线条来绘制图形轮廓。fill()通过填充路径的内容区域生成实心的图形。

注意:当前路径为空,即调用beginPath()之后,或者canvas刚建的时候,第一条路径构造命令通常被视为是moveTo(),无论实际上是什么。出于这个原因,你几乎总是要在设置路径之后专门指定你的起始位置

注意:当你调用fill()函数时,所有没有闭合的形状都会自动闭合,所以你不需要调用closePath()函数。但是调用stroke()时不会自动闭合

绘制一个三角形

varcanvas=document.getElementById('canvas');varctx=canvas.getContext('2d');ctx.beginPath();//新建一条路径ctx.moveTo(75,50);//将笔触移动到指定的坐标x以及y上。ctx.lineTo(100,75);ctx.lineTo(100,25);ctx.fill();

moveTo(x,y)将笔触移动到指定的坐标x以及y上。当canvas初始化或者beginPath()调用后,你通常会使用moveTo()函数设置起点。我们也能够使用moveTo()绘制一些不连续的路径。

lineTo(x,y)绘制一条从当前位置到指定x以及y位置的直线。x、y,代表坐标系中直线结束的点。之前路径的结束点就是接下来的开始点、也可以通过moveTo()函数改变。

.lineWidth=设置线宽.lineCap=type设置设置线条末端样式。(默认buttround半圆square方).lineJoin=type设定线条与线条间接合处的样式。(默认round圆角belve不变miter延申).miterLimit=value限制当两条线相交时交接处最大长度;所谓交接处长度(斜接长度)是指线条交接处内角顶点到外角顶点的长度。.getLineDash()返回一个包含当前虚线样式,长度为非负偶数的数组。.setLineDash(segments)设置当前虚线样式。lineDashOffset=value设置虚线样式的起始偏移量。

arc(x,y,radius,startAngle,endAngle,anticlockwise)画一个以(x,y)为圆心的以radius为半径的圆弧(圆),从startAngle(以X轴为基准的弧度)开始到endAngle(以X轴为基准的弧度)结束,按照anticlockwise给定的方向(默认为顺时针false)来生成。

方向默认为顺时针(false)

弧度=(Math.PI/180)*角度

注意:arc()函数中表示角的单位是弧度,不是角度。角度与弧度的js表达式:弧度=(Math.PI/180)*角度。

//绘制了一个圆弧ctx.beginPath();//ctx.moveTo(0,0);//若与起点连接可以打开这个letx=(Math.PI/180)*30//起始为30度lety=(Math.PI/180)*60//结束为60度ctx.arc(0,0,50,x,y,false);//ctx.closePath();//若闭合则打开这个ctx.stroke();//以线条绘制轮廓(不自动闭合)

quadraticCurveTo(cp1x,cp1y,x,y)绘制二次贝塞尔曲线,cp1x,cp1y为一个控制点,x,y为结束点。bezierCurveTo(cp1x,cp1y,cp2x,cp2y,x,y)绘制三次贝塞尔曲线,cp1x,cp1y为控制点一,cp2x,cp2y为控制点二,x,y为结束点。

stroke()通过线条来绘制图形轮廓。(不自动闭合,需要调用方法闭合)fill()通过填充路径的内容区域生成实心的图形。(自动闭合)

注意:调用fill()函数时,所有没有闭合的形状都会自动闭合,所以你不需要调用closePath()函数。但是调用stroke()时不会自动闭合

.fillStyle=''填充颜色color、rgb、rgba、#000strokeStyle=color设置图形轮廓的颜色。

注意:一旦您设置了strokeStyle或者fillStyle的值,那么这个新值就会成为新绘制的图形的默认值。如果你要给每个图形上不同的颜色,你需要重新设置fillStyle或strokeStyle的值。

globalAlpha=0设置透明度0-1

就好像一般的绘图软件一样,我们可以用线性或者径向的渐变来填充或描边。我们用下面的方法新建一个canvasGradient对象,并且赋给图形的fillStyle或strokeStyle属性。

createLinearGradient(x1,y1,x2,y2)方法接受4个参数,表示渐变的起点(x1,y1)与终点(x2,y2)。createRadialGradient(x1,y1,r1,x2,y2,r2)方法接受6个参数,前三个定义一个以(x1,y1)为原点,半径为r1的圆,后三个参数则定义另一个以(x2,y2)为原点,半径为r2的圆。

varlineargradient=ctx.createLinearGradient(0,0,150,150);varradialgradient=ctx.createRadialGradient(75,75,0,75,75,100);创建出canvasGradient对象后,我们就可以用addColorStop方法给它上色了。

.addColorStop(position,color)方法接受2个参数,position参数必须是一个0.0与1.0之间的数值,表示渐变中颜色所在的相对位置。例如,0.5表示颜色会出现在正中间。

shadowOffsetX=floatX和Y用来设定阴影在X和Y轴的延伸距离shadowBlur=float用于设定阴影的模糊程度,其数值并不跟像素数量挂钩,也不受变换矩阵的影响,默认为0。shadowColor=color是标准的CSS颜色值,用于设定阴影颜色效果,默认是全透明的黑色。

文字阴影的例子:

varctx=document.getElementById('canvas').getContext('2d');ctx.shadowOffsetX=2;ctx.shadowOffsetY=2;ctx.shadowBlur=2;ctx.shadowColor="rgba(0,0,0,0.5)";ctx.font="20pxTimesNewRoman";ctx.fillStyle="Black";ctx.fillText("SampleString",5,30);

创建文本fillText(text,x,y[,maxWidth\])在指定的(x,y)位置填充指定的文本,绘制的最大宽度是可选的.strokeText(text,x,y[,maxWidth\])在指定的(x,y)位置绘制文本边框,绘制的最大宽度是可选的.

ctx.font="48pxserif";ctx.textBaseline="hanging";ctx.strokeText("Helloworld",0,100);

varctx=document.getElementById('canvas').getContext('2d');vartext=ctx.measureText("foo");//TextMetricsobjecttext.width;//16;

Path2D()会返回一个新初始化的Path2D对象(可能将某一个路径作为变量——创建一个它的副本,或者将一个包含SVGpath数据的字符串作为变量)。

newPath2D();//空的Path对象newPath2D(path);//克隆Path对象newPath2D(d);//从SVG建立Path对象创建Path2D对象

varcanvas=document.getElementById('canvas');varctx=canvas.getContext('2d');varrectangle=newPath2D();rectangle.rect(10,10,50,50);varcircle=newPath2D();circle.moveTo(125,35);circle.arc(100,35,25,0,2*Math.PI);ctx.stroke(rectangle);ctx.fill(circle);

文件操作:gitpull//将云端的文件从新下载到本地gitclone项目地址//将仓库文件夹克隆到本地mkdir文件名//创建文件夹cd文件名//进入文件cd..///返回上一级gitpull--rebaseoriginmaster//同步云端仓库和自己的仓库

上传操作:gitadd.//选择当前文件夹内的所有文件gitcommit-m"firstcommit"//使文件上传到缓存区,备注(firstcommit)//上传如果报错在这一步后加一步同步gitpush-uoriginmaster//上传到git中

当不在master分支的时候gitreset--hardhead//回退版本信息

gitpull--rebaseoriginmaster//合并分支

git出现(master|REBASE1/1)

gitrebase--abort//取消合并gitrebase--continue//继续执行

使用npm全局安装yarn

$npminstall-gyarn//使用npm安装yarn$yarn--version//检查是否安装成功$yarnconfiggetregistry//检查安装配置

yarn

npminit===yarninitnpminstall===yarn或者yarninstallnpminstalltaco--save===yarnaddtaconpmuninstalltaco--save===yarnremovetaconpminstalltaco--save-dev===yarnaddtaco--devnpmupdate--save===yarnupgradenpminstalltaco@latest--save===yarnaddtaconpminstalltaco--global===yarnglobaladdtaconpminit--yes/-y===yarninit--yes/-ynpmlink===yarnlinknpmoutdated===yarnoutdatednpmpublish===yarnpublishnpmrun===yarnrunnpmcacheclean===yarncachecleannpmlogin===yarnloginnpmtest===yarntest

修改gitbash样式找到安装git的文件夹,进去之后,右击git-bash.exe选择以管理员身份运行

app.json为整体的配置文件

pages为所有页面的地址,(创建新页面也直接在此创建即可)。

"pages":["pages/index/index","pages/fenlei/fenlei","pages/gouwuche/gouwuche","pages/me/me"],

window为所有页面的配置属性

"window":{"backgroundTextStyle":"light","navigationBarBackgroundColor":"#AB956D","backgroundColor":"#eeeeee","navigationBarTitleText":"李硕的小程序","navigationBarTextStyle":"black"},

tabBar为上部(下部)导航栏,list为导航栏的内容(最少两个最多五个),具体参考文档

"tabBar":{"list":[//为导航栏页数{"pagePath":"pages/index/index",//为导航地址"text":"营养早餐",//导航名"iconPath":"./imgs/12.png",//点击前的图片"selectedIconPath":"./imgs/11.png"//点击后的图片},{"pagePath":"pages/fenlei/fenlei","text":"分类","iconPath":"./imgs/22.png","selectedIconPath":"./imgs/21.png"}],"selectedColor":"#AB956D",//点击前文字的颜色"backgroundColor":"#fff"//点击后文字的颜色},

标签相当于div标签相当于span标签相当于img标签相当于template并不实际渲染在页面上

wxml就像vue采取数据绑定

wx:for进行列表渲染使用wx:key=''绑定key使用wx:for-item=""将遍历后的item改变为任意值使用wx:for-index=""将遍历后的index改变为任意值

{{item}}注意:当wx:for的值为字符串时,会解析为字符串的遍历wx:for="array"注意:花括号和引号之间如果有空格,将最终被解析成为字符串wx:for="{{[1,2,3]}}"

可滑动的view

wxml部分

111222333js部分

Page({data:{news:[123],toView:'bing',boxIndex:0,category:[{name:'烙饼',id:'bing'},{name:'粥类',id:'zhou'},{name:'面点',id:'mian'}],},bhclick(e){//console.log(e.currentTarget)this.setData({toView:e.currentTarget.id,boxIndex:e.currentTarget.dataset.index})},})

bindscrolltoupper——滚动到顶部/左边bindscrolltolower——滚动到底部/右边bindscroll——滚动的过程

upper:function(event){console.log("滚动到顶部");},lower:function(event){console.log("滚动到底部");},scroll:function(event){console.log("正在滚动");}

this.data只能改变数据不能实时渲染到页面上使用setData()方法实时改变

Page({data:{name:"李硕"},change(){this.setData({name:"小明"//实时改变})this.name="小明"//只改变数据,页面不变}})

tableBar中的页面不能被跳转只能跳转tableBar中没有的页面

//保留当前页面,跳转到应用内的某个页面,使用wx.navigateBack可以返回到原页面。wx.navigateTo({url:'page/home/homeuser_id=111'})//关闭当前页面,跳转到应用内的某个页面。wx.redirectTo({url:'page/home/homeuser_id=111'})//跳转到tabBar页面(在app.json中注册过的tabBar页面),同时关闭其他非tabBar页面。wx.switchTab({url:'page/index/index'})//关闭所有页面,打开到应用内的某个页面。wx.reLaunch({url:'page/home/homeuser_id=111'})

事件绑定:bind绑定;catch绑定;(能阻止事件冒泡)

事件类别:tap:点击事件;longtap:长按事件;touchstart:触摸开始;touchend:触摸结束;touchcansce:取消触摸;

例:绑定点击事件:

打印一个事件

btnclick:(e){console.log(e)}其中:currentTarget:是我们点击的这个view;target:是我们目标的这个view;可以给这个view加一个id:在冒泡的事件中:currentTarget和target是不一致的;currentTarget是我们绑定了的组件,target是发生事件的组件;currentTarget里面的dataset是没有数据的。这个是为了方便我们添加我们自定义的属性:通过点击事件,可以获取到这个空间的属性,从而可以方便我们的逻辑。

使用自定义属性在单击事件打印事件对象e就可以拿到自定义的属性值,可以用来传参

{{item.name}}

{{boxIndex==index'on':''}}

boxindex是否等于index若等于添加类名on若不等于添加类名''(空)

class="box{{boxIndex==index'on':''}}"

onLoad:function(options){//生命周期函数constapp=getApp()//获取app.jsthis.setData({//将app.js的数据赋给本js的数据goods:app.data.goods})},

方法一:利用跳转url传值

页面1:跳转传参

tz(e){wx.navigateTo({//跳转url:'../xq/xqname='+goodname,})},

液面2:接收参数

onLoad:function(options){//生命周期函数--监听页面加载console.log(options)},

方法二:利用app.js传值

举例:极点日历

ios端不支持日期格式中出现-使用其他字符代替(/)

加上//#ifdefMP-WEIXIN这个代码的意思是只在小程序中执行这串代码H5和APP中的代码,//#endif这个代码的意思是就是除了小程序其他的平台都执行这个代码

搭建viet+vue3项目

yarncreateviteapp_name--templatevue//安装yarn+vue3项目yarninstall//安装项目依赖yarndev//启动项目搭建vue3项目

$npmcreatevite@latest$yarncreatevite

(vscodevue2插件:Vutervue3插件VeuLanguageFeatures(Volar))

创建响应式变量

import{reactive,ref}from"@vue/runtime-core";//引入refleta=ref("");//使用ref创建响应式变量a.value=123//响应式变量赋值console.log(a.value)//响应式变量取值(注意,在{{}}中不用加value)letb=reactive({//使用ractive创建响应式对象lon:"",lat:"",height:"",});

父组件

importDetailsDialogBoxfrom"@/....../.vue";//引入子组件letPositionInfo_=reactive({})//传递的对象varisshow=ref(false);letclose=function(){//传递的方法isshow.value=false;};子组件

//获得父组件传递的当地信息letprops=defineProps({PositionInfo_:Object});//获取值需要在后标注值的类型//取值console.log(props.PositionInfo_.value)//获取父组件传递的方法constclose=()=>{emit("close");};watch(//监听数据,数据有变化立即执行函数()=>props,//监听props(props,prevProps)=>{//操作//props为新数据//prevProps为旧数据},{deep:true}//深度监听);

THE END
1.大小单双赚钱平台APP下载?2024-11-29 13:38:19?3分钟前大小单双赚钱平台-App下载支持:64/128bit位系统类型:开yun体育官网入口登录APP官方网站-App下载(2024全站)最新版本IOS/安卓通用版V.3.91.96.49(安全平台)登录入口现在下载,新用户还送新人礼包《大小单双赚钱平台》在竞争激烈的NBA西部联盟中,休斯顿火http://www.share.mxcxj.cn/cxB/detail/ESSFGvG.html
2.大小单双赚钱平台APP下载最新官方版下载Welcome老板大小单双赚钱平台APP下载支持:64/128bit位系统类型:大小单双赚钱平台官方网站-App下载(2024全站)最新版本IOS/安卓通用版V.19.526.144支持winall/win7/win10/win11(安全平台)官方入口|登录【下载次数677437】随着国际局势面临着更多不确定性,中http://www.m.share.ygxqw.cn/Fhu/detail/xouNyCm.html
3.大小单双赚钱平台APP下载? ωειcοmε ?大小单双赚钱平台,欢迎使用:大小单双赚钱平台,大小单双赚钱平台-App官方下载(2024全站)最新版本IOS/安卓通用版V1.6.3,系统:32/64操作系统;语言:中文|English;支持平台:安卓|IOS|PC;下载次数:424654;官方网址:http://www.slushark.cn。现在下载APP,新用户还赠送新人大礼包http://www.wap.share.slushark.cn/OoU/detail/iuQkQX.html
4.大小单双赚钱平台APP下载4.大小单双赚钱平台官网-APP下载支持:winall/win7/win10/win11系统类型:大小单双赚钱平台下载(2024全站)最新版本IOS/安卓官方入口V9.42.26.77(安全平台)登录入口《大小单双赚钱平台》 本文大概919字,阅读大概需要3分钟风暴体育讯 北京时间昨天,国足在世预赛亚洲区12强赛关键战中以2-3输给了沙特队,比赛http://www.share.hfsgx.com/csi/detail/wab98i.html
5.大小单双赚钱平台手机版标签:大小单双赚钱平台V9.6.2大小单双赚钱平台V1.1.3大小单双赚钱平台V8.6.4 详情 介绍 猜你喜欢 相关版本 截图内容详情 ?2024-11-24 17:39「百科/秒懂百科」【】支持:32/64bit系统类型:(官方)官方网站IOS/Android通用版/手机APP(2024APP下载)《》 葫芦侠3楼破解游戏盒子 最新版v4.1.http://www.glz.life/UvZ/detail/kdrgGn.html
6.大小单双赚钱平台APP下载《大小单双赚钱平台》 大小单双赚钱平台游戏介绍 2024-11-28 16:05:07「百科/秒懂百科」【 大小单双赚钱平台】支持:32/64bi系统类型:大小单双赚钱平台(官方)官方网站IOS/Android通用版/手机APP(2024APP下载)《大小单双赚钱平台》《九游武娘别传》是完美结合模仿运营与战略卡牌的娘化武侠网游。游戏中http://www.share.sbymsm.cn/mjI/detail/XUfQKzJo.html
7.大小单双赚钱平台(综合)官方网站IOS/安卓/手机APP最新版下载普通下载 安全下载 需下载豌豆荚APP 扫码打开当前页下载 小编点评 大小单双赚钱平台是一家备受瞩目的体育平台,提供丰富多样的体育赛事和刺激的游戏体验。如果您想加入大小单双赚钱平台的大家庭,参与其中的乐趣,本文将为您详细介绍大小单双赚钱平台的注册流程,让您轻松开启精彩的体育之旅。 第一步:访问“大小单双赚钱http://www.dyhjw.com/wardWYDV/
8.我在网上参加了一个彩票控app.里面有一款买大小单双的游戏,我输了我在网上参加了一个彩票控app.里面有一款买大小单双的游戏,我输了6万多元。请问报警的话能追回吗?我要承担法律责任吗? 报告编号:No.20200315*** 【问题分析】您好,您所提出的是关于 【解决方案】***【具体操作】*** 完整报告 关于我在网上参加了一个彩票控app.里面有一款买大小单双的游戏,我输了6万https://m.66law.cn/question/27646212.aspx
9.实践GoogleI/O应用是如何适配大尺寸屏幕UI的?本文介绍了Google I/O应用如何适配大尺寸屏幕,包括响应式导航、单双窗格布局的转换、资源限定符的使用,以及如何处理屏幕尺寸变化带来的内容转换。应用利用Navigation rail优化横屏导航,使用SlidingPaneLayout处理单双窗格布局,针对不同屏幕尺寸调整内容显示,以提供更好的用户体验。 https://blog.csdn.net/jILRvRTrc/article/details/121527377
10.花小钱办大事篇四:智能家居DIY老司机手把手带你搞定智能插座智能单双火墙壁开关 开关的介绍 现在的装修公司,不论大小,基本上无论你关照与否,基本上布线时都是不会留零线,这就导致了基本上家里的墙壁开关都是没有零线的单火线路,单火线路这几年随着智能家居产品的普及,无法使用零火智能开关,导致智能家居改造成本上升,变相的降低了智能家居普及的速度,对于单火线路,各家也陆http://www.360doc.com/content/19/0303/09/58230995_818751089.shtml
11.XiaomiSU7,Xiaomi14Ultra,小米澎湃OS,小米徕卡影像大赛让全球每个人都能享受科技带来的美好生活https://www.mi.com/
12.iPhone7PlusiPhone 7 Plus是美国苹果公司于2016年9月8日(北京时间)在2016苹果秋季新品发布会上发布的手机。iPhone 7 Plus起售价为6388元。iPhone 7 Plus有银色、金色、玫瑰金、黑色、亮黑和红色等配色版本。屏幕大小5.5英寸,拥有双1200万像素摄像头,虚化效果自然,亮度提升了25%。扬声器采用上下立体声的扬声器,取消了3.https://baike.baidu.com/item/iPhone%207%20Plus/15595891
13.降龙统计七星“关羽”“张飞”“赵云”杀码全对!连对七星APP2759期精选数据 ?七星二定 头尾8组:09/X/X/1459(128期未开) 中肚10组:X/45689/27/X(87期未开) 中肚15组:X/01236/012/X(57期未开) 16组:X/2347/0247/X(69期未开) 单双大小 X/双/X/单(X/02468/X/13579)--18 期未出 https://news.sohu.com/a/565770377_121117475
14.商业篇:单双与大小平台app经验单双与大小平台app《fc 002 點V IP》《筘3.476-291》罔《fc 19點V IP》【财丨运丨当丨头】?【好丨运丨连丨连】【共丨创丨辉丨煌】如果你是刚刚玩,我来教教你,如果你已经玩很久了,却不稳,我来拉拉你,如果你已经遍体鳞伤,我来帮帮你。 用我们真诚的微笑,换取您对我们的满意。用我们真诚的微笑,换取https://www.bilibili.com/read/cv32381414/