HTML5 现在已经不是 SGML 的子集;主要是关于图像;位置;存储;多任务等功能的增加。
绘画 canvas;用于媒介回放的 video 和 audio 元素;本地离线存储 localStorage 长期存储数据;浏览器关闭后数据不丢失;sessionStorage 的数据在浏览器关闭后自动删除;语意化更好的内容元素;比如 article、footer、header、nav、section;表单控件;calendar、date、time、email、url、search;新的技术webworker, websocket, Geolocation;IE8/IE7/IE6支持通过document.createElement方法产生的标签;
可以利用这一特性让这些浏览器支持HTML5新标签;浏览器支持新标签后;还需要添加标签默认的样式。当然也可以直接使用成熟的框架、比如html5shim;<header> 表示页面中一个内容区块或整个页面的标题。
<section> 页面中的一个内容区块;如章节、页眉、页脚或页面的其他地方;可以和h1、h2……元素结合起来使用;表示文档结构。
<article> 表示页面中一块与上下文不相关的独立内容;如一篇文章。
<aside> 表示<article>标签内容之外的;与<article>标签内容相关的辅助信息。
<hgroup> 表示对整个页面或页面中的一个内容区块的标题进行组合。
<figure> 表示一段独立的流内容;一般表示文档主体流内容中的一个独立单元。
<figcaption> 定义<figure>标签的标题。
<nav> 表示页面中导航链接的部分。
<footer> 表示整个页面或页面中一个内容区块的脚注。一般来说;它会包含创作者的姓名、创作日期及联系方式。
</!doctype>
严格模式的排版和 JS 运作模式是 以该浏览器支持的最高标准运行。
在混杂模式中;页面以宽松的向后兼容的方式显示。模拟老式浏览器的行为以防止站点无法工作。
.square{
width:0;
height:0;
margin:0 auto;
border:6px solid transparent;
border-top: 6px solid red;
}
通过媒体查询可以为不同大小和尺寸的媒体定义不同的css;适合相应的设备显示;即响应式布局
;media screen and (min-width: 400px) and (max-width: 700px) { … }
;media handheld and (min-width: 20em), screen and (min-width: 20em) { … }
以数字、字母、下划线、&字符组成;不能以字数开;;
不使用关键字、保留字;
建议命名见名知义;小驼峰命名方式。
宏观任务;macro task;;由宿主;node、浏览器;发起的任务;如setTimeout、setInterval、setImmediate、I/O
微观任务;micro task;;由js引擎发起的任务;如process.nextTick、promise、mutationObserver
执行顺序;同步任务——>微观任务——>宏观任务
typeof; 是一个操作符;其右侧跟一个一元表达式;并返回这个表达式的数据类型。返回的结果用该类型的字符串;包括以下 7 种;number、boolean、symbol、string、object、undefined、function 等。
**instanceof;**是用来判断 A 是否为 B 的实例;表达式为;A instanceof B;如果 A 是 B 的实例;则返回 true,否则返回 false。 这里需要注意的是;instanceof 检测的是原型。
**toString;**是 Object 的原型方法;调用该方法;默认返回当前对象的 [[Class]] 。这是一个内部属性;Object.prototype.toString.call(‘传判断数据’)
null;访问一个不存在对象返回的值;表示空对象
undefined;访问一个声明完没有赋值的变量返回的值;表示空变量
console.log(a,b) //11,10
== 判断值相等;判断的过程中会隐式转换为number类型进行比较 “10”==10 true
=== 值、数据类型全等;严格相等;不会发生类型转换;“10”===10 false
document.write; 操作body的内容不会覆盖之前已经存在的body中的内容;document.write添加的内容会叠加
innerHTML; 操作所有闭合标签的内容 会覆盖之前的所有内容
this存储任何地方;不同环境代表不同的含义;取决于调用时的环境。
A.事件处理函数中的this—触发事件的对象 document.onclick = function(){ alert;this;}
B.普通函数中的this—window function sum;;{ alert(this)} sum()
var x = 1,
y = z = 0;
function add(n) {
n = n ; 1;
};
y = add(x);
function add(n) {
n = n ; 3;
};
z = add(x);
console.log(x, y, z); //结果;1,undfined,undfined
浏览器解析js代码至少会经过两个过程;预解析和逐步执行
预解析;找东西var;function;如果找到var;会在内存中存储变量没有值;function则会存储整个函数
逐步执行;逐行执行代码 console.log(a); //undefined
//函数声明;
function fn(){
};
//函数表达式:
var fn = function(){
};
Js中两种变量;全局变量和局部变量
全局变量;函数外声明;在任何地方都能被修改和访问;会一直存储在内存中
局部变量;函数内声明;只能在函数内部使用;除了函数{}就会被销毁
setInterval;间歇执行;setTimeout;延迟执行
setInterval(函数;时间) 语法;setInterval(function(){},1000); 时间单位ms;每隔特定时间执行多次函数;一般用于倒计时;轮播图等
setTimeout(函数;时间) 语法;setTimeout(function(){},1000); 时间单位ms;隔特定时间执行一次函数; 一般用于广告;广告弹出等
原生对象;Object;Function ,Array, String, Boolean, Number,RegExp,Date,Error
内置对象;Global(全局 window,documet), Math
宿主对象;DOM BOM
全局对象;window
pop();从数组尾部删除;
push();从数组尾部增加;
unshift();从数组头部增加;
shift();从数组头部删除;
forEach();没有返回值;只是针对每个元素调用func 。循环数组。和for的用法一样的。
map();返回一个新的Array;每个元素为调用func的结果。新数组的长度和原来的是一样的;他只不过是逐一对原来数据里的每个元素进行操作。
filter();返回一个符合func条件的元素数组。筛选条件;把数组符合条件的放在新的数组里面返回。新数组和原来的数组长度不一定一样。
every();返回一个boolean;判断每个元素是否符合func条件。数组里面所有的元素都符合才返回true。
some();返回一个boolean;判断是否有元素是否符合func条件。数组里面所有的元素有一个符合条件就返回true。
var arr = new Array(100);
//方法1
[...arr.keys()];
//方法二
Array.from(arr.keys());
//方法三
Array.from({length: 100});
// 方法四 借助string
var arr1 = new Array(101);
var str = arr1.join(;1,;);
str = str.replace(/(1,)/g, function ($0, $1, index) {
var start = ;; ; Math.ceil(index/2);
if(index < str.length - 2) {
start ;= ;,;
}
return start;
});
return str.split(;,;);
// 方法五;函数式;参考网络;
function reduce(arr, val) {
if(Object.prototype.toString.apply(val)){
return;
}
if(val >= 100) {
return arr;
}
arr.push(val);
return reduce(arr, val;1);
}
var res = reduce([], 0)
offsetWidth;占位宽;内容有效宽 ; padding;填白;;border;边框;
clientWidth;可视宽;内容有效宽 ; padding;填白;
scrollTop;页面被卷去的高
break: 结束循环;本次后面的代码也不再执行
continue;结束本次循环;本次后面的代码也不再执行。下次的循环继续
ev.stopPropagation ? ev.stopPropagation() : ev.cancelBubble = true;
return false
var ev = ev || window.event
document.documentElement.clientWidth || document.body.clientWidth
Var target = ev.srcElement||ev.target
标签.事件;如果给同一个元素添加同一个事件;后面的会覆盖前面
事件绑定;可以给同一个元素添加同一个事件;不会被覆盖
事件捕获阶段;当事件发生的时候;将事件从window依次往子元素传递
确定目标阶段;确定事件目标
事件冒泡阶段;事件目标开始处理事件;处理完以后会将事件依次传递给父元素;一直到window
事件都是在事件冒泡处理;ie只有冒泡
ul.onclick = function (ev) {
var ev = ev || event; //做事件的兼容
var target = ev.target || ev.srcElement; //做事件委托的兼容
if (target.nodeName === ;li;) {
target.style.backgroundColor = ;red;;
}
}
for(var i=0;i<li.length;i;;){
li[i].oncnlick=function(){
}
}
function (str) {
var re = /(^s*)|(s*$)/g;
return str.replace(re, ;;);
}
var str = “ fdf er re545 6565 2fdfd ”
var reg = /s/g;
consloe.log(str.replace(reg,;;));
var str=;a531791740941fgs3124;
var reg = /^[a-z]w{4,19}$/ig;
if (reg.test(str)) {
console.log(;是;)
} else {
console.log(;否;)
}
//1.字面量创建 缺点;代码冗余;单个对象创建
var obj = {
name:;web;,
eat:function(){}
}
//2.实例创建 缺点;代码冗余;适合单个对象创建
var obj = new Object();
obj.name = ;web;;
obj.eat = function(){}
//3.工厂模式创建 缺点;识别不明确
function createObj(name){
var obj = new Object();
obj.name = name;
obj.eat = function(){}
return obj
}
createObj(“web”);
//4.构造函数创建 缺点;浪费内存
function Student(name){
//new Object
this.name = name;
this.eat = function(){}
}
new Student(name)
//5.原型创建 缺点;不能传参
//原型对象;prototype ;构造函数中;共享的一块区域
//原型属性;__proto__,实例对象中;指向原型对象
function Student(){}
Student.prototype.name = ;web;;
Student.prototype.eat = function(){}
new Student();
//6.混合创建;构造函数(可变的);原型(共享;不变的)
function Student(name){
this.name = name;
}
Student.prototype.eat = function(){
}
// 父类
function Person(name, age) {
this.name = name;
this.age = age;
this.arr = [1, 2, 3];
}
Person.prototype.showName = function () {
console.log(this.name);
}
Person.prototype.showAge = function () {
console.log(this.age);
}
//1、原型链继承
function ChildPerson() { } // 子类
ChildPerson.prototype = new Person(;小王;, 3); // 原型继承;将父类的实例赋给子类的原型;用一句话实现继承;
var c1 = new ChildPerson();
console.log(c1);
c1.arr.
push(4);
console.log(c1.arr);
var c2 = new ChildPerson();
console.log(c2.arr);
console.log(c2.constructor); // 问题;this指向了Person;应该指向ChildPerson;
//2、对象冒充继承
function ChildPerson(name, age, sex) { //子类
Person.call(this, name, age);
this.sex = sex;
}
var c1 = new ChildPerson(;小王;, 3, ;男;);
console.log(c1);
c1.arr.push(4);
console.log(c1.arr);
var c2 = new ChildPerson(;小张;, 5, ;男;);
console.log(c2.arr);
//3、组合继承 ;对象冒充继承 ; 原型链继承;
function ChildPerson(name, age, sex) { //子类
Person.call(this, name, age); // 对象冒充继承
this.sex = sex;
}
ChildPerson.prototype = new Person(); // 原型链继承
var c1 = new ChildPerson(;小王;, 3, ;男;);
// 存在的问题
// 1)同一个属性;在原型链中会存在多个
// 2)父类的构造函数;调用了两次
console.log(c1);
console.log(c1.name);
c1.showName();
//4、寄生组合继承 通过新创变量生创存在空间;(对象冒充继承 ; 原型链继承)
function ChildPerson(name, age, sex) { // 子类
Person.call(this, name, age); // 对象冒充继承
this.sex = sex;
}
//寄生组合方法封装
function inherits(parent, child) {
var F = function () { };
F.prototype = parent.prototype;
child.prototype = new F();
child.prototype.constructor = child;
}
inherits(Person, ChildPerson);
// 子类继承添加方法
ChildPerson.prototype.showSex = function () {
console.log(this.sex);
}
var c1 = new ChildPerson(;小王;, 3, ;男;);
console.log(c1);
c1.showName()
原型;js每声明一个function;都有prototype原型;prototype原型是函数的一个默认属性;在函数的创建过程中由js编译器自动添加。也就是说;当生产一个function对象的时候;就有一个原型prototype。原型中存储对象共享的属性和方法。
原型链; 当你定义一个函数对象的时候;其内部就有这样一个链表关系。声明foo对象;自带了_proto_的属性;而这个属性指向了prototype;从而实现对象的扩展;例如继承等操作;
function Dog() {
this.wow = function () {
alert(;wow;);
}
this.yelp = function () {
this.wow();
}
}
function MadDog() {
Dog.call(this);
var _this = this;
this.yelp = function () {
setInterval(function () {
_this.wow();
}, 500);
}
}
闭包;就是能够读取其他函数内部变量的函数;函数里面套函数;内部函数访问外部函数变量;; 在本质上;闭包是将函数内部和函数外部连接起来的桥梁。
作用;闭包中使用的变量会一直存储在内存中;类似全局变量 ;避免全局污染;可以解决全局变量的问题。
function fun() {
var c = 10;
return function () {
console.log(c;;);
}
}
var fn = fun();
fn();//10 第一次调用;未运算
fn();//11
User = function () { }
User.prototype = {
id: ;;,
name: ;;,
getId: function () { return this.id },
setId: function () { this.id = id },
getName: function () { return this.name },
setName: function () { this.name = name }
}
//直接声明两个变量;这两个变量的作用域只是在这个函数体之中所以外界是不能访问的
var User = function () {
var id = ;id;;
var name = ;name;;
this.__proto__ = {
getId: function () {
return id;
},
setId: function (_id) {
id = _id;
},
getName: function () {
return name;
},
setName: function (_name) {
name = _name;
}
}
}
var u = new User();
u.setId(;007;);
u.setName(;tom;);
console.log(u.name, u.getName()); // undefined tom
创建XMLHttpRequest对象,也就是创建一个异步调用对象
创建一个新的HTTP请求,并指定该HTTP请求的方法、URL及验证信息.
设置响应HTTP请求状态变化的函数.
发送HTTP请求
获取异步调用返回的数据
使用JavaScript和DOM实现局部刷新
var xmlHttp = new XMLHttpRequest();
xmlHttp.open(;GET;,;demo.php;,;true;);
xmlHttp.send()
xmlHttp.onreadystatechange = function(){
if(xmlHttp.readyState === 4 & xmlHttp.status === 200){
}
}
function ajax(json) {
json.type = json.type ? json.type : ;get;;
json.async = json.async == false ? false : true;
json.contentType = json.contentType ? json.contentType : ;application/x-www-form-urlencoded;;
json.data = json.data ? json.data : ;;;
var ajax = new XMLHttpRequest();
// 判断是get还是post请求
if (json.type.toLowerCase() == ;post;) {
ajax.open(;post;, json.url, json.async);
ajax.setRequestHeader(;Content-type;, json.contentType ; ;;charset=utf-8;);
ajax.send(json.data);
} else {
ajax.open(;get;, json.url ; ;?; ; json.data, json.async);
ajax.send();
}
ajax.onreadystatechange = function () {
if (ajax.readyState == 4 && ajax.status == 200) {
json.success(ajax.response);
}
}
}
GET请求会将参数跟在URL后进行传递;而POST请求则是作为HTTP消息的实体内容发送给WEB服务器。当然在Ajax请求中;这种区别对用户是不可见的
GET传输数据容量小;12k;;不安全;POST传输数据内容大;更加安全; 当向服务器发生一些数据的时候选择post比较安全
2XX;表示成功 200
3XX;表示重定向 301;永久重定向;;302(临时重定向)
4XX;表示客户端错误 404;找不页面;
5XX;服务器错误 500;内部服务器错误;; 504;服务器超时;
在默认情况下;通过$.extend()合并操作不是递归的;而是浅拷贝;;
如果第一个对象的属性本身是一个对象或数组;那么它将完全用第二个对象相同的key重写一个属性。这些值不会被合并。然而;如果将true作为该函数的第一个参数;那么会在对象上进行递归的合并;深拷贝;。
浅拷贝;false 默认;;如果第二个参数对象有的属性第一个参数对象也有;那么不会进行相同参数内部的比较;直接将第一个对象的相同参数覆盖。
深拷贝;true;;如果第二个参数对象有的属性第一个参数对象也有;还要继续在这个相同的参数向下一层找;比较相同参数的对象中是否还有不一样的属性;如果有;将其继承到第一个对象;如果没有;则覆盖。
对于HTML元素本身就带有的固有属性;在处理时;使用prop方法。
对于HTML元素我们自己自定义的DOM属性;在处理时;使用attr方法。
$(“#chk1”).prop(“checked”) == false
$(“#chk2”).prop(“checked”) == true
如果上面使用attr方法;则会出现; $(“#chk1”).attr(“checked”) == undefined
setInterval(function () {
host = window.location.host
$.post(;http://; ; host ; ;/index.php/Article/cpMes/value/1;);
}, 5000);
比如;http://www.yyy.com/a.html 中嵌入了一个http://www.xxx.com/test.js
a.html 的编码是gbk或gb2312的。 而引入的js编码为utf-8的
那就需要在引入的时候 <script src=“http://www.xxx.com/test.js” charset=“utf-8”></script> 同理;如果你的页面是utf-8的;引入的js是gbk的;那么就需要加上charset=“gbk”
ajax不支持浏览器back按钮。
安全问题 AJAX暴露了与服务器交互的细节。
对搜索引擎的支持比较弱。
破坏了程序的异常机制。
get一般用来进行查询操作;url地址有长度限制;请求的参数都暴露在url地址当中;如果传递中文参数;需要自己进行编码操作;安全性较低。
post请求方式主要用来提交数据;没有数据长度的限制;提交的数据内容存在于http请求体中;数据不会暴漏在url地址中。
bind(type,[data],fn) 为每个匹配元素的特定事件绑定事件处理函数
$(;a;).bind(;click;,function(){alert(;ok;);});
live(type,[data],fn) 给所有匹配的元素附加一个事件处理函数;即使这个元素是以后再添加进来的
$(;a;).live(;click;,function(){alert(;ok;);});
delegate(selector,[type],[data],fn) 指定的元素;属于被选元素的子元素;添加一个或多个事件处理程序;并规定当这些事件发生时运行的函数
$(;#container;).delegate(;a;,;click;,function(){alert(;ok;);})
on(events,[selector],[data],fn) 在选择元素上绑定一个或多个事件的事件处理函数
function fn(event) {
alert(event.data.foo);
}
$(;p;).on(;click;, {foo: ;bar;}, fn)
区别;
.bind()是直接绑定在元素上.live()则是通过冒泡的方式来绑定到元素上的。更适合列表类型的;绑定到document DOM节点上。和.bind()的优势是支持动态数据。.delegate()则是更精确的小范围使用事件代理;性能优于.live().on()则是最新的1.9版本整合了之前的三种方式的新事件绑定机制$(;#id;).click(func1).mouseover(func2) //方法连写;func为方法的名字
$(;#id;).click(function(){}),mouser(function(){); //多个事件
$(;#id;).bind(;click mouseover;,func) //两个事件中间有空格 ;func为方法的名字
$(;#id;).bind(;load scroll;,function(){});
jQuery更多是在PC端被应用;因此;考虑了很多低级浏览器的的兼容性问题;而Zepto.js则是直接抛弃了低级浏览器的适配问题;显得很轻盈;
Zepto.js在移动端被运用的更加广泛;更注重在移动端的使用。
jQuery的底层是通过DOM来实现效果的;zepto.js 是用css3来实现的;
Zepto.js可以说是轻量级版本的jQuery。
Zepto不支持旧版本的Inernet Explorer浏览器;<10;
Zepto还提供了一些模块的使用
没有defer或async浏览器会立即加载并执行指定的脚本;指的是在渲染该 <script> 标签之下的文档元素之前;也就是说不等待后续载入的文档元素;读到就加载并执行。
<script src=;script.js;></script>
有 async加载和渲染后续文档元素的过程将和 script.js 的加载与执行并行进行;异步;。
<script async src=;script.js;></script>
有 defer加载后续文档元素的过程将和script.js的加载并行进行;异步;;但是 script.js 的执行要在所有元素解析完成之后;DOMContentLoaded 事件触发之前完成。
<script defer src=;myscript.js;></script>
首先把所有脚本都丢到 <body> 之前是最佳实践;因为对于旧浏览器来说这是唯一的优化选择;此法可保证非脚本的其他一切元素能够以最快的速度得到加载和解析。
如我们所知;在浏览器渲染网页的过程中;加载到HTML文档后;会将文档解析并构建DOM树;然后将其与解析CSS生成的CSSOM树一起结合产生爱的结晶——RenderObject树;然后将RenderObject树渲染成页面;当然中间可能会有一些优化;比如RenderLayer树;。这些过程都存在与渲染引擎之中;渲染引擎在浏览器中是于JavaScript引擎;JavaScriptCore也好V8也好;分离开的;但为了方便JS操作DOM结构;渲染引擎会暴露一些接口供JavaScript调用。由于这两块相互分离;通信是需要付出代价的;因此JavaScript调用DOM提供的接口性能不咋地。各种性能优化的最佳实践也都在尽可能的减少DOM操作次数。
而虚拟DOM干了什么?它直接用JavaScript实现了DOM树;大致上;。组件的HTML结构并不会直接生成DOM;而是映射生成虚拟的JavaScript DOM结构;React又通过在这个虚拟DOM上实现了一个 diff 算法找出最小变更;再把这些变更写入实际的DOM中。这个虚拟DOM以JS结构的形式存在;计算性能会比较好;而且由于减少了实际DOM操作次数;性能会有较大提升
var a={}
delete a //报错
不允许变量重名不允许使用八进制和转义字符不允许对只读属性赋值不允许对一个使用getter方法读取的属性进行赋值不允许删除一个不允许删除的属性;比如delete Object.prototype;变量名不能为eval和 arguments在作用域 eval() 创建的变量不能被调用禁止this关键字指向全局对象
let arr =new Set([2,4,4,6,3,6,7,5,7])
**浅拷贝;**只拷贝指向对象的地址;不拷贝对象本身;修改一个对象会影响另外一个对象
let obj = {};
let obj2 = obj;
obj2.x = 11;
console.log(obj, obj2);
**深拷贝;**创建并复制对象本身;不共用内存空间;改变一个对象不影响另外对象
let obj = {
;usr;: ;lisi;,
;age;: 20,
fn: function() { console.log(;fn...;); }
};
let obj2 = JSON.parse(JSON.stringify(obj));
obj2.usr = ;zhangsan;;
console.log(obj, obj2);
//简写;
let obj = {
usr,
email,
fn(){}
}
//表达式;
let x=age;
let obj2={
[x]:20
}
class computers{
attr:;cpu800;,
fn(){
console.log(;input321;)
}
constructor(a,b){
this.cpu=a;
this.ads=b;
}
}
//父类
class Peoples {
usr;
age;
constructor(usrs, ages) {
this.usr = usrs;
this.age = ages;
}
}
//子类
class Students extends Peoples {
constructor(xuehao, names, ages) {
super(names, ages);
this.xh = ;xuehao;;
}
}
var p = new Promise((resolve,reject)={
if(1){
resolve(‘成功’)
}
else{
reject(‘失败’);
}
})
p.then((res)=>{}).catch((err)=>{})
async:
1、被async修饰过的函数调用返回promise对象;默认状态为resolve
2、async函数无需手动调用resolve()和reject()方法;async函数会根据当前状态自动调用
3、asyns函数遇到await等待;当异步执行完后再往下执行
await:
1、await要与async一起使用;不能单独使用
2、asyns函数遇到await等待;当异步执行完后再往下执行
3、await可以直接处理promise的resolve;;结果;不能直接处理reject()的结果
Exports是对Module.exports的引用。
单个暴露;
exports.属性=属性值
exports.方法=函数
Module.exports.属性=属性值
Module.exports.方法=函数
批量暴露
exports={ }
Module.exports={ }
多用途互联网邮件扩展类型。这是HTTP协议中用来定义文档性质及格式的标准。服务器通过MIME告知响应内容类型;而浏览器则通过MIME类型来确定如何处理文档。
常见的MIME类型有;
text/html html数据text/css css数据application/js js数据application/json json数据Image/gif gif格式的图片Image/png png格式的图片Image/jpg jpg格式的图片Image/jpeg jpeg格式的图片通过应用生成器工具;express-generator可以快速创建一个应用的骨架, 包含一整套配置好的服务器配置, 文件和文件夹等, 包括静态资源的暴露等, 包括路由的配置, 和模板引擎配置, 以及404的处理
首先前端代码运行在浏览器中, 由浏览器的XMLHTTPRequest发起一个请求, 如果通过了跨域的检测, 进行http连接, 发送请求信息, 服务器触发对应监听的;/api/getNews;接口的回调函数, 执行其中的代码, 最后res返回响应的内容等给本次请求的地方。
WebPack可以看做是模块打包机;它做的事情是;分析你的项目结构;找到JavaScript模块以及其它的一些浏览器不能直接运行的拓展语言;Sass;TypeScript等;;并将其转换和打包为合适的格式供浏览器使用。在3.0出现后;Webpack还肩负起了优化项目的责任。
这段话有三个重点;
打包;可以把多个Javascript文件打包成一个文件;减少服务器压力和下载带宽。转换;把拓展语言转换成为普通的JavaScript;让浏览器顺利运行。优化;前端变的越来越复杂后;性能也会遇到问题;而WebPack也开始肩负起了优化和提升性能的责任。语法区别
experss 异步使用 回调koa1 异步使用 generator ; yeildkoa2 异步使用 await/async中间件区别
koa采用洋葱模型;进行顺序执行;出去反向执行;支持context传递数据express本身无洋葱模型;需要引入插件;不支持contextexpress的中间件中执行异步函数;执行顺序不会按照洋葱模型;异步的执行结果有可能被放到最后;response之前。这是由于;其中间件执行机制;递归回调中没有等待中间件中的异步函数执行完毕;就是没有await中间件异步函数集成度区别
express 内置了很多中间件;集成度高;使用省心;
koa 轻量简洁;容易定制
该如何选择?
如果你不想自己选择和搭建各种模块组件并有可能需要处理兼容问题;而喜欢一体的、快速集成开发;那么选择Express;Express是一套成熟的应用开发框架;而不仅仅提供核心模块。如果是新项目;运行环境对ES7语法没有限制;对性能比较看重;团队有较高的定制化需求和技能;那么优先选择Koa;如果是Express的老项目;那么建议继续使用Express。MVC全名是Model View Controller;是模型(model);视图(view);控制器(controller)的缩写。
Model;模型;表示应用程序核心;如数据库;。View;视图;显示效果;HTML页面;。Controller;控制器;处理输入;业务逻辑;。是一种软件设计典范;用一种业务逻辑、数据、界面显示分离的方法组织代码;将业务逻辑聚集到一个部件里面;在改进和个性化定制界面及用户交互的同时;不需要重新编写业务逻辑。MVC被独特的发展起来用于映射传统的输入、处理和输出功能在一个逻辑的图形化用户界面的结构中。
MVC工作方式;
MVVM
M: model ;模型;指的就是数据
V;view 视图;是应用程序中处理数据显示部分。通常视图是依据模型数据创建的。
VM: view-model 负责状态改变可以自动传递给View;即所谓的数控双向绑定
v-model 多用于表单元素实现双向数据绑定;同angular中的ng-model;
v-for 格式; v-for=;字段名 in(of) 数组json; 循环数组或json(同angular中的ng-repeat),需要注意从vue2开始取消了$index
v-show 显示内容 ;同angular中的ng-show;
v-hide 隐藏内容;同angular中的ng-hide;
v-if 显示与隐藏 ;dom元素的删除添加 同angular中的ng-if 默认值为false;
v-else-if 必须和v-if连用
v-else 必须和v-if连用 不能单独使用 否则报错 模板编译错误
v-bind 动态绑定 作用; 及时对页面的数据进行更改
v-on:click 给标签绑定函数;可以缩写为;;例如绑定一个点击函数 函数必须写在methods里面
v-text 解析文本
v-html 解析html标签
v-bind:class 三种绑定方法 1、对象型 ;{red:isred}; 2、三元型 ;isred?;red;:;blue;; 3、数组型
<script>
// 注册一个全局自定义指令 ;v-focus;
Vue.directive(;focus;, {
// 当被绑定的元素插入到 DOM 中时……
inserted: function (el;;参数;) {
// 聚焦元素
el.focus()
}
})
//注册局部自定义指令
directives: {
focus: {
// 指令的定义
inserted: function (el,;参数;) {
el.focus()
}
}
}
</script>
<!--使用-->
</input v-focus>
v-model.number=; ; 绑定值强制转换为 number 类型
v-model.trim=; ; 去除前后部分空格修饰符
v-model.lazy=; ; 赋值触发事件 变成为 onchange
;click.stop=; ; 阻止事件冒泡
;submit.prevent=; ; 阻止默认事件; 如;默认表单提交事件
;click.capture=; ; 捕获阶段触发
;click.self=; ; 只响应 事件源为自己的事件
;click.once=; ; 只触发 一次
;keydown.enter=; ; 回车键
;keydown.13=; ; 回车键 ;13为键码
<input type=;text; :value=;msg; ;input=;fn($event);>
<script >
let vm = new Vue({
el:;#app;,
data:{
msg:;hello;
},
methods:{
fn(e){
this.msg = e.target.value;
}
}
})
</script>
全局注册: Vue.component(;组件名;,{配置对象})
局部注册; components:{ 组件名:{ 配置对象 } }
注意点;
组件名注意驼峰命名小坑;不要取html有的标签名;
data是一个函数;且必须返回一个对象
template 模板 只可以有一个根标签;且可以简化;通过 选择器绑定body里面的template模板
el 挂载的节点
computed 计算属性
directives 自定义指令
data 存储数据对象
computed 计算属性
watch 侦听器
methods 函数方法
filters 过滤器
components 注册组件
生命周期钩子函数
watch 是观察的动作;自动执行
methods 是方法;主动调用
//普通监听
watch:{
count:function(newValue,oldValue){
console.log(newValue,oldValue)
console.log(;count 变化;)
}
}
//深度侦听
watch:{
list:{
handler(val){ // 监听函数
console.log(val)
this.allCheck = val.every(item=>item.checked)
},
deep:true, // 设置深度监听
immediate:true // 实例加载完毕立即执行
}
}
//作用: 对数据进行一些加工处理;比如 数字保留几位小数
// 全局注册
console.log(Vue.filter);
// 定义;Vue.filter(;过滤器名;,过滤器函数)
// 过滤器函数一定要有返回值
Vue.filter(;过滤器名;,functon(变量值,传入的参数){
//过滤处理
return {处理后的结果}
})
// 局部注册;
new Vue({
el:;;
filters:{
过滤器名:function(变量值;传入的参数=参数默认值){
// 过滤处理
return {处理后的结果}
}
}
})
// 使用; {{ 变量 | 过滤器名 }}
//定义;
export default new Router({
routes: [
{path: ;/index/:id;,
component: index}
]
}
)
//获取;
this.$route.params.id
vue用来写路由的一个插件。
router-link是路由导航组件;会生成a标签;需要设置to属性;
router-view是路由出口;会根据浏览器地址进行匹配路由规则;并将匹配到的路由规则对应的组件展示在router-view处。
//在脚手架中使用;
import Vue from ;vue; 引入vue
import VueRouter from ;vue-router; 引入路由插件
Vue.use(VueRouter); 安装路由
new Vue({
el: ;#app;,
router, 使用配置好的路由
components: { App },
template: ;<App/>;
})
import Home from ;;/pages/Home; 引用组件
let router = new VueRouter({
配置路由
routes:[{
path:;/;, 路由地址
component:Home 路由使用组件
}]
})
export default router 暴露路由实例
<router-view /> 路由出口
异步加载的写法;
let Index = () => import(/* webpackChunkName: ;group-index; */ ;;/pages/index;);
同步加载的写法 ;
import Index from ;;/pages/index;
router.beforeEach((to,from,next)=>{
if(to.path===;/login;){
next()
return;
}
if(store.state.user){
next();
return;
}
next(;/login;)
}
)
全局前置守卫 router.beforeEach((to,from,next)=>{})
全局解析守卫 router.beforeResolve((to,from,next)=>{})
全局后置钩子 router.afterEach((to,from)=>{})
路由独享的守卫 beforeEnter(to,from,next){ }
组件内的守卫
beforeRouteEnter(to,from,next){//不能使用this},
beforeRouteUpdate(to,from,next){},
beforeRouteLeave(to,from,next){}
npm install vuex --save //安装
import Vuex from ;vuex; //引入
Vue.use(Vuex) //已中间件使用
export default new Vuex.Store({
state:{ // 状态;整个应用共享的数据
}
})
this.$store.state //获取共享的数据
getters //是 store 的计算属性
mutations // 同步 修改state 仓库通过commit调用
actions // 异步 修改state 仓库通过dispatch调用
modules //store 分割成模块
axios.get(请求地址;配置对象).then(res=>{
成功的回调的函数;res是相应的数据
})
axios.post(请求地址;请求数据;配置对象).then(res=>{
成功的回调的函数;res是相应的数据
})
axios.all([请求1;请求2]).then(res=>{
res是一个数组。 数组的值就是每个请求返回的数据信息
})
//自定义配置新建一个 axios 实例
axios.create(配置对象)
axios({ 配置信息 })
import axios from ;axios;
/**
* 封装请求
* ;url: String 请求地址
* ;method: String 请求方法
* ;params: Object 请求参数
*/
// 一、request请求拦截
axios.interceptors.request.use((config) => {
console.log(;请求拦截;)
console.log(config)
return config
}, (error) => {
return Promise.reject(error)
})
// 二、respone响应拦截
axios.interceptors.response.use((response) => {
console.log(;响应拦截;)
console.log(response)
return response
}, (error) => {
return Promise.reject(error)
})
export function http(url, method, params) {
return new Promise((resolve, reject) => {
axios({
method: method,
url: url,
data: params
}).then(res => {
// 这里我们和后端约定当返回的状态码为0的时候ok
if(res.data.retcode === 0) {
resolve(res.data)
}else {
Message({
message: ;请联系开发者;,
type: ;error;
})
reject(res.data)
}
}).catch(err => {
Message({
message: ;请联系开发者;,
type: ;error;
})
reject(err)
console.log(err)
})
})
}
//使用
http(url, ;post;, params).then(data => {
console.log(data;
}).catch(err => {
console.log(err)
})
1、search传参
<router-link to=;/地址?属性名=属性值;></router-link>
this.$route.query.属性名
2、动态路由
path:;/地址/变量名;
<router-link to=;/地址/数据值;></router-link>
this.$route.params.变量名
3、本地存储
setItem() getItem()
Vue 实例从创建到销毁的过程;就是生命周期。从开始创建、初始化数据、编译模板、挂载Dom→渲染、更新→渲染、销毁等一系列过程;
创建期; 一个周期执行一次
beforeCreate; 创建之前, el;data;methods都为undefined
created; 创建完成;data;methods初始化完成;el为undefined;数据添加完毕;还没有编译模板挂载
载入期;
beforeMount; 挂载之前;el为挂载标签;但是 {{ }} 还在
mounted; 挂载完成;页面完成;数据请求;操作DOM
更新期 : 数据变化 就会重新渲染DOM
beforeUpdate; 更新之前
updated; 更新完成
销毁期; 中止数据请求;关闭定时器
beforeDestroy; 销毁之前
destroyed; 销毁完成
全局注册 Vue.component(;组件名;,{配置对象})
局部注册;
components:{
组件名:{ 配置对象 }
}
注意;
1. template 只能有1个根子节点
2. 组件中的data必须是一个函数 且必须返回一个对象
3. 组件的命名方式 ;注册组件命名可以写为 驼峰和烤串写法 ;
4. props只能单向通信;并且不能修改
区别;
v-if是动态地向DOM树内添加或者删除DOM元素;
v-show是通过设置DOM元素的display样式属性控制元素的显示或隐藏;
场景;
基于简单元素显示使用 v-if;
基于css频繁的切换用 v-show
对象方法;
:class=;{ ;active;: isActive };
:class=;{;active;:isActive==-1};
或者
:class=;{;active;:isActive==index};
绑定并判断多个
:class=;{ ;active;: isActive, ;sort;: isSort };
第二种;放在data里面;
:class=;classObject;
data() {
return {
classObject:{ active: true, sort:false }
}
}
数组方法
:class=;[isActive,isSort];
data() {
return{
isActive:;active;,
isSort:;sort;
}
}
:class=;[isActive?;active;:;;];
:class=;[isActive==1?;active;:;;];
进入;
v-enter 定义进入过渡的开始状态
v-enter-active 定义进入过渡生效时的状态
v-enter-to 定义进入过渡的结束状态
离开;
v-leave 定义离开过渡的开始状态
v-leave-active 定义离开过渡生效时的状态
v-leave-to 定义离开过渡的结束状态
<button ;click=;show(11,$events);></button>
methods:{
show(x,ev){
// x就是参数
// ev就是事件对象
}
}
使用自定义属性 向子组件传入数据值 :msg=;msg;
子组件通过 props 对象接收父组件的数据值 props: {msg: { type: String, default: ;;}}
在子组件中使用 传过来的值 <h5>{{msg}}</h5>
子组件通过通过触发自定事件传值 this.$emit(;showMsg;, ;子组改了父组件值;)
父组件中的子组件标签绑定自定义件事 ;showMsg=;getChild;
函数接收自定义事件传过来的值; getChild(val) { this.msg=val }
组件之间中传值
创建一个空 vue 的实例;如;Bus.js
A组件中引入vue空实例Bus;在创建完成(created);给Bus绑定自定义事件 Bus.$on(;add;,(n)=>{ this.count;=n;})
A组件中引入vue空实例Bus;在挂载完成(mounted);触发Bus的自定事件 Bus.$emit(;add;,3)
assets: 里面存放静态文件;比如css,js,image图片等
components;存放组件
router;用来存放路由文件;里面包含一个inde.js路由文件
App.vue:为主组件页面;用来显示其他的组件 Main.js:为入口文件;用来引入所需的模块
一、在components;专门放组件的文件;下创建一个vue文件
二、在需要使用自定义组件的地方的script标签内引入自定义组件 import 组件标签名from ;;/components/组件名称; 在component中添加组件标签名
三、在template中使用组件标签名<组件标签名></组件标签名>
问题;组件名不可以重复;template只能存在一个根标签;组件名必须和引用的标签名相同
//安装;npm install element-ui --save
//引入;
import Vue from ;vue;
import ElementUI from ;element-ui;
import ;element-ui/lib/theme-chalk/index.css;
Vue.use(ElementUI);
form
- Input 输入框
- Form 表单 el-form-item
Notice
- Message 消息提示
- MessageBox 弹框
Data
- Table 表格
- Tag 标签
先写el-form组件;里面写el-form-item用来放输入框;例如用户名和密码那些。
属性;
一、el-from属性有ref、rules、绑定:model
二、el-form-item属性有prop用来定义一个该输入框对应的验证规则
用一个<el-table>< /el-table>这个是最外面的上面;里面用<el-table-row></el-table-row>。
属性;
一、el-table组件的data是用来获取数据;
二、每一行el-table-row的数据通过prop属性。
改变html标签的默认规则;比如ul里放li;dl里放dt等
动态切换组件;<component v-bind:is=;currentView;></component>
特殊嵌套; <table> <tr is=;my-row;></tr> </table>
//函数组件定义;
function App() {
return ( <div></div> );
}
export default App;
// 类组件定义;
class Index extends React.Component{
constructor() {
super();
this.state = {
}
} ,
render(){
return(<div></div>)
}
}
export default Index
//不同;
函数式组件;没有自己的状态;渲染效率较高,无state和生命周期;传值需要用props
类式组件;拥有自己的状态;方便管理,有state和生命周期;传值需要this.props
//组件跳转方式;
<Link to=;/index;>index</Link>
<NavLink to=;/index; activeClassName=;act;>index</NavLink>
//路由跳转方式;
this.props.history.push(;/index;) //跳转到指定路由;支持返回操作。
this.props.history.replace(;/index;) //跳转到指定路由;不支持返回操作。
this.props.history.go(-1) //后退或前进操作
通过内置组件进行跳转
Link和NavLink;这两个组件都是可以在页面中生成超链接a标签;填写上to属性就可以进行页面跳转;区别是NavLink可以设置导航选中的效果。 通过this.props.history的内置方法进行跳转
push;把当前访问的链接进行记录并跳转到目标路由;replace;把当前访问的链接进行替换并跳转到目标路由;go;进行已访问路由地址的回退;一般写负数;-1表示回退到上一个路由地址上。
// #ifdef H5
alert(;只有h5平台才有alert方法;)
// #endif
运行期判断 运行期判断是指代码已经打入包中;仍然需要在运行期判断平台;此时可使用 uni.getSystemInfoSync().platform 判断客户端环境是 Android、iOS 还是小程序开发工具;在百度小程序开发工具、微信小程序开发工具、支付宝小程序开发工具中使用 uni.getSystemInfoSync().platform 返回值均为 devtools;。
switch(uni.getSystemInfoSync().platform){
case ;android;:
console.log(;运行Android上;)
break;
case ;ios;:
console.log(;运行iOS上;)
break;
default:
console.log(;运行在开发者工具上;)
break;
}
使用全局变量实现数据传递;使用的时候;直接使用 getApp() 拿到存储的信息
使用 wx.navigateTo 与 wx.redirectTo 的时候;可以将部分数据放在 url 里面;并在新页面 onLoad 的时候初始化
需要注意的问题;wx.navigateTo 和 wx.redirectTo 不允许跳转到 tab 所包含的页面onLoad 只执行一次使用本地缓存 Storage 相关
<style>
* {margin: 0;padding: 0;}
.box {
width: 300px;
height: 300px;
border: 1px solid #000;
margin: 30px auto;
position: relative;
}
.sbox {
width: 100px;
height: 100px;
background-color: red;
text-align: center;
color: #fff;
font-weight: bold;
}
/*定位 ; 偏移*/
.sbox1 {
position: absolute;
left: 50%
top: 50%
transform: translate(-50%, -50%);
}
/*定位 ; 外边距*/
.sbox2 {
position: absolute;
left: 50%
top: 50%
margin: -50px 0 0 -50px;
}
/*定位 ; margin;auto;*/
.sbox3 {
position: absolute;
top: 0;
right: 0;
bottom: 0;
left: 0;
margin: auto;
}
</style>
<body>
<div class=;box;>
<div class=;sbox sbox1;>定位 ; 偏移</div>
</div>
<div class=;box;>
<div class=;sbox sbox2;>定位 ; 外边距</div>
</div>
<div class=;box;>
<div class=;sbox sbox3;> margin;auto</div>
</div>
</body>
<style>
.box {
width: 0px;
height: 0px;
/*transparent / rgba(255,0,0,0)透明颜色 alpha透明度 0-1取值 0为全透明 1全不透明*/
border-left:10px solid transparent;
border-bottom:10px solid red;
border-right:10px solid transparent;
}
</style>
<body>
<div class=;box;></div>
</body
<style>
*{
margin: 0;padding: 0;
box-sizing: border-box;
}
.box {
/*定义弹性盒*/
display: flex;
/*flex容器为多行。该情况下flex子项溢出的部分会被放置到新行;子项内部会发生断行*/
flex-wrap: wrap;
width: 800px;
height: auto;
margin: 30px auto;
border: 1px solid;
/* ----------设置横向或纵直排列的方式----------------------- */
/* 从左到右排列 默认值*/
/* flex-direction: row; */
/* 从右到左排列 */
/* flex-direction: row-reverse; */
/* 从上到下排列 */
/* flex-direction: column; */
/* 从下到上排列 */
/* flex-direction: column-reverse; */
/* ----------------设置横向排列样式-------------------------- */
/* 水平从左到右紧靠排列 */
/* justify-content:flex-start; */
/* 水平从右到左紧靠排列 */
/* justify-content: flex-end; */
/* 水平中紧靠排列 */
/* justify-content: center; */
/* 水平两端盒子紧靠父盒子;其它间距均等分配 */
/* justify-content: space-between; */
/* 水平间距都均等分配 */
/* justify-content: space-evenly; */
/* 水平两端子项间距是其它子项的一半。 */
/* justify-content: space-around; */
/* ---------------设置纵向排列样式----------------------------- */
/* 垂直顶部对齐 */
/* align-items: flex-start; */
/* 垂直底部对齐 */
/* align-items: flex-end; */
/* 垂直中部对齐 */
/* align-items: center; */
/* 与;flex-start;等效。其它情况下;该值将参与基线对齐。 */
/* align-items: baseline; */
/* align-items: stretch; */
}
.box div {
width: 20%
height: 100px;
border-right: 1px solid yellow;
line-height: 100px;
font-size: 30px;
text-align: center;
color: #fff;
}
.sbox1 {
background-color: red;
}
.sbox2 {
background-color: orange;
}
.sbox3 {
background-color: green;
}
.sbox4 {
background-color: pink;
}
</style>
<body>
<div class=;box;>
<div class=;sbox1;>1</div>
<div class=;sbox2;>2</div>
<div class=;sbox3;>3</div>
<div class=;sbox4;>4</div>
<div class=;sbox4;>4</div>
<div class=;sbox4;>4</div>
</div>
</body>
<style>
* {
margin: 0;padding: 0;
box-sizing: border-box;
}
.box {
/*定义网格布局*/
display: grid;
width: 600px;
height: 500px;
margin: 50px auto;
border: 2px solid #000;
text-align: center;
font-size: 30px;
color: #fff;
/* -------------定义每一;数列;的子项的宽度--------------------- */
/* 列数 高 */
/* grid-template-columns: 100px 100px 100px; */
/* repeat写法; */
grid-template-columns: repeat(3, 100px);
/* fr单位写法; 相对父盒子的比例分配 */
/* grid-template-columns: 1fr 2fr 1fr 2fr; */
/* grid-template-columns: repeat(4 ,1fr); */
/* grid-template-columns: repeat(auto-fill,100px); */
/* 表示长度在范围之间 */
/* grid-template-columns: 1fr minmax(150px,200px); */
/* grid-template-columns: 100px auto 100px; */
/* --------------定义每一;行数;的子项的高度------------------- */
/* 行数 宽 */
/* grid-template-rows: 100px 100px 100px; */
/* repeat写法; */
grid-template-rows: repeat(4, 100px);
/* fr单位写法; 相对父盒子的比例分配 */
/* grid-template-rows: 1fr 2fr 1fr ; */
/* grid-template-rows: repeat(3 ,1fr); */
/* -----------间距------------ */
/* 行之间的间距*/
/* grid-row-gap:20px; */
/* row-gap: 20px; */
/* 列之间的间距 */
/* grid-column-gap:10px; */
/* column-gap: 10px; */
/* 复合写法 行间距 列间距 */
grid-gap: 20px 10px;
/* gap: 20px 10px; */
/* 给网格定义区域 */
/* grid-template-areas:
;a b c;
;d e f;
;g h i;; */
/*---子项的排列方式顺序;行排列或列排列 ----*/
/* 默认值 值后面加dense;row dense或columndense;;为紧凑排列 */
/* grid-auto-flow: row; */
/* grid-auto-flow: column; */
/* ----整体子项里的内容对齐方式 ---*/
/* justify-items: stretch;
align-items: stretch; */
/* 复合写法 */
/* place-items: center center; */
/* start;对齐单元格的起始边缘。
end;对齐单元格的结束边缘。
center;单元格内部居中。
stretch;拉伸;占满单元格的整个宽度;默认值;。 */
/* 排列方式;与弹性盒一样 */
/* align-content: center; */
/* justify-content:space-between ; */
/* 复合写法 列 行 */
/* place-content: center space-between; */
/* 开始 | 结束 | 中部 | 拉伸 |两端间距是其它一半|两端紧靠父盒子|间距等分 */
/* start | end | center | stretch | space-around | space-between | space-evenly; */
/* 调整没有在设置的行和列内的子项宽高 */
/* grid-auto-rows: 50px; */
/* grid-auto-columns: 50px; */
}
.sbox{
border: 1px solid #000;
/* width: 100%
height: 100% */
}
.sbox:nth-child(1) {
background-color: aqua;
/* grid-column-start: 1; */
/* grid-column-end: 3; */
/* 复合写 grid-column: 1/3; */
/* grid-row-start: 1; */
/* grid-row-end: 3; */
/* 复合写 grid-row: 1/3; */
/* grid-column-start; 左边框所在的垂直网格线 */
/* grid-column-end;右边框所在的垂直网格线 */
/* grid-row-start;上边框所在的水平网格线 */
/* grid-row-end;下边框所在的水平网格线 */
}
.sbox:nth-child(2) {
background-color: plum;
}
.sbox:nth-child(3) {
background-color: red;
}
.sbox:nth-child(4) {
background-color: orange;
}
.sbox:nth-child(5) {
background-color: green;
}
.sbox:nth-child(6) {
background-color: yellowgreen;
}
.sbox:nth-child(7) {
background-color: crimson;
}
.sbox:nth-child(8) {
background-color: thistle;
}
.sbox:nth-child(9) {
background-color: magenta;
}
.sbox:nth-child(10) {
background-color: palegreen;
}
</style>
<body>
<div class=;box;>
<div class=;sbox;>1</div>
<div class=;sbox;>2</div>
<div class=;sbox;>3</div>
<div class=;sbox;>4</div>
<div class=;sbox;>5</div>
<div class=;sbox;>6</div>
<div class=;sbox;>7</div>
<div class=;sbox;>8</div>
<div class=;sbox;>9</div>
<div class=;sbox;>10</div>
</div>
function getStyle(ele, attr) {
if (window.getComputedStyle) {
return window.getComputedStyle(ele)[attr];
} else {
return ele.currentStyle[attr]
}
}
function getPos(ele) {
var lt = 0;
var tp = 0;
while (ele) {
lt ;= ele.offsetLeft;
tp ;= ele.offsetTop;
ele = ele.offsetParent;
}
return {
left: lt,
top: tp
}
}
//方法一
var arr = [3, 27, 5, 86, 22];
function fn(arr) {
return Math.max.apply(null, arr);
// return Math.min.apply(null, arr); //最小值
}
console.log(fn(arr)); // 86
//方法二;
var arr = [4, 2, 65, 32, 6];
var max = arr[0];
for (var i = 1; i < arr.length; i;;) {
if (arr[i] > max) {
max = arr[i];
}
}
console.log(max); //65
//方法一;
function fn(arr) {
for (var i = 0; i < arr.length; i;;) {
for (var j = i ; 1; j < arr.length; j;;) {
if (arr[i] == arr[j]) {
arr.splice(j, 1);
j--; //删除一个元素后;后面的元素会依次往前;下标也需要依次往前
}
}
}
return arr
}
//方法二;
function fn(arr) {
var newArr = [];
for (var i = 0; i < arr.length; i;;) {
if (newArr.indexOf(arr[i]) === -1) {
newArr.push(arr[i]);
}
}
return newArr;
}
//方法三: ES6
let arr =new Set([2,4,4,6,3,6,7,5,7])
var arr = [5, 32, 7, 45, 2];
//方法一;
function sort(arr) {
for (var i = 1; i < arr.length-1; i;;) {
for (var j = 0; j < arr.length - i; j;;) {
if (arr[j] > arr[j ; 1]) {
var temp = arr[j ; 1];
arr[j ; 1] = arr[j];
arr[j] = temp;
}
}
}
return arr;
};
console.log(sort(arr));
//方法二;
var arr = [5, 32, 7, 45, 2];
arr.sort(function (a, b) {
return a - b; //升序
//return b - a; //降序
});
console.log(sort(arr));
//案例一;
var arr = [
{ ;date;: ;2018-08-01;, ;DIU;: 1209, ;country;: ;US; },
{ ;date;: ;2018-08-02;, ;DIU;: 680, ;country;: ;GB; },
{ ;date;: ;2018-08-01;, ;DIU;: 2311, ;country;: ;CN; },
{ ;date;: ;2018-08-02;, ;DIU;: 879, ;country;: ;US; },
{ ;date;: ;2018-08-03;, ;DIU;: 1525, ;country;: ;CN; },
{ ;date;: ;2018-08-02;, ;DIU;: 1525, ;country;: ;CN; }
];
arr.sort(function (a, b) {
var v1 = new Date(a.date).getTime();
var v2 = new Date(b.date).getTime();
if (v1 !== v2) {
return v2 - v1;
} else {
return b.DIU - a.DIU;
}
});
console.log(arr);
//案例二;
var arr = [
{ name: ;武丽昕;, num: 78 },
{ name: ;汤文博;, num: 38 },
{ name: ;卢文博;, num: 58 },
{ name: ;邓钧键;, num: 97 },
{ name: ;刘继昂;, num: 56 },
{ name: ;安军安;, num: 78 },
{ name: ;安晓月;, num: 98 },
{ name: ;乐秋萍;, num: 79 }
];
// 中文比较
arr.sort(function (a, b) {
return a.name.localeCompare(b.name, ;zh;);
});
console.log(arr);
// --------------------------
// 按num排序
arr.sort(function (a, b) {
return a.num - b.num;
})
console.log(arr);
var arr = [5, 32, 7, 45, 2];
function fn(arr) {
var newArr = [].concat(arr); // 重新创个新组数;不影响原数组。
for (var i = 0; i < newArr.length - 1; i;;) {
for (var j = i ; 1; j < newArr.length; j;;) {
if (newArr[i] > newArr[j]) {
var temp = newArr[j];
newArr[j] = newArr[i];
newArr[i] = temp;
}
}
}
return newArr;
}
console.log(fn(arr));
var array = [5, 32, 7, 45, 2];
function fn(arr) {
if (arr.length <= 1) {
return arr;
}
arr = [].concat(arr);
var n = arr.splice(0, 1)[0]; // 获取一个数做比较
var left = []; // 存小于对比项的数
var right = []; // 存大于对比项的数
for (var i = 0; i < arr.length; i;;) {
if (arr[i] < n) {
left.push(arr[i]);
} else {
right.push(arr[i]);
}
}
return fn(left).concat(n, fn(right)); // 递归调用
}
console.log(fn(array));
var arr = [5, 32, 7, 45, 2];
arr.sort(function () {
return Math.random() - 0.5;
});
console.log(arr);
var str = ;abcdefg;;
if (str.indexOf(;def;) != -1) {
console.log(str.substr(str.indexOf(;def;), 3));
}
var str = ;abcdabcd;;
function fn(str) {
var newStr = ;;;
for (var i = 0; i < str.length; i;;) {
if (newStr.indexOf(str[i]) === -1) {
newStr ;= str[i];
}
}
return newStr;
}
console.log(fn(str));
//方法一;
var str = ;assssjdssskssalsssdkjsssdss;;
var obj = {};
for (var i = 0; i < str.length; i;;) {
var chars = str.charAt(i);
if (obj[chars]) {
obj[chars];;;
} else {
obj[chars] = 1;
}
}
console.log(obj); //每个字符出现的个数
var max=0;
var maxStr=;;;
for(var attr in obj){
if(obj[attr]>max){
max=obj[attr];
maxStr=attr;
}
}
console.log(maxStr); //出现最多的字符
console.log(max); //出现最多的字符的个数
//方法二;
var newStr = ;;;
for (var i = 0; i < str.length; i;;) { // 去重
if (newStr.indexOf(str[i]) == -1) {
newStr ;= str[i]
}
}
var arr = [];
for (var i = 0; i < newStr.length; i;;) {
var single = newStr[i]
var num = 0;
for (var j = 0; j < str.length; j;;) {
if (single == str[j]) {
num;;; //计数器
}
}
arr.push(num); //把每一轮的计数结果;通数组的形式记录下来
}
arr.sort(function (a, b) { //排序
return a - b;
});
console.log(arr); //排序后的数组
var n = arr[arr.length - 1]; //获取排序后里的最后一项,为最多的计数。
console.log(;结果;, newStr.charAt(arr.indexOf(n)), n);
如下;“1233fddfd&3434fdsaff&454545&4545444rfdsfds&545gdsgs”
返回;“12345fdsarg”
var str = ;123fd&3434fdsaff&454545&454ds&545gdsgs;
function fn(str) {
var newStr = ;;;
for (var i = 0; i < str.length; i;;) {
if (newStr.indexOf(str[i]) === -1) {
newStr ;= str[i];
}
}
return newStr;
}
console.log(fn(str));//去重后的字符串
function ab(){
var s =fn(str);
var lt=;;;
var rt=;;;
for(var i=0 ; i<s.length;i;;){
if(s[i]>=;1; && s[i]<=;9;){
lt;=s[i];
}else if(s[i]>=;a; && s[i]<=;z;){
rt;=s[i];
}
}
return lt;rt;
}
console.log(ab());
var o = {
a: ;1;,
b: ;2;,
c: ;;,
d: ;xxx;,
e: undefined
};
var str = ;http://item.taobo.com/item.html?a=1&b=2&c=&d=xxx&e;;
function fn(str) {
var obj = {};
var s = str.split(;?;)[1];
var arr = s.split(;&;);
for (var i = 0; i < arr.length; i;;) {
var arr2 = arr[i].split(;=;);
obj[arr2[0]] = arr2[1];
}
return obj;
}
fn();
console.log(obj);
//方法一;
function fn(n) {
var num = 1;
for (var i = n; i >= 1; i--) {
num *= i;
}
return num;
}
console.log(fn(10));
//函数递归;函数中的自我调用;;方法二;
function fn(n) {
if (n <= 1) {
return 1;
}
return n * fn(n - 1);
}
console.log(fn(10));
function ran(min, max) {
return Math.floor(Math.random() * (max - min ; 1) ; min);
}
console.log(ran(1,10))
function bind(ele, event, callback) {
if (ele.addEventListener) {
// 标准浏览器
ele.addEventListener(event, callback, false);
} else {
// IE8及以下
ele.attachEvent(;on; ; event, callback);
}
}
//使用:bind(元素;事件类型;函数)
//如:
bind(box,;click;,function(){
})
//找样式函数封装
function getStyle(ele, attr) {
if (window.getComputedStyle) {
return window.getComputedStyle(ele)[attr];
} else {
return ele.currentStyle[attr]
}
}
//运动函数
function move(ele, obj, callback) {
clearInterval(ele.timer);//清除定时器
ele.timer = setInterval(function () {
var onOff = true;
for (var attr in obj) {
var target = obj[attr];
if (attr === ;opacity;) { //做IE的兼容
var iNow = getStyle(ele, ;opacity;)*100;
} else {
var iNow = parseInt(getStyle(ele, attr));
}
var dir = (target - iNow) / 10;
dir = dir > 0 ? Math.ceil(dir) : Math.floor(dir);
iNow ;= dir;
if ((iNow >= target && dir > 0) || (iNow <= target && dir < 0)) {
iNow = target;
}
if (attr === ;opacity;) {
ele.style.opacity = iNow / 100;
ele.style.filter = ;alpha(opacity = ; ; iNow ; ;);;
} else {
ele.style[attr] = iNow ; ;px;;
}
if (iNow != target) {
onOff = false;
}
}
if (onOff) {
clearInterval(ele.timer);
callback && callback();
}
}, 50)
}
//使用;move;元素;{需要改变的属性};下一步执行的函数;;
//如;
box.onclick = function () {
move(box, {
width: 200,
height: 300,
opacity:50
}, function () {
move(box,
{
width:200,
height:200,
left:200,
top:200,
opacity:100
})
});
}
function drag(ele) {
// 按下
ele.onmousedown = function (ev) {
var ev = ev || event;
// 鼠标到盒子的距离
var disX = ev.clientX - ele.offsetLeft;
var disY = ev.clientY - ele.offsetTop;
// 可视区宽高
var clientW = document.documentElement.clientWidth;
var clientH = document.documentElement.clientHeight;
// 盒子宽高
var boxW = ele.clientWidth;
var boxH = ele.clientHeight;
// 设置全局捕获;IE8及以下兼容
if (ele.setCapture) {
ele.setCapture();
}
// 拖动
document.onmousemove = function (ev) {
var ev = ev || event;
var lt = ev.clientX - disX;
var tp = ev.clientY - disY
// 控制范围
if (lt < 0) {
lt = 0;
} else if (lt > clientW - boxW) {
lt = clientW - boxW
}
if (tp < 0) {
tp = 0;
} else if (tp > clientH - boxH) {
tp = clientH - boxH;
}
ele.style.left = lt ; ;px;;
ele.style.top = tp ; ;px;;
}
// 抬起
document.onmouseup = function () {
document.onmousemove = null;
document.onmouseup = null;
// 取消全局捕获;兼容IE8及以下
if (ele.releaseCapture) {
ele.releaseCapture();
}
}
return false;
}
}
//使用;drag;元素;;
// 参数;请求的方式 地址 数据 成功的回调
function ajax(method, url, data, callback) {
var xhr = XMLHttpRequest();
// get请求
if (method === ;get;) {
if (data) {
url ;= ;?; ; data;
}
xhr.open(method, url, true);
xhr.send();
} else { // post请求
xhr.open(method, url, true);
xhr.setRequestHeader(;content-type;, ;application/x-www-form-urlencoded;);
if (data) {
xhr.send(data);
} else {
xhr.send();
}
}
xhr.onreadystatechange = function () { //ajax状态改变触发的事件后;执行的函数
if (xhr.readyState === 4) { //响应内容解析完成;可以在客户端调用了
if (xhr.status === 200) { // 成功
callback && callback(xhr.responseText);
} else { // 失败
throw new Error(;请求失败;失败原因是;; ; xhr.status);
}
}
}
}
//使用:
// ajax(;请求方式;, ;请求路径;, 发送的数据, function (data) {
// console.log(data);
// })
//如;
ajax(;get;, ;data/1.txt;, null, function (data) {
console.log(data);
})
//封装
function deepCopy(obj) {
if (Object.prototype.toString.call(obj).slice(8, -1) == ;Object;) {
var result = {}
} else if (Object.prototype.toString.call(obj).slice(8, -1) == ;Array;) {
var result = []
} //判断数据类型类型
for (var attr in obj) {
if (typeof obj[attr] == ;object;) {
result[attr] = deepCopy(obj[attr])
} else {
result[attr] = obj[attr]
}
}
return result
}
//使用
let obj = {
;usr;: ;lisi;,
;age;: 20,
fn: function() { console.log(;fn...;); }
};
let obj2 = deepCopy(obj);
obj2.usr = ;zhangsan;;
console.log(obj, obj2);
markyun.Event = {
// 页面加载完成后
readyEvent : function(fn) {
if (fn==null) {
fn=document;
}
var oldonload = window.onload;
if (typeof window.onload != ;function;) {
window.onload = fn;
} else {
window.onload = function() {
oldonload();
fn();
};
}
},
// 视能力分别使用dom0||dom2||IE方式 来绑定事件
// 参数; 操作的元素,事件名称 ,事件处理程序
addEvent : function(element, type, handler) {
if (element.addEventListener) {
//事件类型、需要执行的函数、是否捕捉
element.addEventListener(type, handler, false);
} else if (element.attachEvent) {
element.attachEvent(;on; ; type, function() {
handler.call(element);
});
} else {
element[;on; ; type] = handler;
}
},
// 移除事件
removeEvent : function(element, type, handler) {
if (element.removeEnentListener) {
element.removeEnentListener(type, handler, false);
} else if (element.datachEvent) {
element.detachEvent(;on; ; type, handler);
} else {
element[;on; ; type] = null;
}
},
// 阻止事件 (主要是事件冒泡;因为IE不支持事件捕获)
stopPropagation : function(ev) {
if (ev.stopPropagation) {
ev.stopPropagation();
} else {
ev.cancelBubble = true;
}
},
// 取消事件的默认行为
preventDefault : function(event) {
if (event.preventDefault) {
event.preventDefault();
} else {
event.returnValue = false;
}
},
// 获取事件目标
getTarget : function(event) {
return event.target || event.srcElement;
},
// 获取event对象的引用;取到事件的所有信息;确保随时能使用event;
getEvent : function(e) {
var ev = e || window.event;
if (!ev) {
var c = this.getEvent.caller;
while (c) {
ev = c.arguments[0];
if (ev && Event == ev.constructor) {
break;
}
c = c.caller;
}
}
return ev;
}
};