JavaScript学习笔记

一、JavaScript

内容链接 包含笔记 tool.js 等
https://download.csdn.net/download/weixin_42530002/13086675

1、字符串
(1)、验证码
(2)、将字符串按照单词进行逆序,空格作为划分单词的唯一条件
(3)、对称数组
(4)、已知一个字符串对象中,英语单词用各种非字母字符分割,统计单词个数
(5)、判断单个字符是否是字母(包含大小写)
(6)、实现函数,查找子串出现的次数,返回字符串str中出现substring的次数
(7)、判断是否为邮箱,已知千锋邮箱的用户名只能由数字字母下划线组成,域名为@1000phone.com,
(8)、判断单个字符是否符合数字字母下划线
(9)、敏感词过滤
(10)、表单验证 验证用户名密码是否符合规范
2、math对象及日期对象
(1)、认识对象
(2)、对象的代码
(3)、Math对象
(4)、日期对象
(5)、定时器
(6)、案例 秒表
3、BOM和DOM
(1)、认识BOM
(2)、open方法
(3)、history对象
(4)、location
(5)、DOM
(6)、获取元素节点的方法
4、DOM进阶下
(1)、获取节点样式 跨浏览器的兼容
(2)、生成随机颜色
(3)、attribute
(4)、元素节点的属性
(5)、属性节点
(6)、节点操作
(7)、节点操作案例 添加删除列表
(8)、this概念
(9)、选项卡
(10)、微博发布功能
(11)、offset系列方法
(12)、文档碎片
(13)、遍历
5、event事件上
(1)、绑定事件
(2)、事件类型的种类
(3)、事件绑定
(4)、鼠标事件对象的属性
(5)、跟随鼠标提示框
(6)、修改键 特殊键 shiftKey ctrlKey altKey metakey
(7)、键码和字符码
(8)、微博发布功能
(9)、案例 方向键移动方块
(10)、目标对象target和this (事件绑定)
(11)、事件冒泡 (阻止事件冒泡)
(12)、跟随鼠标移动
(13)、判断手机号码格式
(14)、案例 模拟下拉菜单
(15)、案例 动态生成表格
(15)、案例 ctrl+回车提交
(16)、案例 只能输入数字
(17)、案例 弹出右键菜单
(18)、案例 弹出菜单
(19)、案例 隔行变色及划入隔行变色
5、event事件下
(1)、阻止右键菜单
(2)、阻止超链接的默认行为
(3)、当前窗口的高和宽
(4)、拖拽 限制出界
(5)、事件委托
(6)、微博发布拖拽
(7)、事件监听器 一个事件可触发多个函数
(8)、动态生成表格
(9)、案例 放大镜
6、正则表达式
(1)、创建正则表达式
(2)、在字符串中使用正则的方法
(3)、正则_元字符
(4)、正则补充
(5)、正则练习 验证压缩包 手机号码 身份证号码 纯中文
(6)、注册表单验证(正则)
(7)、localStorage本地存储技术
(8)、案例 滑动条slide 关闭浏览器后存储当前位置
7、ECMA5和ECMA6
(1)、认识this
(2)、强制数据类型转换 改变this指向对象
(3)、let关键字
(4)、const关键字
(5)、箭头函数
(6)、箭头和ECMA5数组方法结合 filter 箭头函数this指向的是上一层函数的主人
(7)、解构
(8)、ECMA6字符串 ``
(9)、ECMA6新增数组方法 Array.from() find() findIndex() arr.copyWithin
(10)、合并对象 Object.assign()
(11)、集合 set
(12)、集合 map
(13)、英汉词典
(14)、Symbol
8、面向对象
(1)、遍历
(2)、创建对象 (未优化)
(3)、prototype原型
(4)、混合法 创建prototype原型对象
(5)、构造函数构造出来的对象__proto__
(6)、面向对象的语法 (继承、封装、多态)
(7)、对象拷贝
(8)、ECMA6class语法
(9)、this指向问题
(10)、选项卡 面向对象
(11)、拖拽 限制拖拽 面向对象
9、运动和游戏开发上
(1)、运动基本流程
(2)、侧边浮动菜单栏
(3)、淡入淡出
(4)、缓冲运动 正反向
(5)、缓冲菜单
(6)、多物体运动 淡入淡出
(7)、offset系列问题
(8)、链式运功
(9)、回调函数 (总结)
(10)、碰撞
(11)、案例 打砖块
(12)、案例 微信打飞机
10、运动和游戏开发下
(1)、圆周运动
(2)、完美运动 多样式运动
(3)、设置多条css样式
(4)、案例 打砖块
(5)、案例 banner图效果
(6)、案例 多图片缩放
(7)、案例 抛物线运动
(8)、案例 评分特效
11、PHP和ajax入门
(1)、认识ajax
(2)、ajax下载数据 非兼容
(3)、ajax对象 兼容
(4)、try_catch
(5)、ajax对象_兼容_try
(6)、onreadystatechange
(7)、form表单的get请求
(8)、form表单的post请求
(9)、ajax get请求
(10)、ajax post请求
12、ajax进阶
(1)、mysql语法
(2)、ajax封装
(3)、JSON对象
(4)、getlist案例 html <-> php 前后端通过ajax交互下载数据
(5)、表单与ajax get post请求区别 及php读取
(6)、案例 新闻列表
(7)、服务器基础知识
(8)、php基本句法
(9)、PHP访问数据库 showStudents.php
13、前后端交互 mysql html -> (from | ajax) -> php -> mysql
(1)、插入学生数据
(2)、登录界面
(3)、注册界面
(4)、查看学生数据
(5)、获取用户列表
14、JSONP跨域
(1)、修改用户密码 mysql html -> (from | ajax) -> php -> mysql
(2)、删除用户 mysql html -> (from | ajax) -> php -> mysql
(3)、跨源方法
(4)、认识JSONP跨域
(5)、案例 天气查询
(6)、案例 百度下拉搜索框
15、网络协议和cookie
(1)、认识网络协议
(2)、认识cookie
(3)、cookie中的中文
(4)、cookie中的可选项
(5)、封装cookie
16、闭包和设计模式
(1)、认识闭包
(2)、闭包的好处
(3)、立即执行函数
(4)、私有化
(5)、闭包在实战中的使用
(6)、自定义警告框
(7)、观察者模式 闭包存储函数
(8)、适配器模式 闭包继承函数
17、gulp
(1)、补充
(2)、使用gulp的流程
(3)、gulpDemo
18、模块化开发
(1)、模块规范
(2)、款放大模式 两js文件可同时声明
(3)、shoppingDemo banner轮播图
(4)、模块化开发 Demo AMD规范
19、scss编程
(1)、声明变量
(2)、选择器嵌套 &
(3)、混合 @mixin @include
(4)、继承 @extend
(5)、import引入公共样式
(6)、scss注释
(7)、控制指令 @if @else
(8)、循环
(9)、函数 @function
(10)、scss sass -> gulp
(11)、sass和scss区别
20、github常用命令
(1)、git基本命令
(2)、git 分支管理
(3)、查看日志版本

附录、tool.js
1、n位验证码 每一个数字的范围 0~9 parseInt(Math.random() * 10);
2、n位验证码 每一个数字的范围 0~9 a-z A-Z parseInt(Math.random() * 123);
3、冒泡排序
4、array去重
5、升序
6、降序
7、显示当前时间 年月日 时分秒格式
8、日期数字转成中文 0-6 -> 日-六
9、数字前补零
10、获取两个日期之间相差的天数
11、输入n,输出n天后的时间。
12、自定义byClassName 兼容IE8以下
13、获取节点样式 跨浏览器的兼容
14、生成随机颜色
15、阻止事件冒泡
16、判断是否是数字
17、删除空白文本子节点
18、随机任意范围整数的函数
19、交换排序
20、倒着遍历元素去重
21、生成n位数字验证码
22、阻止默认行为 跨浏览器
23、限制拖拽
24、拖拽 无限制出界
25、事件监听器兼容
26、判断单个字符是否是字母(包含大小写)
27、判断单个字符是否符合数字字母下划线
28、拖拽 面向对象
29、限制拖拽 面向对象
30、多物体运动 (注释)
31、多物体运动 淡入淡出 (注释)
32、多物体多样式运动 (包含透明度) (注释)
33、链式运动 在第一个动画结束的时候,开始第二个动画。(注释)
34、完美运动
35、碰撞函数
36、设置多条css样式
37、ajax封装
38、封装cookie

一、JavaScript
1、字符串
(1)、验证码
验证码:验证你是否是机器人

		纯数字组成的验证:非常容易破解   6位数字验证码
		数字和字符组成的验证码:
			0~9
			a-z  97~122
			A-Z  65~90
			随机:0~122
		方法:
			1、生成一个数组,装有单个字符,长度62数字
				随机 0~61的下标
			2、随机ASCII码值
	//n位验证码  每一个数字的范围 0~9   parseInt(Math.random() * 10);
	numTestCode(n)
	//n位验证码  每一个数字的范围 0~9 a-z A-Z  parseInt(Math.random() * 123);
	testCode(n);
(2)、将字符串按照单词进行逆序,空格作为划分单词的唯一条件
    传入:”Welome to Beijing”改为 “Beijing to Welcome”
	reverseStr(str)
(3)、对称数组
    传入一个数组,起元素类型与个数皆未知,返回新数组,由原数组的元素正序反序拼接而成。
    传入
        [“One”, “Two”,”Three”] 
    返回
        [“One”, “Two”, “Three”,”Three”,”Two”, “One”]
	symmetryArr(arr)
(4)、已知一个字符串对象中,英语单词用各种非字母字符分割,统计单词个数
	传入:”Yes, she*is%my@love.”;
	返回 5
		【规律】当前面一个字符是字母,后面一个字符是非字母的时候,这就是一个单词
	countOfWord(str)
(5)、判断单个字符是否是字母(包含大小写)
	isABC(charStr)
(6)、实现函数,查找子串出现的次数,返回字符串str中出现substring的次数
	传入:”abcabcabc”, “abc”
    返回:3
	countOfStr(supStr, subStr)
(7)、已知千锋邮箱的用户名只能由数字字母下划线组成,域名为@1000phone.com,
    判断一个字符串是否是千锋邮箱,是返回true,不是返回false。
        [email protected][email protected]  不是
        [email protected]  不是
	isEmail(email)
(8)、判断单个字符是否符合数字字母下划线
	isDEF(charStr)
(9)、敏感词过滤 
	采用正则表达式过滤
	表单元素,获取其中内容,通过.value的属性
	双标签节点 innerHTML属性,获取标签间内容,设置标签间内容,如果文本中含有标签,会自动解析。
	要求:
		1、敏感词都过滤  正则表达式
		2、将敏感词替换成*
		replace()
(10)、表单验证 
	验证用户名和密码是否符合规范

2、math对象及日期对象
(1)、认识对象
语法(在JavaScript中没有类这个概念,只有对象,ECMA6版新增了类的概念)
类:一类具有相同特征事物的抽象概念。
对象:具体某一个个体,唯一的实例。

		类    对象
		狗    你遇到的那只
		电脑  你桌上那台
	数据结构
		基本数据类型(存储一个值) =>  数组(处理批量的数据) => 对象(既可以存储数据又可以存储函数)
	代码
		var car = {
            speed: 60,
            run: function(road){
                return road.length / car.speed;
            }
        };

        var kuahaidaqiao = {
            length: 1000
        };
        /* 
            数字.toFixed(n)
            保留n为小数的
         */
        var hours = car.run(kuahaidaqiao);
		alert("一共花了" + hours.toFixed(2) + "小时");
(2)、对象的代码
	1、通过new运算符声明对象
    2、通过省略new
    3、对象常量赋值 (使用大括号,代表对象)
	var obj1 = new Object();
    var obj2 = Object();
    var obj3 = {};
	通过obj. 或 obj[] 添加属性和方法
	obj3.show();
	obj3['show']();
	delete 关键字  删除对象的属性或者方法
		delete obj3.username; 删除属性
        delete obj3.show;	删除方法

(3)、Math对象
	【注】在JS中一切皆对象。
	【注】在JS,很多关系数学运算的函数,直接一个Math对象提供。
	【注】查阅文档。

	■Math.random() //返回0-1之间的随机数
	■Math.max(num1, num2) //返回较大的数
	■Math.min(num1, num2)  //返回较小的数
	■Math.abs(num)  //绝对值
	■Math.round() 四舍五入(成整数,只看小数点后一位)
	■Math.ceil(19.3)  //向上取整
	■Math.floor(11.8)  //向下取整
	■Math.pow(x,y)  //x的y次方
	■Math.sqrt(num)  //开平方

	传入的参数是:弧度
	Math.sin()  正弦
	Math.cos()  余弦

	Math.PI = Π
	1弧度 = 180 / Math.PI;
(4)、日期对象
	1、日期对象声明
		1、没有传入参数,默认当前系统时间
			Wed Oct 09 2019 09:06:49 GMT+0800 (中国标准时间)
			GMT 格林尼治时间
		2、传入参数
			"2000-01-01"
			"2000/01/01"
			按照顺序,分别传入参数  年 月 日 时 分 秒 毫秒
			【注】在国外月份是从0开始数的 0~11
			直接传入毫秒数   1秒 = 1000毫秒  (已1970年1月1日 0:0:0 为参照时间点去进行换算)
			小彩蛋:linux的创始人
	2、日期对象方法
		【注】所有的参照时间点都是1970年
		Date.parse()
			格式:Date.parse(日期对象)
			功能:可以将日期对象转成毫秒数

		d.getTime()/d.setTime();
			格式:日期对象.getTime/setTime
			功能:将当前日期对象转成毫秒数
	3、日期对象格式化
		//2020/11/1 下午8:07:08
		d.toLocaleDateString() + " " + d.toLocaleTimeString()
	4、自定义当前时间 系统的并非最好的 (推荐)
		tool.js中的showTime() return 
	5、获取两个日期之间相差的天数
            规定,传入日期格式
            "2000-01-01"
            "2000/01/01"
		tool.js countOfDate(d1, d2) return 天数
				afterOfDate(n) return 日期 Tue Dec 01 2020 20:12:58 GMT+0800 (中国标准时间)
(5)、定时器
	格式:var timer = setInterval(函数, 毫秒数);
	功能:每隔对应的毫秒数,执行一次传入的函数。
	返回值:启动定时器的,系统分配的编号。

	clearInterval(timer);  取消定时器
(6)、案例 秒表

3、BOM和DOM
(1)、认识BOM
BOM: browser object model
系统对话框
window 方法 (一般情况下window可以省略)

		alert() 弹出警告框
		confirm() 弹出一个带确定和取消的提示框
			返回值:如果点击确定,返回true
					如果点击取消,返回false

		prompt() 弹出一个带输入框的提示框
			参数:
				第一个参数:面板上显示的内容
				第二个参数:输入框里面的默认(可以不传入)
			返回值:点击确定,返回输入框中的内容
					点击取消,返回null。

(2)、open方法
	open()
		第一个参数:跳转的url  打开一个新窗口,加载url
		第二个参数:字符串,给打开的窗口起一个名字
		第三个参数:一串特殊含义的字符串,可以控制打开窗口的属性

(3)、history对象
	history 对象   window.history  掌管的是,当前窗口(注意不是浏览器)历史记录(只要加载url不一样就会产生历史记录)
		属性 
			history.length 输出当前窗口历史记录的条数
		方法
			history.back()  返回上一条历史记录
			history.forward() 前进到下一条历史记录
			history.go()
				参数: 0  刷新当前页面
						正整数 前进n条记录
						负整数 后退n条记录
(4)、location
	location  地址栏
		属性:
			location.protocol
				url:统一资源定位符。
				协议://IP(域名)/:端口号/路径/?查询字符串#锚点
			location.hostname

		方法:
			location.assign(url)
			【注】在当前窗口跳转带这个url
			location.replace(url)
			【注】在当前窗口替换成新的url。不会产生历史记录。
			location.reload()
			【注】刷新窗前窗口
			location.reload(true)   不经过浏览器缓存强制从服务器重载
                
(5)、DOM
 	DOM: document object model(文档对象模型)
		节点类型:
			元素节点  
属性节点 id = 'div1' 文本节点 div文本 元素节点的获取 document.getElementById(id) 功能:通过id获取符合条件的元素,(id必须是唯一的) 返回值:就是符合条件的一个节点。 获取行间属性的值 alert(oDiv.id); alert(oDiv.title); //访问class 通过className访问 alert(oDiv.className); //设置行间属性的值 /* oDiv.id = "div2"; oDiv.title = 'world'; oDiv.className = 'box4'; */ /* 【注】只能访问标签行间的css样式。 */ alert(oDiv.style.width); alert(oDiv.style.height); /* 【注】如果css样式带-,将-去掉,从第二个单词开始首字母大写 */ // alert(oDiv.style.backgroundColor); oDiv.style.backgroundColor = 'blue'; (6)、获取元素节点的方法 document.getElementById(id); node.getElementsByTagName(标签名); 功能:从node节点开始,通过标签名获取符合条件的元素节点。 返回值:伪数组/类数组 node.getElementsByClassName(class名字) (IE8以下不兼容) 功能:通过class名字获取符合条件的元素节点。 document.getElementsByName(name属性的值); 功能:通过name属性的值获取符合条件的元素节点。 【注】一般使用在表单元素里。 document.querySelector() 返回值:一个元素节点,找到符合条件的第一个元素节点。 document.querySelectorAll() 返回值:返回值,是一个伪数组。 自定义byClassName (IE8以下兼容) tool.js 中node.getElementsByClassName()

4、DOM进阶下
(1)、获取节点样式 跨浏览器的兼容
//可获得sytle中的样式
//通过.style.xxx的方式只能访问内联的css样式。
getStyle(node, cssStyle)
(2)、生成随机颜色
tool.js 中randomColor();
oDiv.style.color = randomColor();
(3)、attribute
setAttribute
getAttribute
removeAttribute()
1、class的访问
2、支持自定义属性
.不支持自定义属性
alert(oDiv.className);
alert(oDiv.getAttribute(“class”));

	oDiv.setAttribute("class", 'box5');
    oDiv.setAttribute("zzz", 'ooo'); 

    oDiv.className = '';
    oDiv.removeAttribute("title");
(4)、元素节点的属性
	innerHTML  获取标签间内容  会解析标签
	innerText  获取标签间纯文本  不会解析标签,设置纯文本
	outerHTML  从外标签开始到外标签结束   会解析标签

	childNodes   访问当前节点下所有的子节点
	firstChild   访问子节点中的首位
	lastChild    访问子节点中的最后一位

	//d 属性节点
	var d = document.getElementById("john").getAttributeNode("name"); 

	childNodes   访问当前节点下所有的子节点
	firstChild   访问子节点中的首位
	lastChild    访问子节点中的最后一位
	nextSibling  访问当前节点兄弟节点中的下一个节点
	previousSibling  访问当前节点兄弟节点中的上一个节点

	【注】上述这些属性都包含文本节点

	【注】下述这些方法只获取子节点中的元素节点。(IE8以下不兼容)

	children
	firstElementChild
	lastElementChild
	nextElementtSibling
	previousElementSibling

            nodeType     nodeName    nodeValue
    元素节点     1          标签名         null
    属性节点     2          属性名       属性值
    文本节点     3          #text       文本内容

	空格、回车、换行 看不见,是字符。 也算文本节点
            
	【注】获取当前节点的父节点通过parentNode获取。

	【注】获取当前整个页面的根节点  document
(5)、属性节点
	attributes  获取当前元素节点上的所有的属性节点
	集合:
		1、无序
		2、不重复
	alert(oDiv.attributes["title"].nodeName);
	alert(oDiv.attributes["title"].nodeType);
	alert(oDiv.attributes["title"].nodeValue);
(6)、节点操作
	document.write()
		【注】会覆盖页面上原有的内容。

	createElement()
		格式:document.createElement()
		参数:标签名
		返回值:创建好的这个节点

	appendChild()
		格式:node1.appendChild(node2);
		功能:将node2节点插入到node1节点子节点的末尾

	createTextNode()
		格式:document.createTextNode(文本);
		功能:创建文本节点(纯文本)

	insertBefore()
		格式:box1.parentNode.insertBefore(box2, box1);
		功能:将box2添加到box1的前面

	replaceChild()
		格式:box1.parentNode.replaceChild(box2, box1);
		功能:用box2节点将box1节点替换掉。

	cloneNode()
		格式:node.cloneNode()
		格式2:node.cloneNode(true);  克隆节点本身和子节点 (整棵树)
		返回值:克隆出来的新节点

	removeChild()
		格式:box.parentNode.removeChild(box);
		功能:将box节点从页面上删除
(7)、节点操作案例 添加删除列表
(8)、this概念
	this概念:只要封装函数,任何一个函数系统都会内置一个叫做this的变量,
		this变量存储的是地址,是当前函数主人的地址。
		【注】this永远指向当前函数的主人。函数的主人要通过当前上下文去判断。
		this类似于现实生活中,用到的"我"。
(9)、选项卡
(10)、微博发布功能
(11)、offset系列方法
	offsetWidth
	offsetHeight

	offsetLeft
	offsetTop
	// alert(oDiv.offsetWidth); //width + border + padding (眼睛能看到的实际的宽)
	// alert(oDiv2.offsetLeft); //眼睛能看到实际距离第一个有定位的父节点的距离。
(12)、文档碎片
	先创建好10W个节点,将10W节点查入到一个节点上,最后将这1个节点添加到页面上
(13)、遍历
	数组:
		for循环
		for...in快速遍历
		forEach

		var arr = [10, 20, 30, 40, 50];
        for(var i = 0; i < arr.length; i++){
            document.write("for, " + i + ", " + arr[i] + "
"); } for(var i in arr){ document.write("forin, " + i + ", " + arr[i] + "
"); } arr.forEach(function(item, index, arr){ document.write("forEach, " + index + ", " + item + "
"); }); 对象: 对象遍历 for...in

5、event事件上
(1)、绑定事件
1、内联模式
2、外联模式/脚本模式(最多)

	绑定事件格式:
		元素节点.on + 事件类型 = 匿名函数。

		click   事件类型
		onclick 事件处理的函数
(2)、事件类型的种类:
	一、鼠标事件(可以绑定在任意的元素节点上)
		click      单击
		dblclick   双击
		mouseover  鼠标移入 
		mouseout   鼠标移出
		mousemove  鼠标移动(会不停的触发)
		mousedown  鼠标按下
		mouseup    鼠标抬起
		mouseenter 鼠标移入
		mouseleave 鼠标移出

		【注】经过子节点会重复触发。
			mouseover
			mouseout

		【注】经过子节点不会重复触发。IE8以后才有。
			mouseenter
			mouseleave

	二、键盘事件
		keydown    键盘按下(如果按下不放手,会一直触发)
		keyup      键盘抬起
		keypress   键盘按下(只支持字符键)(如果按下不放手,会一直触发)
		
	三、HTML事件
		1、window事件
			load    当页面加载完成以后会触发
			unload  当页面解构的时候触发(刷新页面,关闭当前页面)  IE浏览器兼容
			scroll  页面滚动
			resize  窗口大小发生变化的时候触发
		2、表单事件 绑定表单
			blur   失去焦点
			focus  获取焦点
			select 当我们在输入框内选中文本的时候触发
			change 当我们对输入框的文本进行修改并且失去焦点的时候
		【注】必须添加在form元素上
			submit 当我们点击submit上的按钮才能触发
			reset  当我们点击reset上的按钮才能触发
(3)、事件绑定
		元素节点.on + 事件类型 = 匿名函数;
	【注】系统会在事件绑定一旦完成的时候,生成一个事件对象。

	【注】触发事件的时候,系统会自动去调用事件绑定的函数。将事件对象当做第一个参数传入。
	oBtn.onclick = function(ev){
		//事件对象获取的方式,固定写法。
		var e = ev || window.event;
		alert(e);
	}
(4)、鼠标事件对象的属性
	事件对象:
		button 的属性
			0  左键
			1  滚轮
			2  右键
	
	获取当前鼠标位置:(原点位置不一样)
		clientX  clientY  原点位置:可视窗口的左上角为原点
		pageX    pageY    原点位置:整个页面的左上角(包含滚出去的滚动距离)
		screenX  screenY  原点位置:电脑屏幕的左上角

	document.onmousedown = function(ev){
		var e = ev || window.event;
		// alert(e.button);

		alert(e.clientX + ", " + e.clientY);
		// alert(e.pageX + "," + e.pageY);
		alert(e.screenX + ", " + e.screenY);
	}
(5)、跟随鼠标提示框
(6)、修改键 特殊键 shiftKey ctrlKey altKey metakey
	事件对象的四个修改键:
		var e = ev || window.event;
		e.shiftKey

		shiftKey  如果按下shift键,值就是true,否则是false
		ctrlKey
		altKey
		metakey (windows键  mac电脑下command键)
(7)、键码和字符码
	键码:只在keydown下支持。
		【注】不管是在大写字母还是小写字母的情况下,返回的统一都是大写字母的ASIIC码值。
			keyCode
			which
		var which = e.keyCode || e.which;
	
	字符码: 只在keypress下支持
		【注】区分大小写,并且按下的时候我当前按下这个键的ASCII码值。
		【注】
			charCode
			which
		var which = e.charCode || e.which;
(8)、微博发布功能
(9)、案例 方向键移动方块
(10)、目标对象target和this	(事件绑定)
	target   目标对象/触发对象  事件对象的属性
	【注】这个事件是由谁而起的。
	IE8以下不兼容 window.event.srcElement;
	var target = e.target || window.event.srcElement;

	this 永远指向当前函数的主人。
(11)、事件冒泡 (阻止事件冒泡)
	浏览器上事件天生的一个特点:事件流
		事件冒泡:由里向外逐级触发。
		事件捕获:由外向里逐级触发。

		阻止事件冒泡:浏览器兼容问题
		事件对象的属性和方法:
		cancelBubble=true        stopPropagation()
	var e = ev || window.event;
	tool.js 中stopBubble(e);
(12)、跟随鼠标移动
(13)、判断手机号码格式
(14)、案例 模拟下拉菜单
(15)、案例 动态生成表格
(15)、案例 ctrl+回车提交
(16)、案例 只能输入数字
(17)、案例 弹出右键菜单
	document.oncontextmenu
(18)、案例 弹出菜单
(19)、案例 隔行变色及划入隔行变色

5、event事件下
(1)、阻止右键菜单
document.oncontextmenu = function(){
return false;
}

	/* 
		实现自定义的右键菜单,鼠标按下
		按下的是右键  在右键这个位置显示菜单
		如果按下是别的键, 菜单消失
	*/
		
(2)、阻止超链接的默认行为
	/* 
	阻止超链接的默认行为:
		1、简陋的阻止a链接默认行为的方式
			缺点:运行到了return,后续的内容我们就执行不到了。
		2、规范的方法
			e.preventDefault();   W3C
				window.event.returnValue = false;  低版本IE浏览器
	*/
	调用 
		var e = ev || window.event;
		preDef(e);
	tool.js 下preDef(e);
(3)、当前窗口的高和宽
	//输出当前窗口的高
	/* var windowWidth = document.documentElement.clientWidth || document.body.clientWidth;
	alert(windowWidth); */

	var windowHeight = document.documentElement.clientHeight || document.body.clientHeight;
	alert(windowHeight);
(4)、拖拽 限制出界
	拖拽:(拖拽的三剑客)  伪代码(代码草稿)
		mousedown
			记录鼠标按下位置和被拖拽物体相对距离
			var offsetX = e.clientX - node.offsetLeft;
			var offsetY = e.clientY - node.offsetTop;
		mousemove
			一致保持,相对距离
			node.style.left = e.clientX - offsetX + 'px';
			node.style.top = e.clientY - offsetY + 'px';
		mouseup
			取消拖拽
	限制拖拽
		调用
		var oDiv = document.getElementById("div1");
		limitDrag(oDiv);
	tool.js -> limitDrag(oDiv)
(5)、事件委托
 	/* 
		委托:
			A委托B去买饭。
			A发布任务  委托方
			B执行任务  代理方
	*/
	/* 
		事件委托实现步骤:
			1、找到当前节点的父节点或者祖先节点
			2、将事件添加到你找到的这个父节点或者祖先节点上
			3、找到触发对象,判断触发对象是否是想要的触发对象,进行后续的操作
		
		li委托ul将li变成红色

			1、浪费
			2、后添加的li节点没有点击事件
		【注】事件委托的原理是事件冒泡。
	ar oUl = document.getElementById("ul1");
	oUl.onclick = function(ev){
		var e = ev || window.event;
		var target = e.target || window.event.srcElement;
		if(target.nodeName.toLowerCase() == "li"){
			target.style.backgroundColor = 'red';
		}
	}
	var obtn = document.getElementById("btn1");
	var i = 6;
	obtn.onclick = function(){
		var newNode = document.createElement("li");
		newNode.innerHTML = i++ * 1111;
		oUl.appendChild(newNode);
	}
(6)、微博发布拖拽
(7)、事件监听器 一个事件可触发多个函数

	事件监听器兼容 tool.js -> addEvent(node, evenType, funcName) 
							removeEvent(node, eventType, funcName)
	/* 
		attachEvent()和 detachEvent()
	*/
		function addEvent(node, evenType, funcName){
			if(node.addEventListener){
				node.addEventListener(evenType, funcName, false);
			}else{
				node.attachEvent("on" + evenType, funcName);
			}
		}

		function removeEvent(node, eventType, funcName){
			if(node.removeEventListener){
				node.removeEventListener(eventType, funcName);
			}else{
				node.detachEvent("on" + eventType, funcName);
			}
		}

	/* 
		1、传统事件绑定
			<1>重复添加,覆盖
			<2>不能精确的删除事件上的某一个函数

		2、事件监听器(低版本IE浏览器下不兼容)
			addEventListener()
				格式:node.addEventListener("click")
				参数:
					第一个参数  事件类型
					第二个参数  绑定函数
					第三个参数  布尔值  true  事件捕获
										false 事件冒泡  默认
										捕获冒泡指点击子节点
			removeEventListener()
				格式:node.removeEventListener()
				参数:
					第一个参数  事件类型
					第二个参数  删除函数名字 不可少
				有函数名才能删除
	*/
	【注】没函数名称 添加多次相同有多个
		有函数名称 添加多次只相当于一次
	aBtns[1].addEventListener("click", function(){
		alert("原有的函数");
	}, false);

	aBtns[0].onclick = function(){
		aBtns[1].addEventListener("click", show, false);
	}

	aBtns[2].onclick = function(){
		aBtns[1].removeEventListener("click", show);
	}

(8)、动态生成表格
(9)、案例 放大镜

6、正则表达式
(1)、创建正则表达式
1、通过new去声明正则表达式
第一个参数:正则表达式的主体 字符串
第二个参数:修饰符
i
g
【注】修饰符没有顺序

2、省略new运算符去声明正则表达式

3、通过常量赋值
var box1 = new RegExp("hello", "ig");
var box1 = RegExp("hello", "ig");
var box1 = /hello/gi;

正则表达式对象只有两个方法
test
	格式:正则.test(字符串)
	功能:在字符串中匹配这个正则是否存在
	返回值:如果匹配成功返回true,匹配失败返回false。

exec(了解  W3C)
	格式:正则.exec(字符串)
	功能:在字符串中匹配这个正则是否存在
	返回值:返回匹配到的串,匹配成功,返回一个装有字符串的数组 只匹配找到的第一个
						匹配失败,返回null
alert(box.test(str));
alert(box.exec(str)[0]);

(2)、在字符串中使用正则的方法
/*
字符串的函数:
match()
格式:字符串.match(正则)
功能:在字符串匹配是否有符合正则表达式,
返回值:匹配成功,返回装有匹配到子串的数组 加g所有
匹配失败,返回null
replace()
格式:字符串.replace(oldStr/正则, newStr);
功能:用newStr将oldStr替换,
返回值:替换成功的新字符串。 加g替换所有
split()
格式:字符串.split(分割符/正则);
功能:用分割符将原字符串进行分割
返回值:分割剩下的子串组成的数组。 分割所有

	search()
		格式:字符串.search(子串/正则)
		功能:找到符合条件的子串第一次出现的位置
		返回值:
			如果找到,返回>=0的下标
			否则,返回-1
	*/

(3)、正则_元字符
元字符:在正则表达式中有特殊含义的字符。

单个数字和字符的元字符
	.          匹配单个的任意字符
	[范围]         匹配单个范围内的字符
	[0-9]
	[a-zA-Z0-9_] 匹配单个的数字、字母下划线
	[^范围]        匹配任意一个除括号范围内的字符
	[^0-9]     匹配任意一个非数字字符
	\w         匹配单个的数字、字母下划线  等价于 [a-zA-Z0-9_]
	\W         匹配单个非数字、字母下划线
	\d         匹配单个数字  等价于 [0-9]
	\D         匹配单个非数字  等价于 [^0-9]


空白字符
	\s   匹配任意单个的空白字符
	\S   匹配任意单个非空白字符


重复字符  x(任意的单个字符)
	x?    匹配0个或者1个x
	x+    匹配至少一个x字符
	x*    匹配任意个x字符
	x{m,n}匹配至少m个,最多n个x字符,包括n
	x{n}  必须匹配n个x字符
	(xyz)+ 小括号括起来的部分是当做单个字符处理

锚字符
	^  行首匹配  必须以这个正则开头
	$  行尾匹配  必须以这个正则结尾

(4)、正则补充
替代字符 | 选择其一
var box = /google|baidu|bing/;
修饰符
i 忽略大小写
g 全局匹配
m 换行匹配
【注】如果在字符串,遇到换行,重新开始计算行首。

	var str = "1、ba13idu\n2、go33ogle\n3、b12ing";
	var box = /^\d/gm;
	alert(str.replace(box, "*"));

(5)、正则练习 验证压缩包 手机号码 身份证号码 纯中文
转义字符:
. 代表本来.字符的意思
* 代表本来*字符的意思

	/* 
		文件是否是压缩包
		zip  rar  gz
	*/

    var box = /^\w+\.(zip|rar|gz)$/;
    alert(box.test("hello.zip")) 

	/* 
		验证是否是正确的手机号码
	*/
    //   var box = /^1\d{10}$/;

    /* 
        验证是否是正确的身份证号码
    */
    // var box = /^[1-9]\d{16}(\d|x)$/;

    /* 
        验证字符串是否是纯中文
    */
    var box = /^[\u4e00-\u9fa5]+$/;
    alert(box.test("我爱北京啊大大"))

(6)、注册表单验证(正则)
(7)、localStorage本地存储技术
本地存储技术:
localStorage(IE8以下不兼容)
1、永久存储
2、最大可以存储5M 客户端的一个微型数据库
3、只能存储string
cookie
1、可以设置过期时间
2、最大可以存4KB
3、每一个域名下面最多可以存储50条数据
sessionStorage(结合后台使用)

	localStorage 对象
		setItem(name, value);
		getItem(name);
		removeItem(name);

	alert(localStorage.getItem("b"));
	alert(localStorage.c);
	alert(localStorage['a'])

(8)、案例 滑动条slide 关闭浏览器后存储当前位置

7、ECMA5和ECMA6
(1)、认识this
/*
每一个函数中都有一个内置的变量this,this指向当前函数的主人,函数的主人要根据上下文关系进行判断。
【注】this指向当前函数的主人。
*/
// 常见this,一般情况下是下面三种情况

//1、全局函数
/*  function show(){
	alert(this); //[object Window]
}

(2)、强制数据类型转换 改变this指向对象
/*
call
格式:函数名.call();
参数:
第一个参数:传入该函数this指向的对象,传入什么强制指向什么
第二个参数开始:将原函数的参数往后顺延一位。
*/

//  show.call("call", 20, 40);

/* 
	apply
		格式:函数名.apply()
		参数:  
			第一个参数:传入该函数this指向的对象,传入什么强制指向什么
			第二个参数:数组  数组,放入我们原有所有的参数
*/
//  show.apply("apply", [20, 40]);

/* 
	bind   预设this指向
	调用不执行 除非添加参数才执行
	show.bind("bind")(40, 50);
*/
/* function show(x, y){
	alert(this);
	alert(x + ", " + y);
}
var res = show.bind("bind");

/* 
	apply方法使用的小技巧
*/
//  Math.min();  //传入所有参数中的最小值
//  Math.max();  //传入所有参数中的最大值

(3)、let关键字
let 关键字是用来声明变量 更过分,只要遇到大括号就形成作用域
【注】let关键字声明的变量,所在作用域叫做块级作用域。

var 关键字声明变量  将变量或者形参所在函数的大括号作为作用域处理。

(4)、const关键字
/*
const 声明变量,变量值只能在声明的时候确定,后续是没有办法修改的。
【注】const声明常量(变量没有办法改);
/
const IP = “10.30.152.33”;
(5)、箭头函数
/

箭头函数:新潮的函数写法。
【注】适当的省略函数中的function和return关键字。
*/
var add = x => x + 10;
alert(add(5));

/* 
	各种形式的箭头函数
*/

//1、无参数,无返回值
var show = () => {
	alert("hello world");
}

//2、有一个参数,无返回值
var xxx = num => {
	alert(num);
}

//3、有一个参数,有返回值
var add = x => {
	//代码
	return x + 10;
};

//4、多个参数,无返回值
var show = (x, y) => {
	alert(x + y);
}

(6)、箭头和ECMA5数组方法结合 filter 箭头函数this指向的是上一层函数的主人
/*
filter 过滤
/
var arr = [10, 20, 30, 40, 50];
/
var newArr = arr.filter(function(item){
return item > 20;
}) */

/*  var newArr = arr.filter(item => item > 20);
	alert(newArr); */

/*  var newArr = arr.map(item => item * 1.3);
	alert(newArr); */

箭头函数需要注意的部分
1、箭头函数,不能用new
2、箭头,如果返回值是一个对象,一定要加{};
3、箭头函数中的this,指向的是上一层函数的主人。

(7)、解构
/*
中括号解构
大括号解构
*/
使用解构的好处:
1、交换两个数
2、函数可以返回多个值
3、函数定义参数,和传入参数的顺序改变
【注】参数可以带默认值
4、快速取出数组中的某一个元素。
var arr = [10, 20, 30, 40, 50];
var {0:first, 4:last} = arr;
alert(first);
alert(last == arr[4]);

/* function showSelf({name, age, sex = "男"}){
	alert("我叫" + name + ",今年" + age + ",是一位" + sex + "性");
}
showSelf({
	age: 18,
	name: "小明",
	sex: "女"
}) */

(8)、ECMA6字符串 /* 传统字符串:所有单引号,双引号括起来的都叫做字符串。 ECMA6字符串:反引号
1、ECMA6字符串,想怎么写怎么写,换行,代码缩进,都能在字符串中体现出来
2、${变量/表达式/函数调用}
/
(9)、ECMA6新增数组方法 Array.from() find() findIndex() arr.copyWithin
Array.from() 将伪数组转成真数组
/

find()

	功能:在数组中查找符合条件的元素,只要找到第一个符合条件的元素,就终止遍历。
	返回值:找到的元素。

	findIndex()
	返回值:找到的元素的下标。
*/

// var arr = [10, 20, 30, 40, 50];
/*  var res = arr.find(function(item, index, arr){
	//查找条件
	return item > 20;
})
alert(res); */

// alert(arr.find(item => item > 20));

// alert(arr.findIndex(item => item > 20));

/* 
	arr.copyWithin
	第一个参数:从哪个下标开始
	第二个参数和第三个参数是:范围 [start, end)
*/
var arr = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
arr.copyWithin(2, 4, 9);
//1,2,5,6,7,8,9,8,9,10

(10)、合并对象 Object.assign()
/*
Object.assign 合并对象 浅拷贝
【注】将所有传入的对象,都合并到第一个对象中。

	浅拷贝:只拷贝地址
	深拷贝:将复合数据类型重新生成一份,进行拷贝
*/
Object.assign(obj1, obj2, obj3);

(11)、集合 set
/*
集合: 键值相同
1、不重复
2、无序
Set
Map
*/
let imgs = new Set();
//添加元素
imgs.add(100);
imgs.add(100);
imgs.add(“hello”);
imgs.add(“hello”);
imgs.add(true);
//new 生成两对象不同可同时存在
imgs.add(new String(“world”));
imgs.add(new String(“world”));

/* 
	集合遍历	键值相同
	for...of 遍历集合
*/
/* for(let item of imgs.keys()){
	console.log(item);
} */

/*  for(let item of imgs.values()){
	console.log(item);
} */

//imgs.entries	键值相同
/* for(let item of imgs.entries()){
	console.log(item);
} */

//数组变集合
var set = new Set([10, 20, 30, 40, 50, 40, 30, 20, 10]);
	console.log(set);

//集合变数组  将数据结构展开成数组
var arr = [...set];
alert(arr); 

var arr = [10, 20, 30, 40, 50, 40, 30, 20, 10];
arr = [...new Set(arr)];
alert(arr);

(12)、集合 map
/*
map映射
*/
let map = new Map();

//添加数据
map.set("张三", "打渔的");
map.set("李四", "种地的");
map.set("王五", "挖煤的");

alert(map.get("王五"));

/* 
	map遍历  通过for of
*/
for(let [key,value] of map){ 
	console.log(key,value);
}

(13)、英汉词典
(14)、Symbol
/*
Symbol
【注】通过Symbol声明的数据只和自己相等,和其他任何数据都不相等。
【注】让你的程序变得可读性更强,更加形象化的。
/
/
var a = Symbol();
var b = Symbol();
var c = Symbol(100);
var d = Symbol(100);
var e = Symbol(“hello”);
var f = Symbol(“hello”); */

/* alert(a == b);
alert(c == d);
alert(e == f); */

8、面向对象
(1)、遍历
/*
数组
for循环
for…in
foreach
for…of

	对象
		for...in

	set  for...of
	map  for...of
*/
var arr = [10, 20, 30, 40, 50];
for(var i = 0; i < arr.length; i++){
	document.write("for循环:" + arr[i] + ", " + i + "
"); } for(var i in arr){ document.write("for...in遍历:" + arr[i] + ", " + i + "
"); } arr.forEach(function(item, index){ document.write("forEach:" + item + ", " + index + "
"); }) //通过for...of遍历数组 for(var item of arr){ /* item是当前遍历到的元素 */ document.write("for...of:" + item + "
"); } var person = { username: "钢铁侠", age: 20, sex: "男" }; for(var attr in person){ /* attr 遍历到的对象的属性 */ document.write("对象:" + attr + person[attr] + "
"); }

(2)、创建对象 (未优化)
【注】构造函数一般情况下首字母大写
/*
1、创建了一个有名字和有性别的人
2、如果现在想要再创建一个叫red的女人
*/
var p1 = new Object();
p1.name = “blue”;
p1.sex = “男”;
p1.showName = function(){
alert(“我的名字叫” + this.name);
}
p1.showSex = function(){
alert(“我的性别是” + this.sex + “的”);
}

p1.showName();
p1.showSex();

/* 
	工厂模式:
		1、原料
		2、加工
		3、出厂
	【注】凡是满足上述三个步骤创建对象的函数,我们把它叫做工厂方法。
*/

function createPerson(name, sex){
	//1、原料
	var obj = new Object();

	//2、加工
	obj.name = name;
	obj.sex = sex;
	obj.showName = function(){
		alert("我的名字叫" + this.name);
	}
	obj.showSex = function(){
		alert("我的性别是" + this.sex + "的");
	}

	//3、出厂
	return obj;
}

var p1 = createPerson("blue", "男");

/*
	如果,我们某一个函数,使用new运算符去调用
		1、当前函数中的this指向新创建的对象
		2、自动去完成1、原料和3、出厂操作

	这种通过new调用函数,我们把它叫做构造函数,构造函数可以构造对象,
	【注】构造函数一般情况下首字母大写
*?

function Person(name, sex){
	//1、原料
	// var obj = new Object();
	// this = new Object();

	//2、加工
	this.name = name;
	this.sex = sex;
	this.showName = function(){
		alert("我的名字叫" + this.name);
	}
	this.showSex = function(){
		alert("我的性别是" + this.sex + "的");
	}

	//3、出厂
	// return obj;
	//return this;
}

var p1 = new Person("blue", "男");

/* 
	想要给数组添加一个方法,可以对数组中每一个元素进行求和
*/
arr1.sum = function(){
	var res = 0;
	for(var i = 0; i < this.length; i++){
		res += this[i];
	}
	return res;
}

(3)、prototype原型
/*
prototype 原型对象
概念:每一个函数上,都有一个原型对象prototype

	用在构造函数上,我们可以给构造函数的原型prototype,添加方法
	1、如果我们将方法添加到构造函数的原型prototype对象上,
	2、构造函数构造出来的对象共享原型上所有的方法。
*/

var arr1 = [10, 20, 30, 40, 50];
var arr2 = [1, 2, 3, 4, 5];

Array.prototype.sum = function(){
	var res = 0;
	for(var i = 0; i < this.length; i++){
		res += this[i];
	}
	return res;
}

alert(arr1.sum());

(4)、混合法 创建prototype原型对象
function Person(name, sex){
this.name = name;
this.sex = sex;
}

//Person构造函数添加方法,添加在构造函数的原型上prototype
Person.prototype.showName = function(){
	alert("我的名字" + this.name);
}
Person.prototype.showSex = function(){
	alert("我的性别" + this.sex);
}



var p1 = new Person("blue", "男");
p1.showName();
p1.showSex();


var p2 = new Person("red", "女");
p2.showName();
p2.showSex();

alert(p1.showName === p2.showName); //true

(5)、构造函数构造出来的对象__proto__
构造函数构造出来的对象,有一个属性__proto__,指向构造出这个对象的构造函数的原型。
instanceof 关键字
功能:判断某一个对象是否是这个构造函数构造出来的。

Dog.prototype = {
	run: function(){
		alert(this.name + "会飞快的奔跑");
	},
	showSelf: function(){
		alert(`这是一个${this.type}的,${this.age}岁的,叫${this.name}的小狗`);
	}
}

var xiaobai = new Dog({
	name: "小白",
	type: "比熊",
	age: 3
});
alert(xiaobai instanceof Dog);//true
alert(xiaobai instanceof Object);//true
alert(xiaobai.__proto__ === Dog.prototype);//true
alert(xiaobai.__proto__ === xiaohei.__proto__); //true

(6)、面向对象的语法 (继承、封装、多态)
/*
面向对象,继承、封装(封装构造函数)、多态。

	面向对象是一个编程思想,支撑面向对象编程思想的语法是类(ECMA6之前没有类这个概念)和对象,构造函数充当类的角色。
构造函数和对象实现面向对象程序的时候,体现出 继承、 封装、 多态的特点。
*/

a、继承
	原型链 继承父一级的方法
	<1>通过for...in遍历继承
		/* for(var funcName in Person.prototype){
			Worker.prototype[funcName] = Person.prototype[funcName];
		} */
	<2>Object.create()
		// Worker.prototype = Object.create(Person.prototype);
	<3>调用构造函数继承
		Worker.prototype = new Person();

	function Dog({name, type, age}){
		//this = new Object();
		//添加属性
		this.name = name;
		this.type = type;
		this.age = age;
	}
	/* 
		通过构造函数的原型添加方法
		*/
		Dog.prototype = {
			run: function(){
				alert(this.name + "会飞快的奔跑");
			},
			showSelf: function(){
				alert(`这是一个${this.type}的,${this.age}岁的,叫${this.name}的小狗`);
			}
		}
		/* 
		分类更加细分的构造函数。继承
		*/
	function Teddy({name, type, age, color}){
		//this = new Object();
		//1、继承父一级构造函数所有的属性
		//构造函数的伪装
		Dog.call(this, {
			name: name,
			type: type,
			age: age
		})
		//添加自己的属性
		this.color = color;

		//return this;
	}

	/* 
		原型链继承
		*/
	// Teddy.prototype = Dog.prototype;  非常错误的写法
	for(var funcName in Dog.prototype){
		Teddy.prototype[funcName] = Dog.prototype[funcName];
	}


	Teddy.prototype.showColor = function(){
		alert(this.color);
	}
b、多态
	//在子一级构造函数重写showSelf方法
	/* 
		只会在子一级生效,并不会影响父一级构造函数的方法。

		继承和多态同一件事情的两种完全不同的侧重:
		继承:侧重是从父一级构造函数,继承到的属性和方法。
		多态:侧重是,子一级,自己重写和新增的属性和方法。
	*/

	for(var funcName in Dog.prototype){
		Teddy.prototype[funcName] = Dog.prototype[funcName];
	}

	//在子一级构造函数重写showSelf方法
	
	Teddy.prototype.showSelf = function(){
		alert(`这是一个${this.type}的,${this.age}岁的,是${this.color}的,叫${this.name}的小狗`);
	}

	Teddy.prototype.showColor = function(){
		alert(this.color);
	}

(7)、对象拷贝
//浅复制 复制地址
var obj2 = obj1;
//深复制
for(var attr in obj1){
obj2[attr] = obj1[attr];
}

(8)、ECMA6class语法
原型链 继承父一级的方法
<1>通过for…in遍历继承
/* for(var funcName in Person.prototype){
Worker.prototype[funcName] = Person.prototype[funcName];
} */
<2>Object.create()
// Worker.prototype = Object.create(Person.prototype);
<3>调用构造函数继承
Worker.prototype = new Person();

ECMA6class语法
class Person{
	//class属性添加
	constructor(name, sex, age){
		this.name = name;
		this.sex = sex;
		this.age = age;
	}
	showSelf(){
		alert(`我是一个叫${this.name},今年${this.age}岁的${this.sex}孩`);
	}
}

var p1 = new Person("blue", "男", 18);
p1.showSelf();

//extends 继承
class Worker extends Person{
	constructor(name, sex, age, job){
		//1、继承到父一级的属性
		super(name, sex, age);
		this.job = job;
	}
	showJob(){
		alert("我的工作是" + this.job);
	}
}

var w1 = new Worker("小米", "男", 20, "程序员");
w1.showSelf();
w1.showJob();

(9)、this指向问题
1、var _this = this;
2、oBtn.onclick = this.show.bind(this);
(10)、选项卡 面向对象
(11)、拖拽 限制拖拽 面向对象
tool.js -> Drag(id)
LimitDrag(id)
9、运动和游戏开发上
(1)、运动基本流程
/*
运动原理:
人眼能够识别的最小的时间间隔是18帧。
【注】电影院电影24帧。

	运动里面的Bug
		1、运动不会停止
		2、当我们速度取某些值的时候,我们的运动到达目的值是停不下来的。
		3、当重复点击按钮的时候,滑块移动的越来越快
			【注】在每一次启动定时器之前,将上一次定时器关闭掉。
		4、到达目的值以后,再次点击按钮,div会向前运动。
			【注】将运动和停止分开。

	运动框架:
		1、在每一次启动定时器之前,将上一次定时器关闭掉。
		2、将运动和停止分开。
*/
window.onload = function(){
	var oBtn = document.getElementById("btn1");
	var oDiv = document.getElementById("div1");
	var timer = null;
	oBtn.onclick = function(){
		var speed = 7;
		clearInterval(timer);
		timer = setInterval(function(){
			if(oDiv.offsetLeft >= 500){
				clearInterval(timer);
			}else{
				oDiv.style.left = oDiv.offsetLeft + speed + 'px';
			}
			
		}, 30);
	}
}

(2)、侧边浮动菜单栏
oMenu.onmouseenter = function(){
//-100 => 0
startMove(0);
}
oMenu.onmouseleave = function(){
//0 => -100
startMove(-100);
}

var timer = null;
function startMove(iTarget){
	var oMenu = document.getElementById("menu");
	var speed = 10;
	//1、每次启动定时器将上一次定时器关闭
	clearInterval(timer);
	timer = setInterval(function(){
		if(oMenu.offsetLeft < iTarget){
			speed = Math.abs(speed);
		}else{
			speed = -Math.abs(speed);
		}

		//2、运动和停止分开
		if(oMenu.offsetLeft == iTarget){
			clearInterval(timer);
		}else{
			oMenu.style.left = oMenu.offsetLeft + speed + 'px';
		}
	}, 30);
}

(3)、淡入淡出
oImg.onmouseenter = function(){
//30 => 100
startMove(100);
}
oImg.onmouseleave = function(){
//100 => 30
startMove(30);
}

/* 
	类似于透明度这类型的css属性,使用中间变量替代计算。
	*/
var alpha = 30;
var timer = null;
function startMove(iTarget){
	var oImg = document.getElementById("img1");
	var speed = 2;
	clearInterval(timer);
	timer = setInterval(function(){
		if(alpha > iTarget){
			speed = -Math.abs(speed);
		}else{
			speed = Math.abs(speed);
		}
		//1、取当前值
		if(alpha == iTarget){
			clearInterval(timer);
		}else{
			alpha += speed;
			//給当前图片上设置透明度,考虑浏览器兼容
			oImg.style.opacity = alpha / 100;
			oImg.style.filter = "alpha(opacity=" + alpha + ")";
			document.title = alpha;
		}
	}, 30);
	
}

(4)、缓冲运动 正反向
/*
缓冲运动

	var speed = 距离;
	var speed = (iTarget - iCur) / 8;
	【注】被除的这个数8,可以换成任意的数,8经过长期试验,缓冲运动效果最好的一个数。

	速度:0.375   计算机最小能够识别的像素是一像素。
*/
oBtn.onclick = function(){
	startMove(500);
}

var timer = null;
function startMove(iTarget){
	var oDiv = document.getElementById("div1");
	var oTxt1 = document.getElementById("txt1");

	clearInterval(timer);
	timer = setInterval(function(){
			//计算速度
		var speed = (iTarget - oDiv.offsetLeft) / 8;
		speed = speed > 0 ? Math.ceil(speed) : Math.floor(speed);

		if(oDiv.offsetLeft == iTarget){
			clearInterval(timer);
		}else{
			oDiv.style.left = oDiv.offsetLeft + speed + 'px';
			txt1.value += oDiv.offsetLeft + ", " + speed + "\n";
		}
	}, 30);
}

(5)、缓冲菜单
var scrollTop = document.documentElement.scrollTop || document.body.scrollTop;
var windowHeight = document.documentElement.clientHeight || document.body.clientHeight;
var iH = parseInt(scrollTop + (windowHeight - oMenu.offsetHeight) / 2);

startMove(iH);


window.onscroll = function(){
	var scrollTop = document.documentElement.scrollTop || document.body.scrollTop;
	var windowHeight = document.documentElement.clientHeight || document.body.clientHeight;
	var iH = parseInt(scrollTop + (windowHeight - oMenu.offsetHeight) / 2);

	startMove(iH);
}

(6)、多物体运动 淡入淡出
/*
原因是:我们整个页面上只有一个定时器。
解决:让每一个运动的物体,独立拥有自己的定时器。
/
for(var i = 0; i < aDivs.length; i++){
aDivs[i].onmouseover = function(){
startMove(this, 300);
}
aDivs[i].onmouseout = function(){
startMove(this, 100);
}
}
/

中间变量:多个物体在进行透明度变化的时候,公用的是一个中间变量。
结论:任何的变量在多物体运动中,都不能共用。
/
for(var i = 0; i < aDivs.length; i++){
aDivs[i].alpha = 30; // 中间变量
aDivs[i].onmouseover = function(){
startMove(this, 100);
}
aDivs[i].onmouseout = function(){
startMove(this, 30);
}
}
(7)、offset系列问题
// parseInt() npx -> n
offsetWidth //width + border + padding (眼睛能看到的实际的宽)
/

offset不满足运动要求
接下来,实现运动的函数里面,都用getStyle方法来获取当前有效样式。
tool.js -> getstyle
/
setInterval(function(){
//获取当前值
var iCur = parseInt(getStyle(oDiv, “width”));
alert(iCur);
oDiv.style.width = iCur - 1 + ‘px’;
}, 30);
(8)、链式运功
/

链式运动:
在第一个动画结束的时候,开始第二个动画。
【注】关键点,找到第一个动画结束的时候。
/
var aDivs = document.getElementsByTagName(“div”);
aDivs[0].onmouseover = function(){
startMove(this, “width”, 300, function(){
startMove(this, “height”, 300, function(){
startMove(this, “opacity”, 100);
})
});
}
aDivs[0].onmouseout = function(){
startMove(this, “opacity”, 30, function(){
startMove(this, “height”, 100, function(){
startMove(this, “width”, 100);
})
});
}
tool.js -> startMove(node, attr, iTarget, complete)
(9)、回调函数 (总结)
/

1、认识运动(运动框架)
<1>每次启动定时器,将上一次定时器关闭
<2>运动和停止 if…else
2、分享到菜单和淡入淡出
startMove(iTarget);
3、缓冲运动
var speed = (iTarget - iCur) / 8;
speed = speed > 0 ? Math.ceil(speed) : Math.floor(speed);
4、多物体运动
node.timer;
多物体淡入淡出:任何一个变量都不能公用
startMove(node, iTarget);
5、多物体多样式运动
offset系列 透明度
startMove(node, attr, iTarget);
6、链式运动
startMove(node, attr, iTarget, complete)
7、完美运动
startMove(node, cssObject, complete);
/
(10)、碰撞
/

逆向思维:什么情况下,两个物体绝对碰不到。
if(konck(node1, node2))
node1 球 碰撞方
node2 板 被碰撞方
碰了 return true
*/
tool.js -> konck(node1, node2)
(11)、案例 打砖块
(12)、案例 微信打飞机

10、运动和游戏开发下
(1)、圆周运动
/*
画圆的步骤:(圆规画圆)
1、确定圆心
2、确定半径
3、旋转(顺时针)

	1弧度 = 180 / Math.PI;
*/
var oDiv = document.getElementById("div1");

var X = 500;
var Y = 400;

var r = 100;
var i = 0; //代表转过的弧度
setInterval(function(){
	i++;
	var radian = i * Math.PI / 180;
	var a = Math.sin(radian) * r;
	var b = Math.cos(radian) * r;

	oDiv.style.left = X + a + 'px';
	oDiv.style.top = Y - b + 'px';

	
	//显示当前圆周运动的轨迹
	var node = document.createElement("div");
	node.style.width = "5px";
	node.style.height = "5px";
	node.style.backgroundColor = 'black';
	node.style.position = 'absolute';
	node.style.left = oDiv.offsetLeft + 'px';
	node.style.top = oDiv.offsetTop + 'px';
	document.body.appendChild(node);

}, 30);

(2)、完美运动 多样式运动
/*
宽高透明度同时发生变化
*/
oDiv1.onmouseover = function(){
startMove(this, {
width: 300,
height: 102,
opacity: 30
}, function(){
alert(“动画结束了”);
});

}

oDiv1.onmouseout = function(){
	startMove(this, {
		width: 100,
		height: 100,
		opacity: 100
	});
}
tool.js -> startMove(node, cssObj, complete)

(3)、设置多条css样式
setStyle(this, {
width: “300px”,
height: “300px”,
backgroundColor: ‘blue’
})
tool.js -> setStyle(node, cssObj)
(4)、案例 打砖块
(5)、案例 banner图效果
(6)、案例 多图片缩放
(7)、案例 抛物线运动

/js/抛物线运动/.js 及参数详解



var oDiv1 = document.getElementById("div1");
var oDiv2 = document.getElementById("div2");
var aBtns = document.getElementsByTagName("button");
var oul1 = document.getElementById("ul1");

/* 
	创建一个抛物线对象
	*/
var bool = new Parabola({
	el: "#div1",
	targetEl: "#div2",
	duration: 2000,
	curvature: 0.003,
	callback: function(){
		alert("动画结束了");
	},
	stepCallback: function(){
		//在整个运动中不停的调用
		var node = document.createElement("li");
		node.style.left = oDiv1.offsetLeft + 'px';
		node.style.top = oDiv1.offsetTop + 'px';
		oul1.appendChild(node);
	}

})

aBtns[0].onclick = function(){
	bool.start();
}
aBtns[1].onclick = function(){
	bool.stop();
}
aBtns[2].onclick = function(){
	bool.reset();
}
aBtns[3].onclick = function(){
	bool.setOptions({
		targetEl: null,
		offset: [500, 300]
	})
}

(8)、案例 评分特效

11、PHP和ajax入门
(1)、认识ajax
/*
ajax 异步的 javascript和 xml(数据传输格式)
异步的 javascript 和 数据传输

	【注】ajax是前后端数据交互的搬运工,都可以异步执行。

	xml数据传输格式(大型的门户网站  新浪、网易、凤凰网)
		优点:
			1、种类丰富
			2、传输量非常大
		缺点:
			1、解析麻烦
			2、不太适合轻量级数据

	json数据传输格式(字符串) 95%移动端应用。
		优点:
			1、轻量级数据
			2、解析比较轻松
		缺点:
			1、数据种类比较少
			2、传输数据量比较小
		
	JSON.parse()
	JSON.stringify()

【注】任何一个程序都是由很多个小程序组成的。
【注】用来描述一个程序运行状态。
	同步  阻塞,当前程序运行,必须等前一个程序运行完毕以后,才能运行。
	异步  非阻塞,当前程序运行,和前面程序的运行没有任何关系。
*/

(2)、ajax下载数据 非兼容
//1、创建ajax对象
var xhr = new XMLHttpRequest();

//2、调用open
/* 
	第一个参数: 请求方式  get post
	第二个参数:url
	第三个参数: 是否异步  
			true 异步
			false同步
	*/
xhr.open("get", "1.txt", true);

//3、调用send
xhr.send();

//4、等待数据响应
xhr.onreadystatechange = function(){
	if(xhr.readyState == 4){
		alert(xhr.responseText);
	}
}

(3)、ajax对象 兼容
/*
XMLHttpRequest IE8以下不兼容
IE8以下声明ajax的方法是
ActiveXObject(“Microsoft.XMLHTTP”);
*/
//1、创建ajax对象
var xhr = null;
if(window.XMLHttpRequest){
xhr = new XMLHttpRequest();
}else{
xhr = new ActiveXObject(“Microsoft.XMLHTTP”);
}

//2、调用open
/* 
	第一个参数: 请求方式  get post
	第二个参数:url
	第三个参数: 是否异步  
			true 异步
			false同步
	*/
xhr.open("get", "1.txt", true);

//3、调用send
xhr.send();

//4、等待数据响应
xhr.onreadystatechange = function(){
	if(xhr.readyState == 4){
		alert(xhr.responseText);
	}
}

(4)、try_catch
/*
try一出错触发catch 剩下的不执行
try{
尝试执行的代码
}catch(error){
error 错误对象,try括号中代码执行的异常信息;
补救代码;
}
执行过程:
1、先去执行try中的代码
2、如果try中的代码执行正常,catch中的代码就不执行了
3、如果try中的代码执行异常,直接执行catch中的代码进行补救

	【注】更多的用在代码调试和后期维护。

	try_throw_catch
	throw 手动抛出异常	剩下的不执行
	格式:
		try{
			尝试执行的代码
			throw new Error("异常信息文本")
		}catch(error){
			error 错误对象,try括号中代码执行的异常信息;
			补救代码;
		}
*/

(5)、ajax对象_兼容_try
/*
XMLHttpRequest IE8以下不兼容
IE8以下声明ajax的方法是
ActiveXObject(“Microsoft.XMLHTTP”);
*/
//1、创建ajax对象
var xhr = null;
try{
xhr = new XMLHttpRequest();
}catch(error){
xhr = new ActiveXObject(“Microsoft.XMLHTTP”);
}

//2、调用open
/* 
	第一个参数: 请求方式  get post
	第二个参数:url
	第三个参数: 是否异步  
			true 异步
			false同步
	*/
xhr.open("get", "1.txt", true);

//3、调用send
xhr.send();

//4、等待数据响应
xhr.onreadystatechange = function(){
	if(xhr.readyState == 4){
		alert(xhr.responseText);
	}
}

(6)、onreadystatechange
//4、等待数据响应
/*
readystatechange 事件类型
xhr.readyState 发生变化的时候调用
0 调用open方法之前
1 调用你send方法之后,发送请求
2 send方法完成,已经接受到所有的响应内容
3 正在解析下载到的数据
4 解析完成
*/
xhr.onreadystatechange = function(){
if(xhr.readyState == 4){
//判断本次下载的状态码都是多少
if(xhr.status == 200){
alert(xhr.responseText);
}else{
alert(“Error:” + xhr.status);
}
}
}
(7)、form表单的get请求
action 点击submit以后跳转到的url
method 表单的提交数据的方式
get(默认)
http://localhost/code14/1.get.php?username=xxxx&age=18&password=123abc
提交方式:是直接将数据拼接在url后面进行提交,通过?进行拼接,查询字符串
好处: 简单
缺点:
1、不安全
2、最大2kb
3、没法实现上传
post
–>






(8)、form表单的post请求
action 点击submit以后跳转到的url
method 表单的提交数据的方式
get(默认)
http://localhost/code14/1.get.php?username=xxxx&age=18&password=123abc
提交方式:是直接将数据拼接在url后面进行提交,通过?进行拼接,查询字符串
好处: 简单
缺点:
1、不安全
2、最大2kb
3、没法实现上传

			post
			提交方式:post提交通过浏览器内部进行提交。
			好处:
				1、安全
				2、理论上没有上限
				3、上传
			缺点:比get复杂

	-->

(9)、ajax get请求
//1、创建ajax对象
var xhr = null;
try{
xhr = new XMLHttpRequest();
}catch(error){
xhr = new ActiveXObject(“Microsoft.XMLHTTP”);
}

//2、调用open

xhr.open("get", "1.get.php?username=yyy&age=19&password=123abc", true);

//3、调用send
xhr.send();


//4、等待数据响应

xhr.onreadystatechange = function(){
	if(xhr.readyState == 4){
		//判断本次下载的状态码都是多少
		if(xhr.status == 200){
			alert(xhr.responseText);
		}else{
			alert("Error:" + xhr.status);
		}
	}
}

(10)、ajax post请求
//1、创建ajax对象
var xhr = null;
try{
xhr = new XMLHttpRequest();
}catch(error){
xhr = new ActiveXObject(“Microsoft.XMLHTTP”);
}

//2、调用open

xhr.open("post", "1.post.php", true);


//必须在send方法之前,去设置请求的格式
xhr.setRequestHeader("content-type", "application/x-www-form-urlencoded");

/* 
	post提交的数据,需要通过send方法进行提交

	?name1=value&name2=value2  search
	name1=value&name2=value2   querystring
	*/
//3、调用send
xhr.send("username=yyy&age=19&password=123abc");


//4、等待数据响应

xhr.onreadystatechange = function(){
	if(xhr.readyState == 4){
		//判断本次下载的状态码都是多少
		if(xhr.status == 200){
			alert(xhr.responseText);
		}else{
			alert("Error:" + xhr.status);
		}
	}
}

12、ajax进阶 mysql
(1)、mysql语法
/*
shell 壳
core 核
【注】shell编程。

	1、DOS界面:不是内部或者外部命令
		解决办法:配置环境变量。
		我的电脑右键 => 属性 => 高级系统设置 => 环境变量 => PATH

		处理服务器或者数据库链接失败
		我的电脑右键 => 管理 => 服务和应用程序 => 服务 => 启动程序

	2、登录mySQL
		mysql -u root -p  +  回车

		ctrl + C 终止当前程序

	3、查看数据库(接下来输入的mysql命令操作都要加分号)
		show databases;

	4、创建数据库
		create database db2 character set utf8;

	5、选择数据库
		use 数据库名字;

	6、创建表(一定要设置id))
		CREATE TABLE 表名(
			字段名1 数据类型,
			字段名2 数据类型,
			…
			字段名n 数据类型
			)character set 字符集 collate 校对规则;
	7、数据类型
		int    整形
		float  浮点数

		char(10)
		varchar(30)

		date  日期  "2000-01-01"

		text  文本(理论上没有上线)
	8、查看当前数据库下的表
		show tables;
	
	9、查看表结构
		desc 表名;

	10、插入操作
		INSERT INTO 表名(字段1, 字段2,...) VALUES(具体的值1, 具体的值2…);

	11、查找表下面所有的数据
		SELECT * FROM 表名;
	
	12、修改操作
		UPDATE 表名 SET 字段名1 =新值, 字段名2=新值... WHERE 条件;
	
	13、删除操作
		DELETE FROM 表名 WHERE 条件;
		【注】通过delete语句只会将表中的数据删除,并不会将整个表删除。
	14、删除表
		drop table 表名;
	15、删除数据库
		drop database [if exists] 数据库名;
	
	16、查询操作
		SELECT 字段1,字段2... FROM 表名 WHERE 条件;

	17、排序
		SELECT 字段名1,字段名2... FROM 表名 WHERE 条件 ORDER BY 字段 [asc|desc]
*/
/*
	【注】保证id不重复,设置id为这个表的主键(PrimaryKey) 选择id为AI(自动增加)
	id 学号
	name 姓名
	math
	english
	chinese
*/

(2)、ajax封装
get请求
$ajax({
url: “1.get.php”,
data: {
username: “xxx”,
age: 19,
password: “123abc”
},
success: function(result){
// alert(3);
alert(“GET请求下载到的数据:” + result);
},
error: function(msg){
alert(msg);
}
})
post请求
$ajax({
method: “post”,
url: “2.post.php”,
data: {
username: “xxx”,
age: 19,
password: “123abc”
},
success: function(result){
alert(“POST请求下载到的数据:” + result);
},
error: function(msg){
alert(msg);
}
})

/* 
	method
	url
	data
	success  数据下载成功以后执行的函数
	error    数据下载失败以后执行的函数
*/
function $ajax({method = "get", url, data, success, error}){
	//1、创建ajax对象
	var xhr = null;
	try{
		xhr = new XMLHttpRequest();
	}catch(error){
		xhr = new ActiveXObject("Microsoft.XMLHTTP");
	}

	//判断如果数据存在
	if(data){
		data = querystring(data);
	}

	if(method == "get" && data){
		url += "?" + data;
	}

	xhr.open(method, url, true);

	if(method == "get"){
		xhr.send();
	}else{
		//必须在send方法之前,去设置请求的格式
		xhr.setRequestHeader("content-type", "application/x-www-form-urlencoded");
		xhr.send(data);
	}

		//4、等待数据响应
		
	xhr.onreadystatechange = function(){
		if(xhr.readyState == 4){
			//判断本次下载的状态码都是多少
			if(xhr.status == 200){
				/* 
					如何去处理数据操作不确定
					回调函数
				*/

				if(success){
					// alert(2);
					success(xhr.responseText);
				}
			}else{
				if(error){
					error("Error:" + xhr.status);
				}
			}
		}
	}
}
/* 
	?name1=value1    search
	name1=value1&name2=value2     querystring
*/
function querystring(obj){
	var str = "";
	for(var attr in obj){
		str += attr + "=" + obj[attr] + "&";
	}
	return str.substring(0, str.length - 1);
}

/* 	
	method
	url
	data
	success  数据下载成功以后执行的函数
	error    数据下载失败以后执行的函数
*/
tool.js $ajax({method = "get", url, data, success, error})

(3)、JSON对象
/*
json数据传输格式(字符串的一种格式)
xml数据传输格式

	宜家        运输         我家
	装好的       拆掉         装好的

	前端        运输         后端
	数据结构     字符串       数据结构
*/
/* 
	JSON对象

	JSON.stringify()  数据结构 => 字符串
	JSON.parse()      json格式字符串 => 数据结构
*/
// alert(JSON);

//1、数组
/* var arr = [100, true, "hello"];
var str = JSON.stringify(arr);
alert(arr);
alert(str); //'[100,true,"hello"]' */

/* var str = '[100,true,"hello"]';
var arr = JSON.parse(str);
alert(arr[1]); */


//2、对象
/*  var obj = {
	username: "钢铁侠",
	age: 18,
	sex: "男"
}; */

/* var str = JSON.stringify(obj);
alert(obj);
alert(str); //'{"username":"钢铁侠","age":18,"sex":"男"}' */

var str = '{"username":"钢铁侠","age":18,"sex":"男"}';
var obj = JSON.parse(str);
alert(obj.username);

(4)、getlist案例 html <-> php 前后端通过ajax交互下载数据
/*
前后端交互的流程:
1、通过ajax下载数据
2、分析数据,转成对应数据结构 bejson.com
3、处理数据
/
window.onload = function(){
var oBtn = document.getElementById(“btn1”);
oBtn.onclick = function(){
$ajax({
method: “get”,
url: “getList.php”,
success: function(result){
alert(result);
/
var arr = JSON.parse(result);
for(var i = 0; i < arr.length; i++){
alert(i + ", " + arr[i]);
} */

				var obj = JSON.parse(result);
				alert(obj.username);
			},
			error: function(msg){
				//报错
				alert(msg);
			}
		})
	}
}

'leo','age'=>32);

	echo json_encode($arr2);

	// json_encode()  将数据结构转成字符串	
	// json_decode()  将字符串转成对应的数据机构
?>

(5)、表单与ajax get post请求区别 及php读取
表单 (post不通过url键值对)
get
url后方添加?name=value

http://localhost/code14/1.get.php?username=xxxx&age=18&password=123abc
post
post提交通过浏览器内部进行提交。

ajax	(都通过url键值对)
	get 
		xhr.open("get", "1.get.php?username=yyy&age=19&password=123abc", true);
	post 
		xhr.open("post", "1.post.php", true);
		xhr.setRequestHeader("content-type", "application/x-www-form-urlencoded");
		xhr.send("username=yyy&age=19&password=123abc");

php读取	
	基本结构
	

	/* 
		$_GET(全局的关联数组)  存放通过get提交提交的所有数据
		获取?后面对应健的值
	*/
	$username = $_GET['username'];
	$age = $_GET['age'];
	$password = $_GET["password"];

	/*
		$_POST全局数组
		存储过来的post发送过来的数组
	*/
	$username = $_POST['username'];
	$age = $_POST['age'];
	$password = $_POST["password"];

(6)、案例 新闻列表
(7)、服务器基础知识
/*
服务器 apache这个软件运行在你的电脑上,那么你电脑上某一个磁盘就对外可见,别人可以通过IP或者域名访问到这个位置。

	服务器  资源提供方
	客户端  资源受益方
	相对概念。

	服务器安装:
		(集成开发环境)
		WAMP  
			windows + apache + mysql + php
		LAMP
			linux + apache + mysql + php
		PHPnow
			apache + mysql + php

	PHPnow/htdocs  服务器的根目录
		localhost  直接访问本地电脑服务器
		127.0.0.1  直接访问本地电脑服务器(保留IP)
		IP         访问当前电脑的服务器

	默认访问到的是 index开头的文件
		index.php
		index.html
		index.jsp
*/

(8)、php基本句法
/*
类似于js中的console.log() 测试程序
*/
var_dump(100);
var_dump(“hello”);

/* 
    php声明变量通过$符号进行声明
    弱引用类型:给变量赋值什么数据,就是什么数据类型。

    php字符串拼接的时候,用的不是加号,而是 .
    php在进行字符串拼接的时候:占位符的方式进行拼接 {变量/表达式}
*/
$username = "钢铁侠";
$age = 18;

/* 
    md5编码
    功能:md5将任何的数据,编成一个32位的十六进制的字符串。
    【注】不可逆加密,同样的字符串加密以后,长的一样。
*/
$str1 = "123abc";
echo md5($str1); 
/* 
    自行去设计一套加密规则。
*/
$str1 = "123abc";
echo md5(md5(md5($str1).'qianfeng')."qingdao");

数组
	/* 
		1、索引数组  下标是数字叫做索引数组
		2、关联数组  下标是字符串叫关联数组   (类似于ECMA6的map类型)
		3、全局数组
			$_GET  接收通过get提交过来的所有的数据
			$_POST 接收通过post提交过来的所有的数据

			数组中的索引数组和关联数组可以相互结合,结合成多维数组。

		数组的长度 count($cars)  返回数组的长度
	*/

	//1、索引数组
	$cars = array("大众", "别克", "现代");
	array_push($cars, "宝马", "奔驰");
	// var_dump($cars);

	// echo $cars[1];

	for($i = 0; $i < count($cars); $i++){
		echo "下标:{$i}, 数据:{$cars[$i]}
"; } //2、关联数组/键值数组 /* $arr = array("王五" => "打渔的", "李四" => "种地的", "张三" => "打猎的"); // var_dump($arr); foreach($arr as $key => $value){ echo "下标:{$key}, 数据:{$value}
"; } */ /* $arr = array( array("name" => "小白", "english" => 100, "math" => 50), array("name" => "小花", "english" => 60, "math" => 80), array("name" => "小红", "english" => 100, "math" => 100) ); echo $arr[2]["math"]; */ /* for($i = 0; $i < count($arr); $i++){ var_dump($arr[$i]."
"); } */

(9)、PHP访问数据库 showStudents.php
header(“Content-type:text/html;charset=utf-8”);
/*
链接数据库 天龙八部
/
//1、链接数据库
/

第一个参数:链接数据库的IP/域名
第二个参数:用户名
第三个参数:密码
*/
$link = mysql_connect(“localhost”, “root”, “123456”);

	//2、判断是否连接成功
	if(!$link){
		echo "链接失败";
		exit; //终止后续所有的代码
	}

	//3、设置字符集
	mysql_set_charset("utf8");

	//4、选择数据库
	mysql_select_db("yyy");

	//5、准备sql语句
	$sql = "SELECT * FROM students";

	//6、发送sql语句
	$res = mysql_query($sql);

	//设置表头
	echo "";
	echo "";

	//7、处理结果
	while($row = mysql_fetch_assoc($res)){
		echo "";
	}
	echo "
学生学号学生姓名英语成绩数学成绩语文成绩
{$row['id']}{$row['name']}{$row['english']}{$row['math']}{$row['chinese']}
"; //8、关闭数据库 mysql_close($link); ?>

13、前后端交互 mysql html -> (from | ajax) -> php -> mysql
(1)、插入学生数据
/*
form表单点击提交数据以后,需要跳转页面
ajax 异步进行数据传输
【注】两者选其一。
*/
(2)、登录界面
(3)、注册界面
(4)、查看学生数据
(5)、获取用户列表

14、JSONP跨域
(1)、修改用户密码 mysql html -> (from | ajax) -> php -> mysql
(2)、删除用户 mysql html -> (from | ajax) -> php -> mysql
(3)、跨源方法
/*
已拦截跨源请求:同源策略禁止读取位于 https://api.asilu.com/weather/ 的远程资源。(原因:CORS 头缺少 ‘Access-Control-Allow-Origin’)。

	【注】ajax只能下载同源的数据,跨源的数据是禁止下载。

	同源策略:
		1、通协议
		2、同域名/同IP
		3、同端口号

	跨源的需求:
	
	跨源的方式:
		1、修改ajax同源协议(不建议)
		2、委托php文件进行跨源
		3、JSONP
*/

(4)、认识JSONP跨域
通过script src=url&callback=download 使用回调函数处理数据 完成跨域下载数据
https://api.asilu.com 在线 JSONP 接口测试api
https://www.bejson.com/ 下载的json结构可视化 方便解析

oScript.src = `https://api.asilu.com/weather/?city=${oCity.value}&callback=download`;

/* 
	1、在需要的时候加载数据
	2、能否引入除.js文件以外的其他路径,重点是代码是否是我们想要的代码


	【注】对于计算机来说,文件后缀是没有任何用处的。
	后缀作用:用于给计算机上的软件,快速识别应该用哪个软件打开。


	JSONP跨域的使用流程:
		1、先去声明一个函数,这个函数有一个形参,这个形参会拿到我们想要下载的数据,使用这个参数做后续数据的处理
		2、在需要下载数据的时候,动态创建script标签,将标签src属性设置成,下载数据的链接
		3、当script插入到页面上的时候,就会,调用已经封装好的函数,将我们需要的数据传过来。
*/
function download(data){
	alert("下载的数据:" + data);
}

demo.js -> download("I am String!");

(5)、案例 天气查询
https://api.asilu.com 在线 JSONP 接口测试api
https://www.bejson.com/ 下载的json结构可视化 方便解析

oScript.src = `https://api.asilu.com/weather/?city=${oCity.value}&callback=download`;

function download(data){
	var oT1 = document.getElementById("t1");
	var oInfo = document.getElementById("info");

	oInfo.innerHTML = `城市:${data.city}, pm2.5:${data.pm25}`;
	//1、天气情况取出
	var arr = data.weather;
	var str = ``;
	for(var i = 0; i < arr.length; i++){
		str += `
					${arr[i].date}
					${arr[i].weather}
					${arr[i].wind}
					${arr[i].temp}
				`;
	}
	oT1.innerHTML = str;
}

window.onload = function(){
	var oSearch = document.getElementById("search");
	var oCity = document.getElementById("city");
	oSearch.onclick = function(){
		if(!oCity.value){
			alert("请输入城市名字");
		}else{
			var oScript = document.createElement("script");
			oScript.src = `https://api.asilu.com/weather/?city=${oCity.value}&callback=download`;
			document.body.appendChild(oScript);
		}
	}
}

(6)、案例 百度下拉搜索框
function download(data){
// alert(“下载的数据是:” + data);

	//取出数据
	var arr = data.s;
	var oUl = document.getElementById('ul1');
	oUl.innerHTML = '';
	oUl.style.display = 'block';

	for(var i = 0; i < arr.length; i++){
		var newLi = document.createElement("li");
		var oA = document.createElement("a");
		oA.innerHTML = arr[i];
		oA.href = 'http://www.baidu.com/s?wd=' + arr[i];
		oA.target = '_blank';
		
		newLi.appendChild(oA);
		oUl.appendChild(newLi);
	}
}
window.onload = function(){
	var oQ = document.getElementById('q');
	var oUl = document.getElementById('ul1');
	
	oQ.onkeyup = function(){
		var oValue = this.value;
		if(!oValue){
			oUl.style.display = 'none';
		}else{
			//加载数据
			var oScript = document.createElement("script");
			oScript.src = `http://suggestion.baidu.com/su?wd=${this.value}&cb=download`;
			document.body.appendChild(oScript);
		}
	}
}

15、网络协议和cookie
(1)、认识网络协议
/*
计算机网络
ISO 7层的网络分层
通用 5层的网络分层

	网络数据在互联网进行传输,遵从传输规则,叫做网络传输协议。
*/
/* 
	TCP:面向链接协议。(快递,外卖)
	传输数据:
		1、建立链接  三次握手
		2、传输数据
		3、断开链接  四次挥手

	优点:
		1、安全
		2、准确度非常高
	缺点:
		1、传输效率低
		2、耗资源

	UDP:无连接协议(适用于对于及时性要求高,但是对于数据准确度要求不高)
	传输数据:
		直接传,根本不管是否收到数据。
	
	缺点:
		1、不安全
		2、准确度非常低
		3、经常丢包
	优点:
		1、及时性非常高
		2、消耗资源少
	【注】视频聊天。
*/

(2)、认识cookie
/*
cookie
1、可以设置过期时间
2、最大可以存储4KB,每一个域名下最多可以存储50条数据(不同的浏览器,有偏差)
【注】只能字符串。一般只存储一些重要的信息。登录,购物车信息,是否点赞,视频播放进度等。
*/

/* 
	cookie的语法
	格式: name=value;[expires=date];[path=path];[domain=somewhere.com];[secure],
	name 键
	value 值  都是自定义
	【注】后续中括号的内容(中括号是我加的),都是可选项。

	【注】火狐支持本地加载的文件缓存cookie,谷歌只支持服务器加载文件缓存cookie
*/

//设置cookie
document.cookie = 'username=xxx';

(3)、cookie中的中文
/*
encodeURIComponent 将中文编译成对应的字符
decodeURIComponent 将对应的字符编译成中文
*/
//设置cookie
document.cookie = ‘username=’ + encodeURIComponent(“钢铁侠”);

//获取cookie
alert(decodeURIComponent(document.cookie));

(4)、cookie中的可选项
/*
expires:过期时间
必须填写,日期对象
【注】系统会自动清除过期的cookie。
/
/

path 限制访问路径
如果不去设置,默认是加载当前.html文件的路径
【注】我们设置的cookie的路径,和加载当前文件的路径,必须一致,如果不一致,cookie访问失败。
/
/

domain 限制访问域名
如果不去设置,默认是加载当前.html文件的服务器域名/ip
【注】如果加载当前文件域名和设置的域名不一致,设置cookie失败。
/
/

secure
如果不设置,设置cookie,可以通过http协议加载文件设置 false
也可以通过https协议加载文件设置 true

		【注】设置这个字段以后,只能设置https协议加载cookie.
	
	https  证书认证协议
	http  
*/

// document.cookie = 'username=xxx;domain=' + "localhosx";

document.cookie = 'username=xxx;secure'

//获取n天后的日期
function afterOfDate(n){
	var d = new Date();
	var day = d.getDate();
	d.setDate(n + day);
	return d;
}

//快速获取过去时间的方法
alert(new Date(0));

document.cookie = "username=xxx;expires=" + afterOfDate(7);

window.onload = function(){
	var oBtn = document.getElementById("btn1");
	oBtn.onclick = function(){
	// document.cookie = "username=;expires=" + afterOfDate(-1);

	document.cookie = "username=;expires=" + new Date(0);
	}
}

(5)、封装cookie
/*
setCookie() setCookie(“超级英雄”, “钢铁侠”, {
expires: 7
})
getCookie() getCookie(“DC”)
removeCookie(); removeCookie(“超级英雄”);

	encodeURIComponent  将中文编译成对应的字符
	decodeURIComponent  将对应的字符编译成中文

	设置cookie                      $cookie("神话", "猪八戒", {
    $cookie(name, value);               expires: 30
    $cookie(name, value, {});       });
    
    获取cookie
    $cookie(name);                  $cookie("DC")

    删除cookie
    $cookie(name, null);            $cookie("超级英雄", null);
*/
//name=value;[expires=date];[path=path];[domain=somewhere.com];[secure],
/* 
	expires  传入对应天数
*/
tool.js -> cookie

16、闭包和设计模式
(1)、认识闭包
/*
什么是闭包?
1、函数嵌套函数
2、内部函数引用外部函数到的变量或者形参
3、被引用的变量或者形参就不会被垃圾回收机制所回收,常驻内存。
/
/

回顾垃圾回收机制:函数作用域(结果)
*/
function aaa(num1){
var num2 = 20;
function bbb(){
alert(num1 + ", " + num2);
}
return bbb;
}

var ccc = aaa(10);
ccc();

(2)、闭包的好处
/*
闭包的好处:
1、希望一个变量常驻在内存当中
2、避免全局变量的污染
3、声明私有变量

【注】我们应该避免声明全局变量,避免全局变量的污染。
*/
 var ccc = (function(){
	var a = 2;
	return function(){
		a++;
		alert(a);
	}
})();

ccc();
ccc();

(3)、立即执行函数
(function(){
alert(“hello world”);
})();
(4)、私有化
/*
有一个团队,ABC三位员工,一起开发项目,避免全局变量污染。
*/

//A员工的代码和函数
var moduleA = (function(){
	var count = 5;  //私有变量
	function aaa(){ //私有方法
		count += 10;
		alert(count);
	}

	function bbb(){
		count *= 20;
		alert(count);
	}
	
	//对外
	return {
		outA: aaa,
		outB: bbb
	}
})();

moduleA.outA() //15
moduleA.outB(); //300

//B员工代码和函数
var moduleB = (function(){
	var count = 1;
	function aaa(){
		count += 10;
		alert(count);
	}

	function bbb(){
		count *= 20;
		alert(count);
	}
	
	//对外
	return {
		outA: aaa,
		outB: bbb
	}
})();
moduleB.outA() //11
moduleB.outB(); //220

(5)、闭包在实战中的使用
for(var i = 0; i < aBtns.length; i++){
/* aBtns[i].index = i;

	aBtns[i].onclick = function(){
		alert(this.index);
	} */

	/*  aBtns[i].onclick = (function(index){
		return function(){
			alert(index);
		}
	})(i); */
	aBtns[i].onclick = btnClick(i);
}


function btnClick(index){
	return function(){
		alert(index);
	}
}

(6)、自定义警告框
/*
我们每一次点击弹出警告框,我们都需要在页面上查找一次,效率太低。
我们可以将警告框,直接存储在内存,将警告框常驻内存,闭包。
*/
(7)、观察者模式 闭包存储函数
function ObServer(){
this.funcs = []; //保存订阅者的信息
}

ObServer.prototype.subscribe = function(funcName){
	this.funcs.push(funcName);
}
ObServer.prototype.unsubscribe = function(funcName){
	this.funcs = this.funcs.filter(item => item != funcName);
}
ObServer.prototype.broadcast = function(msg){
	this.funcs.forEach(item => item(msg));
}


var kai55 = new ObServer();


function xiaoming(msg){
	console.log('您好您有一条新消息:' + msg + ", 小明都等不及下班了,非常想55开吹牛");
}

function xiaohua(msg){
	console.log('您好您有一条新消息:' + msg + ", 小花打开斗鱼直播,欣赏盛世美颜");
}


//订阅
kai55.subscribe(xiaoming);
kai55.subscribe(xiaohua);

kai55.broadcast("老铁们,我没开挂");

kai55.unsubscribe(xiaoming);

kai55.broadcast("老铁们,我凉了");

//01观察者模式.html:28 您好您有一条新消息:老铁们,我没开挂, 小明都等不及下班了,非常想55开吹牛
//01观察者模式.html:32 您好您有一条新消息:老铁们,我没开挂, 小花打开斗鱼直播,欣赏盛世美颜
//01观察者模式.html:32 您好您有一条新消息:老铁们,我凉了, 小花打开斗鱼直播,欣赏盛世美颜

(8)、适配器模式 闭包继承函数
/*
1、接收一个老项目
2、开发了一半的项目

	原则:
		<1>尽量不要去修改老的源代码
		<2>兼容老代码,还能增加新功能。
*/
function sum(x, y){
	return x + y;
}

alert(sum(10, 20));

// 在老函数的功能上再去增加一些功能。
//写一个适配器
function add(x, y){
	return sum(x, y) + "我是新功能";
}

alert(add(40, 50));

17、gulp
(1)、补充
/*
JQ bind 类似于on方法
绑定
*/
$(document).bind(“click”, function(){
alert(1);
})
(2)、使用gulp的流程
1、下载和安装NodeJS
http://nodejs.cn/download/
2、启动Nodejs
windows
windows键(开始键) => nodeJS文件 => nodejs prompt
苹果电脑 => 终端

	node -v  查看安装的nodeJS的版本
	(拓展知识)nvm  自行查阅,自行安装
3、安装nodeJS   
	npm  管理第三方包的包管理器  (下载源是国外的网站)
4、安装cnpm  淘宝镜像
	https://npm.taobao.org/
	命令:npm install -g cnpm --registry=https://registry.npm.taobao.org

5、cnpm下载一些数据,是从国内淘宝服务器上下载数据。


6、安装gulp到本地
	【注】windows不用注意这个细节,苹果电脑的每一条命令前面都必须加sudo(可以需要输入密码)
	<1>全局安装gulp
		cnpm install gulp -g
		gulp -v  查看安装的gulp版本

	<2>进入到你想开发项目的这个目录
		【注】windows的电脑是分磁盘的,如果你在别的盘创建的文件夹,应该先去切换盘符
			D:  + enter
			cd 目录路径
		清屏:window  cls       苹果/linux:clear

7、初始化当前目录
		cnpm init
	【注】生成package.json的文件,存放你当前项目一些配置信息。

8、在当前项目里面安装gulp到本地
		cnpm install [email protected] --save-dev
		cnpm i [email protected] -D

		--save  将这个文件,安装到本地的当前文件夹
		-dev    将安装gulp的信息保存在package.json里面

9、创建一个gulpfile.js的文件,专门gulp去编写任务的。
10、gulpfile.js中编写任务,需要在控制台通过
		gulp 任务名   运行你编写好的任务

11、给gulp添加插件
		https://gulpjs.com/plugins/
	
	使用第三方插件的步骤:
		commonJS规范
	<1>先去下载插件到本地
		cnpm install 插件名字 --save-dev
		cnpm i 插件名字 -D
	<2>通过require() 引入文件
	<3>查阅插件的用法

重点:JQuery编写的代码大家不要合并和压缩。
记住:给别人代码的时候,node_models删除
拿到这个项目以后:进入目录,重新下载所有的依赖文件 cnpm install

温馨提示:配置两个以上屏幕,进行前端开发。

gulp启动服务器可监控除php外的文件
	php需要放到服务器根目录下可以执行

(3)、gulpDemo

18、模块化开发
(1)、模块规范
/*
CommonJS规范(服务器)编写代码
声明:
module.exports = {
outA: showA,
outB: showB
}
引入:(同步执行)
var moduleA = require(‘moduleA.js’);
moduleA.outA();
moduleA.outB();

	AMD规范:(客户端/浏览器)
	声明:
		define(function(){
			//代码
			return {
				outA: showA,
				outB: showB
			}
		})
	引入:(异步执行)
		require("moduleA.js", function(moduleA){

			//这里的代码。模块引入之后执行。
			moduleA.putA();
			moduleA.outB();
		})

		alert("hello world");

	小彩蛋:CMD  阿里

	ECMA6(模块化规范)
	声明:
		export = {
			outA: showA
			outB: showB
		}

	引入:
		import moduleA from "moduleA.js"
		moduleA.outA()
		moduleA.outB();
*/

(2)、款放大模式 两js文件可同时声明

var moduleA = (function(mod){
function showC(){
alert(“hello world”);
}

		mod.outC = showC;
		return mod;
	})(moduleA || {});


	var moduleA = (function(mod){
		var count = 10; //私有变量

		function showA(){ //私有函数
			count += 20;
			alert(count);
		}
		function showB(){
			count *= 10;
			alert(count);
		}
		mod.outA = showA;
		mod.outB = showB;

		//对外暴露
		return mod;
	})(moduleA || {});

moduleA.outA();
moduleA.outB();
moduleA.outC();

(3)、shoppingDemo banner轮播图
(4)、模块化开发 Demo AMD规范
模块化开发的作用域:管理当前页面上引入的所有.js文件的。

	defer async = 'true' 引入的所有.js文件都是异步加载
	defer IE兼容的异步加载js文件
	data-main = ""  设置入口文件
	【注】每一个.html文件都要一个入口文件,入口文件:管理当前.html页面使用所有的.js代码

	【注】后续引入的所有.js,后缀都可以省略。
	-->
testDemo	AMD规范
	

	main.js
		console.log("加载成功");

		/* 
			引入模块 遵从AMD规范
			第一个参数,必须是数组
		*/
		/* require(["demo/add"], function(addObj){
			var res = addObj.outAdd(10, 20);
			alert(res);
			addObj.outShow();
		}) */

		/* 
			我们可以配置路径,你就没必要再引入模块的时候再写路径
		*/
		require.config({
			paths: {
				// 自定义模块的名字: 引入模块的路径
				add: "demo/add",
				mul: 'demo/mul'
			}
		})

		require(["add", "mul"], function(addObj, mul){
			var res = addObj.outAdd(10, 20);
			alert(res);
			addObj.outShow();

			alert(mul.mul(10, 20));
		})

	add.js
		/* 
			小A同学封装,进行两个数的和计算的模块
			可以写很多个函数,一般情况下把实现同类型功能的函数,放在一个模块。

			遵从AMD规范
		*/
		define(function(){
			function add(x, y){
				return x + y;
			}
			function show(){
				console.log("hello world");
			}
			function ccc(){
				console.log("在mul中要去使用的函数")
			}
			// 对外暴露
			return {
				outAdd: add,
				outShow: show,
				ccc: ccc
			}
		});

	mul.js
		/* 
			小B同学开发
			求两个数的积

			当前模块依赖另外一个模块
		*/
		define(["add"], function(add){
			function mul(x, y){
				add.ccc();
				return x * y;
			}

			return {
				mul: mul
			}
		})
testDemo2
	

	xxx.js
		console.log("加载完毕");
		/* 
			管理当前.html页面上引入的所有模块的
		*/
		require.config({
			paths: {
				"index": "demo/index",
				"scale": "demo/scale",
				"drag": "demo/drag"
			}
		})

		//使用模块 AMD规范
		require(["index"], function(index){
			index.init();
		})
	index.js
		/* 
			遵从AMD规范
		*/
		define(["scale", "drag"], function(scale, drag){
			//封装函数
			function init(){
				var oBtn = document.getElementById("btn1");
				var oDiv1 = document.getElementById("div1");
				var oDiv2 = document.getElementById("div2");
				var oDiv3 = document.getElementById("div3");

				oBtn.onclick = function(){
					//显示div1
					oDiv1.style.display = 'block';
					scale.scale(oDiv1, oDiv2);
				}

				drag.drag(oDiv3);
			}


			return {
				init: init
			}
		})
	drag.js
		define(function(){
			function drag(node){
				node.onmousedown = function(ev){
					var e = ev || window.event;
					var offsetX = e.clientX - this.offsetLeft;
					var offsetY = e.clientY - this.offsetTop;

					document.onmousemove = function(ev){
						var e = ev || window.event;
						var l = e.clientX - offsetX;
						var t = e.clientY - offsetY;

						var windowWidth = document.documentElement.clientWidth || document.body.clientWidth;
						var windowHeight = document.documentElement.clientHeight || document.body.clientHeight;

						l = range(l, 0, windowWidth - node.offsetWidth);
						t = range(t, 0, windowHeight - node.offsetHeight);


						node.style.left = l + 'px';
						node.style.top = t + 'px';
					}
				}
				document.onmouseup = function(){
					document.onmousemove = null;
				}
			}

			function range(iCur, iMin, iMax){
				if(iCur >= iMax){
					return iMax;
				}else if(iCur <= iMin){
					return iMin;
				}else{
					return iCur;
				}
			}

			return {
				drag: drag,
				range: range
			}
		})
	scale.js
		define(['drag'], function(drag){
			/* 
				node1 被缩放的控件
				node2 按下的控件
			*/
			function scale(node1, node2){
				node2.onmousedown = function(ev){
					var e = ev || window.event;
					//1、记录
					var w = node1.offsetWidth;
					var h = node1.offsetHeight;
					var l = e.clientX;
					var t = e.clientY;

					document.onmousemove = function(ev){
						var e = ev || window.event;
						//改变宽和高,进行缩放
						var W = w + (e.clientX - l);
						var H = h + (e.clientY - t);

						//限制出界
						W = drag.range(W, 100, 500);
						H = drag.range(H, 100, 500);

						node1.style.width = W + 'px';
						node1.style.height = H + 'px';
					}
				}
				document.onmouseup = function(){
					document.onmousemove = null;
				}
			}
			return {
				scale: scale
			}
		})

19、scss编程
(1)、声明变量
$xxx: 300px;
$xxx: 100px; //普通变量

$yyy: 50px;  
//默认变量 只要有新值进行赋值,值就用新值
$yyy: 200px !default; 

#div1{
	width: $xxx;
	height: $yyy;
}


$color: red; //全局变量

#div2{
	color: $color;
	$color: orange !global; //局部变量  全局变量
	.box{
		background-color: $color;
	}
}

#div3{
	background-color: $color;
}


/* 
	特殊变量
	#{表达式/变量}; 进行字符串拼接
	类似于js中的ECMA6 ${};
*/
$zzz: top;
#div4{
	border-#{$zzz}: 1px solid black;
}

(2)、选择器嵌套 &
#div1{
width: 100px;
.box{
height: 200px;
}
a{
background-color: red;
//& 父级元素选择器
&:hover{
color: orange;
background-color: blue;
}
}
}
(3)、混合 @mixin @include
/*
混合 类似于C语言中的宏定义
混合 代码块(不是函数)

	@mixin 混合名字{}
	@include 混合名字;

	【注】可以选择有参数或者没有参数。
*/
@mixin center-block {
	margin-left: auto;
	margin-right: auto;
}

//清除浮动

@mixin clearBoth{
	content: "";
	display: block;
	height: 0px;
	clear: both;
	overflow: hidden;
	visibility: hidden;
}


#div1{
	@include center-block;
	.box{
		@include clearBoth;
	}
}


@mixin xxx($padding: 30px, $border: 1px solid black) {
	border-right: $border;
	border-top: $border;
	padding-left: $padding;
}

#div2{
	@include xxx;
	.box1{
		@include xxx(50px);
	}
	.box2{
		@include xxx(50px, 3px dashed red);
	}
	.box3{
		@include xxx($border: 5px dashed orange);
	}
}

(4)、继承 @extend
/*
@extend 进行继承
*/
.btn{
width: 200px;
height: 50px;
a{
color: red;
&:hover{
background-color: orange;
color: yellow
}
}
}
.btn-primary{
@extend .btn;
background-color: blue;
}

.btn-success{
	@extend .btn;
	background-color: green;
}

(5)、import引入公共样式
/*
.js 引入.js文件

	声明公共样式的时候:
		标准:_base.scss
		引入:@import "base"
*/
@import "base";
@import "mixin";

#div1{
	@include clearBoth;
}

_base.js
	@charset "utf-8";
	/* CSS Document */
	$bg-color: white;

	body,h1,h3,h2,h4,h5,h6,p,dl,dd,ul,li,ol,td,form,input,fieldset,legend{
		margin:0; padding:0;
	}  
	...
_mixin.js
	@mixin clearBoth{
		content: "";
		display: block;
		height: 0px;
		clear: both;
		overflow: hidden;
		visibility: hidden;
	}

(6)、scss注释
// 普通注释 不会显示在.css文件中

/* 
	多行注释  会出现在.css文件中,不会出现在压缩版本里
*/

/*! 
	强制注释  在任何版本下都会保留
*/

(7)、控制指令 @if @else
$theme: light;

body{
	@if $theme == dark{
		background-color: black;
	}@else if $theme == light{
		background-color: white;
	}@else{
		background-color: gray;
	}
}

(8)、循环
$count: 12;
//包含结束位置
@for $i from 1 through KaTeX parse error: Expected '}', got '#' at position 18: …unt{ .col-lg-#̲{i}{
width: 100px / 12 * $i;
}
}

//不包含结束位置
@for $i from 1 to $count{
	.col-md-#{$i}{
		width: 100px / 12 * $i;
	}
}

$icons: success warning error primary info;
@each $icon in $icons{
	.icon-#{$icon}{
		background: url(images/#{$icon}.png) no-repeat;
	}
}

$num: 6;
@while $num > 0{
	.item#{$num}{
		width: 1em * $num;
	}
	$num: $num - 1;
}

(9)、函数 @function
$colors: (light: white,dark: black);

//函数声明
@function color($key){
	@if not map-has-key($colors, $key){
		//警告不会中断我们的scss监听
		// @warn "在这个映射里没有一个叫#{$key}的键";

		//错误会中断我们的scss监听
		@error "在这个映射里没有一个叫#{$key}的键";
	}
	@return map-get($colors, $key); 
}
//函数调用
body{
	background-color: color(xxx);
}

(10)、scss sass -> gulp
const gulp = require(“gulp”);
const scss = require(“gulp-sass”);

/* 
	编写任务,编写.scss文件
*/
gulp.task("scss", function(){
	return gulp.src("*.{sass,scss}")
	.pipe(scss())
	.pipe(gulp.dest("dist/css"));
})

const minifyCSS = require("gulp-minify-css");
const rename = require("gulp-rename");

gulp.task("scss2", function(){
	return gulp.src("07scss的注释.scss")
	.pipe(scss())
	.pipe(gulp.dest("dist/css"))
	.pipe(minifyCSS())
	.pipe(rename("07scss的注释.min.css"))
	.pipe(gulp.dest("dist/css"));
})


gulp.task("watch", function(){
	gulp.watch("*.{sass,scss}", ['scss']);
})

(11)、sass和scss区别
sass
// 1、不能有大括号 2、不能有分号 【注】必须通过严格的代码缩进进行编码

	body
		margin: 0px
		padding: 0px
scss
	/* 
		1、可以有大括号,和分号
		2、基本上使用方式css语法方式一样。

		sass  比较古老的版本
		scss  现在用的版本
	*/

	body{
		margin: 0px;
		padding: 0px;
	}

20、github常用命令
(1)、git基本命令
1)git add 将想要快照的内容写入缓存区
2)git status -s “AM” 状态的意思是,这个文件在我们将它添加到缓存之后又有改动
3)git commit -m ‘第一次版本提交’ -m选项添加备注信息
4)git clone url 使用 git clone 拷贝一个 Git 仓库到本地
5)git diff 查看执行 git status 的结果的详细信息
6)git reset HEAD 用于取消已缓存的内容
7)git rm file
  git rm 会将条目从缓存区中移除。这与 git reset HEAD 将条目取消缓存是有区别的。
  "取消缓存"的意思就是将缓存区恢复为我们做出修改之前的样子。
  默认情况下,git rm file 会将文件从缓存区和你的硬盘中(工作目录)删除。
8)git mv 重命名磁盘上的文件 如 git mv README README.md

9)git push -u origin master 提交代码

(2)、git 分支管理
1)创建分支命令 git branch (branchname) 列出分支 git branch
2)切换分支命令 git checkout (branchname)
3)合并分支 git merge (branchname)
4)创建新分支并立即切换到该分支下 git checkout -b (branchname)
5)删除分支命令 git branch -d (branchname)

(3)、查看日志版本
git log 命令列出历史提交记录
git log --oneline 查看历史记录的简洁的版本
git log --oneline --graph 查看历史中什么时候出现了分支、合并

附录、tool.js
1、n位验证码 每一个数字的范围 0~9 parseInt(Math.random() * 10);
numTestCode(n) return
2、n位验证码 每一个数字的范围 0~9 a-z A-Z parseInt(Math.random() * 123);
testCode(n); return
3、冒泡排序
bubbleSort(arr)
4、array去重
noRepeat(arr)
5、升序
changeSortAsc(arr)
6、降序
changeSortDesc(arr)
7、显示当前时间 年月日 时分秒格式
showTime() return
8、日期数字转成中文 0-6 -> 日-六
numOfChinese(num) return
9、数字前补零
doubleNum(n) return
10、获取两个日期之间相差的天数
countOfDate(d1, d2) return 天数
11、输入n,输出n天后的时间。
afterOfDate(n) return 日期 Tue Dec 01 2020 20:12:58 GMT+0800 (中国标准时间)
12、自定义byClassName 兼容IE8以下
elementsByClassName(node, classStr)
13、获取节点样式 跨浏览器的兼容
//可获得sytle中的样式
//通过.style.xxx的方式只能访问内联的css样式。
getStyle(node, cssStyle)
14、生成随机颜色
randomColor();
// 颜色随机
// rgba(255,255,255,1);
// oDiv.style.color = randomColor();
15、阻止事件冒泡
//封装跨浏览器兼容的阻止事件冒泡
//var e = ev || window.event;
//stopBubble(e);
stopBubble(e)
16、判断是否是数字
//仅限一位数字
isNum(num)
17、删除空白文本子节点
removeSpaceNode(parentNode)
18、随机任意范围整数的函数
randomNum(min, max)
19、交换排序
changeSort(arr)
20、倒着遍历元素去重
norepeatDown(arr)
21、生成n位数字验证码
testCodeNum(n)
22、阻止默认行为 跨浏览器
preDef(e)
23、限制拖拽
limitDrag(node)
24、拖拽 无限制出界
drag(node)
25、事件监听器兼容
addEvent(node, evenType, funcName)
removeEvent(node, eventType, funcName)
26、判断单个字符是否是字母(包含大小写)
isABC(charStr)
27、判断单个字符是否符合数字字母下划线
isDEF(charStr)
28、拖拽 面向对象
Drag(id)
29、限制拖拽 面向对象
LimitDrag(id)
30、多物体运动 (注释)
startMove(node, iTarget)
31、多物体运动 淡入淡出 (注释)
startMove(node, iTarget)
32、多物体多样式运动 (包含透明度) (注释)
startMove(node, attr, iTarget)
33、链式运动 在第一个动画结束的时候,开始第二个动画。(注释)
startMove(node, attr, iTarget, complete)
34、完美运动
cssObj //css样式对象
startMove(node, cssObj, complete)
35、碰撞函数
node1 球 碰撞方
node2 板 被碰撞方
konck(node1, node2)
碰了 return true
36、设置多条css样式
setStyle(node, cssObj)
37、ajax封装
/*
method
url
data
success 数据下载成功以后执行的函数
error 数据下载失败以后执行的函数
/
$ajax({method = “get”, url, data, success, error})
38、封装cookie
/

setCookie() setCookie(“超级英雄”, “钢铁侠”, {
expires: 7
})
getCookie() getCookie(“DC”)
removeCookie(); removeCookie(“超级英雄”);

	encodeURIComponent  将中文编译成对应的字符
	decodeURIComponent  将对应的字符编译成中文

	设置cookie                      $cookie("神话", "猪八戒", {
    $cookie(name, value);               expires: 30
    $cookie(name, value, {});       });
    
    获取cookie
    $cookie(name);                  $cookie("DC")

    删除cookie
    $cookie(name, null);            $cookie("超级英雄", null);
*/

你可能感兴趣的:(学习笔记,js常用函数,js包,javascript,sass,github,git,npm)