JS基础语法

JS

JS

JS的组成:

ECMAScript 基本语法、DOM文档对象模型、BOM浏览器对象模型
JS有三种书写位置:行内(body元素内)、内嵌式(head中)、外部式
行内:例:

<body>
    <input type="button" value="唐伯虎" onclick="alert('秋香')">
</body>

外部:引入<script src='my.js'></script>
html中推荐使用双引号,js中使用单引号

JS注释

//单行注释 CTRL+/
/多行注释/ shift+alt+a 也可使用CTRL+/

JS输入输出语句

alert(“返回结果”);浏览器弹出警示框 输出的
输入框prompt(“请输入”);
console.log(“我是程序员能看见的”)控制台输出 给程序员测试用的

变量

变量的本质是在内存中申请的一块用来存储数据的空间

变量的使用

声明变量+赋值

  1. 声明变量var age; var关键字声明 后加变量名
  2. 赋值 age=10;

变量的初始化:var age =10;
var myname=prompt(‘请输入你的名字’);
alert(myname)
更新变量 重新赋值
一次声明多个变量:var age=18,name=‘zhangsan’,sex=‘nan’; 用英文逗号隔开

特殊情况

只声明不赋值,为undefined
不声明不赋值直接使用,报错,not defined
不声明直接赋值使用qq=110;不报错,可以使用,和python类似

数据类型

变量的数据类型是可以变化的

数据类型分类

简单数据类型:Number Boolean String Undefined Null
Number.MAX_VALUE MIN_VALUE最大最小值
三个特殊值:Infinity(无穷大) NaN非数值
isNaN()用来判断是否为数字 是数字返回false

字符串型String引号外单内双
获取长度:str.length
字符串拼接:字符串+任意类型=新字符串 数值相加,字符相连
变量是不能加引号的
Boolean true和false 布尔型和数字型相加时,true为1 ,false为0
变量为赋值,为undefined型 var a= undefined; 可以这样定义 和数值型相加为NaN
null 可以定义 var a null;和数字型相加为另一个数字
typeof 变量;检测数据类型 typeof a;
prompt()获得的是字符型的数据类型

字面量一个固定值的表示法

数据类型的转换
转为字符型三种方法:

  1. toString() num.toString();
  2. String() String(num);
  3. +号拼接 num+’ ';

转为数字型:

  1. parseInt(string) 取整数,去小数点,去单位
  2. parseFloat(string) 也可以去单位
  3. Number(string) 强制转换
  4. 利用计算隐式转换(- * / ) ‘string’-0; ‘123’-‘120’;

转为布尔型
Boolean()函数
0、NaN、null、undefined、’ '转为false 其他全转为true

编译和解释语言的区别
编译完才执行
边解释边执行

运算符

算数运算符

表达式和返回值

递增运算符(和变量配合)

++num;(前置递增)(age=age+1)先+1后返回值
num++;(后置递增(age=age+1) 先返回原值再+1

比较运算符(关系运算符)

<
>=
>
<=
== “18”==18 true 默认转换数据类型再比较 只要求值
=== ‘18’===18 要求两侧值数据类型完全一致才可以true
!==

逻辑运算符(布尔运算符)

与&&
或||
非!

短路运算 (逻辑中断):

当有多个表达式值时,左边表达式值可以确定结果时,就不再运算右边表达式值。
逻辑与:若表达式1为真,则返回表达式二;若表达式1为假,返回表达式1
若有空或否定为假,其他为真
逻辑或:若表达式1结果为真,返回表达式1,若表达式1结果为假,则返回表达式2

赋值运算符

+=;-=;*=;/=;%=;

运算符优先级

小括号>一元运算符(++,–,!)>算数运算符>关系》相等》逻辑(先与后或)》赋值》逗号

流程控制

分支结构

if语句

语法:if(条件表达式){执行语句}

if else语句

语法:

if(条件表达式){
	执行语句1
} else{
	执行语句2
}
if else if 语句

语法:

if(条件表达式){
	语句1
}else if(条件表达式){
	语句2
}else if(条件表达式){
	语句3
}else{
	语句四
}

三元表达式

?:
语法 条件表达式?表达式1:表达式2
若条件表达式结果为真返回表达式1结果,否则返回表达式2 的值

switch语句

语法结构

switch(表达式){
	case value1:
			执行语句1breakcase value2:
			执行语句2breakdefault:
			最后语句;
}

switch和if else区别

固定值用switch 范围用if

循环结构

for 循环

语法结构:

for(初始化变量;条件表达式;操作表达式){
	循环体
}

调试;sources 前面可以设置断点

while循环

语法

while(条件表达式){
	循环体
}

do while循环

语法结构

do{
	循环体
}while(条件表达式)

条件不满足时退出循环

continue关键字

跳出本次循环,其他循环继续

break关键字

跳出整个循环

数组

数组;一组数据的集合,存储在单个变量下

创建数组

  1. 利用new关键字创建
    var 数组名=new Array();
  2. 利用数组字面量创建数组
    var 数组名=[2,‘pink’]; 可以放任意数据类型,用逗号分隔

获取数组元素

索引(下标):从0开始
语法: 数组名[2]
var y=myCars.indexOf(“Volvo”) // “Volvo” 值的索引值

遍历数组

for循环 数组长度 arr.length
for(var i=0;i<arr.length;i++)

数组新增元素

  1. 通过修改length长度
    arr.length=5;手动修改数组长度 扩充的元素为undefined
  2. 索引号赋值
    arr[3]=‘pink’;
  3. 修改数组元素
    arr[2]=0;
    不要直接给数组名赋值,否则之前的元素都没有了

删除数组元素

删除指定元素 for循环加if语句

反转数组

for(var i=arr.length-1;i>=0;i--){
	newarr[newarr.length]=arr[i];
}

数组排序——冒泡排序

//外层循环管趟数
for(var i=0;i<=元素数-1;i++){
//内层循环 每一趟交换次数 arr.length-i-1
	for(var j=0;j<=arr.length-i-1;j++){
			//内部交换变量对的值
			if(arr[j]>arr[j+1]){
				var temp=arr[j];
				arr[j]=arr[j+1];
				arr[j+1]=temp;
			}
	}
}

函数

函数的使用

声明函数+调用函数m
function 函数名(){
函数体
}
调用:函数名();

函数参数

声明:function(形参1,形参2……){
函数体
}
调用:函数名(实参1,实参2……);
实参是传递,形参是接收(相当于变量)

函数形参与实参的匹配问题

若实参个数多于形参个数,取形参个数
若实参个数小于形参个数 形参看作未申明的变量 多的形参为undefined

函数的返回值

return语句:return 返回的结果;只能返回一个值,返回的结果是最后一个值;
return终止函数:return之后语句不会执行
函数没有return返回undefined
return也可退出循环

arguments的使用

arguements是当前函数的一个内置对象 存储传递过来的实参 可以不定义形参
伪数组:

  • 具有数组的length属性
  • 按照索引方式进行存储
  • 没有真正数组的方法

可以按数组方式进行遍历arguments
应用:利用函数求任意个数的最大值

函数的两种声明方式

  1. 函数关键字声明(命名函数)
    function 函数名(){表达式}
  2. 函数表达式声明 (匿名函数)
    var 变量名=function(){表达式}
    调用 变量名();

JS作用域

作用域:代码名在某个范围内起效果
js的作用域(es6):全局作用域、局部作用域
全局作用域:整个script标签 或是单独的js文件
局部作用域(函数作用域):在函数内部就是局部作用域

变量的作用域

全局变量:全局作用域下的变量
var num=10; num为一个全局变量
如果在函数内部没有声明,直接赋值的变量也属于全局变量
局部变量:函数内部的变量,函数形参也为局部变量
全局变量只有浏览器关闭时才会销毁,比较占内存
局部变量当程序关闭就会销毁
js没有块级作用域:{},es6新增块级作用域
作用域链
函数内部有一个函数:内部函数可以访问外部函数的变量,
作用域链:链式查找,找上一级(就近原则)

两个重要的 JavaScript 关键字

let 和 const。
使用 var 关键字声明的变量不具备块级作用域的特性,它在 {} 外依然能被访问到。
let 声明的变量只在 let 命令所在的代码块 {} 内有效,在 {} 之外不能访问。let 声明的变量不会在作用域中被提升
const 声明一个只读的常量,一旦声明,常量的值就不能改变。

预解析

js引擎运行js分为两步:预解析和代码执行
预解析:js引擎会把js里面所有的var和function提升到当前作用域最前面
预解析分为变量预解析(变量提升)和函数预解析(函数提升)
变量提升:把所有变量声明提升到当前作用域最前面,不提升赋值操作

例1:

console.log(num);
var num=10;
相当于以下代码:
var num;
console.log(num);
num=10;
例2:
fun();
var fun=function(){
console.log(22);
}
相当于以下代码:
var fun();
fun();
fun=function(){}

函数关键字声明可以提升到最前面

JS类

类声明:
语法:
class ClassName {
constructor() { … }
method_1() { … }
method_2() { … }
method_3() { … }
}
例:

class Rectangle {
    // constructor
    constructor(height, width) {
        this.height = height;
        this.width = width;
    }
    // Getter
    get area() {
        return this.calcArea()
    }
    // Method
    calcArea() {
        return this.height * this.width;
    }
}

类声明不会提升
匿名类和命名类

/ 未命名/匿名类
let Rectangle = class {
  constructor(height, width) {
    this.height = height;
    this.width = width;
  }
};
console.log(Rectangle.name);
// output: "Rectangle"

// 命名类
let Rectangle = class Rectangle2 {
  constructor(height, width) {
    this.height = height;
    this.width = width;
  }
};
console.log(Rectangle.name);

JS 对象

对象是一组无序的相关属性和方法的集合,所有事物都是对象,字符串、数值、数组(万物皆对象)
对象由属性和方法组成
属性:特征
方法:行为

创建对象(object)

  1. 用字面量创建对象{}
    var obj={};创建了一个空对象
    创建方法属性对象:键值对形式 键:属性名,值:属性值 多个属性方法之间用逗号隔开,最后一个可以不用逗号,方法冒号跟的是一个匿名函数
var obj={
	uname:"jane",
	age:18,
	sex:'male',
	sayHi:function(){}
}
  1. 利用new Object创建
    var obj=new Object();
    增加属性和方法—等号赋值方法
    obj.uname=‘jane’;
    obj.age=18;
    obj.sayHi=function(){}
  2. 构造函数创建对象
    将对象里面一些相同的属性和方法抽象出来封装
    语法:
    function 构造函数名(){
    this.属性=值;
    this.方法=function(){}
    }
    new 构造函数名(); 创建一个对象
    例:
// 构造函数名首字母要大写
function Star(uname,age,sex){
	this.name=uname;
	this.age=age;
	this.sex=sex;
	this.sing=function(song){}
}
//构造函数不需要return就可以返回结果
var ldh=new Star('刘德华',18,'male');

new 关键字执行过程
new创建一个空对象
this指向创建的空对象
执行构造函数中的代码,添加属性和方法
返回这个新对象
构造函数类似于python中的类,构造函数创建对象也称为对象实例化

调用对象属性
  1. 采取对象名.属性名;
  2. 对象名[‘属性名’]
调用对象方法

对象名.方法名();记得添加小括号

区别

变量:单独声明并赋值,单独存在
属性:在对象里面,不需要声明
函数:单独声明 调用:函数名(); 单独存在
方法:对象里面,调用时:对象.方法

遍历对象

新的for循环 for in
语法:for(变量 in 对象){}
for (var k in obj){} k 输出属性名 obj[k] 输出属性值

内置对象

js对象有三种:自定义对象、内置对象、浏览器对象
内置对象:js自带的一些对象,提供一些常用的属性和方法
查阅文档mdn

Math对象

Math不是一个构造器,所以无需new,直接使用属性方法就可以
Math.max()
Math.min()
Math.abs(‘-1’) 会把数据类型转为数字型
Math.abs(‘pink’) 返回NaN
三个取整方法:
Math.floor()向下取整 往小了的取 小数点去掉
Math.ceil() 往大取,进一
Math.round()四舍五入 1.5 -2 五舍六入负数
Math.round(-1.5) 结果为-1 (.5往大的取)
Math.random() 返回一个随机小数【0,1)里面不跟参数
返回两个数之间随机整数,并且两端包含
function getRandom(min,max){
return Math.floor(Math.random()*(max-min+1))+min;
}

Date 对象

Date是一个构造函数需要new来创建对象
var date=new Date();
没有参数,返回系统当前时间
参数常用写法:数字型2019,10,01 字符串型‘2019-10-01 8:8:8’
日期格式化
var date=new Date();
date.getFullYear()返回年份
date.getMonth() 返回的月份小1月(0-11)
date.getDate() 返回几号
date.getDay() (周日为0,周一 1周六6)
2019年5月1日星期一
var year=date.getFullYear();
var month=date.getMonth() +1;
var date=date.getDate();
var arr=[‘星期日,‘星期一’];
var day=date.getDay();
console.log(‘今天是’+‘year’+‘年’+month+‘月’+date+‘日’+arr[day]);
格式化日期时分秒
date.getHours();
date.getMinutes();
date.getSeconds();
返回当前时分秒函数
function getTime(){
var time=new Date();
var h=date.getHours();
h=h<10?‘0’+h:h;
var m=date.getMinutes();
m=m<10?‘0’+m:m;
var s=date.getSeconds();
s=s<10?‘0’+s:s;
return h+“:”+m+’:'+s;
}
获取总的毫秒数(时间戳)
Date对象基于1970年1月1日
date.valueOf();
date.getTime();新增时间距离基准时间总毫秒数
var date1=+new Date();返回的也是总的毫秒数
H5新增的方法Date.now();

倒计时

输入时间-现在时间,不能那时分秒直接相减;用时间戳做;把时间戳毫秒数转换为时分秒
d=秒数/60/60/24;天数
h=秒数/60/60%24;小时
m=秒数/60%60;分数
s=秒数%60;秒数

function countDown(time){
	var nowtime=+new Date();
	var inputtime=+new Date(time);
	var times=(inputtimes-nowtime)/1000;
	var d=parseInt(times/60/60/24);
	var h=parseInt(times/60/60%24);
	var m=parseInt(times/60%60);
	var s=parseInt(times%60):
	return d+'天'+h+'时'+m+'分'+s+'秒';
}

数组对象

var arr=new Array(2); 长度为2 的数组
var arr=new Array(2,3);等价于[2,3]
检查是否为数组:

  1. instanceof 运算符 用来检测是否为数组 arr instanceof Array;
  2. Array.isArray(arr);

添加删除数组元素

添加

push() 添加到末尾
arr.push(4,‘pink’);
返回值为添加后新数组长度,原数组发生变化
unshift()在开头添加一个或多个
arr.unshift(‘pink’,1);
返回值为新数组的长度,原数组发生变化,

删除

pop() 删除数组最后一个元素,一次只能删一个,无参数
arr.pop();返回值为删除的元素,原数组发生变化
shift()删除第一个元素,一次只能删一个,无参数,返回删除的那个元素,原数组发生变化

数组排序

翻转数组:arr.reverse();
排序:arr.sort(); 按照各个字符的Unicode位点排序
arr.sort(function(a,b){return a-b;}) 降序;return b-a; 正常排序

数组索引

获取指定数组元素索引:arr.indexOf(‘blue’); 如果有多个,返回第一个满足条件的索引号;找不到,返回-1;
arr.lastIndexOf(‘lan’);从后面开始查找,索引仍为正常

数组去重
数组转换为字符串

arr.toString();逗号分割
join(分割符)arr.join(‘-’); 默认逗号分割 返回一个新数组
concat() 连接两个或多个数组 不影响原数组
slice(begin,end);数组截取 返回被截取的新数组
splice(第几个开始,要删除几个) 返回被删除的新数组,影响原数组

字符串对象

基本包装类型:把简单数据类型包装为复杂数据类型
字符串是不可变的:里面的值是不可变的,但地址
字符串本身是不可变的,会开辟一个新空间存放新的字符串
返回索引:str.indexOf(‘春’); indexOf(‘要查找的字符’,‘起始位置’)后一个参数可选lastIndexOf()
根据位置返回字符:str.charAt(3);
str.charCodeAt(index) 返回对应字符的ascll码
str[index]
字符串拼接截取方法
str.concat(str1);
str.substr(start,length);相当于数组中的splice
slice(start,end);
substring(strat,end);
替换
str.replace(x,y);x替换前,y替换后 只替换第一个字符
转换为数组
str.split(‘分隔符’);
toUpperCase();转换大写
toLowerCase();转换小写

简单数据类型和复杂数据类型

数据类型内存分配
值类型(简单数据类型)null返回的是空对象
引用类型(复杂数据类型)
内存分配:堆(复杂)和栈(简单,存放的是值)
复杂数据类型:首先在栈里存放地址16进制,这个地址指向的数据值存在堆中
简单类型传参:值传递——不影响实参
复杂数据类型传参:地址传递——影响实参 堆地址复制

WebAPIs和API

webAPI学的是DOM和BOM 页面交互
API:应用程序编程接口 是一些预先定义的函数,目的是提供应用程序
webAPI:浏览器提供的操作浏览器功能和页面元素的API(BOM和DOM)


DOM

获取元素

文档页面从上往下加载,所以先有标签,script写在标签下面

  1. document. getElementById
    id 是大小写敏感的
    var timer = document.getElementById(‘time’);
    返回的是对象
    console.dir(timer);打印返回的元素对象,更好的查看属性和方法
  2. document. getElementsByTagName(‘li’) 通过标签名
    返回的是元素对象的集合,以伪数组形式存储
    打印里面元素,采取for循环遍历
    得到的元素是动态的(随之变化)
    若页面只有一个元素,返回的也是一个伪数组,若页面没有这个元素,返回的是一个空的伪数组
    可以根据父元素获取子元素
    document.getElementsByTagName(‘ol’);
    父元素要指定是哪个对象
    例:
    ol[0].getElementsByTagName(‘li’);
  3. document.getElementsByClassName根据类名获取
    也是伪数组形式存储
  4. document.querySelctor(‘选择器’)返回指定选择器第一个元素对象,选择器需要加符号
    document.querySelctor(‘.box’);类选择
    document.querySelctor(‘#nav’);id选择
    document.querySelctor(‘li’);标签选择
  5. document.querySelctorAll()返回指定选择器所有的元素对象

获取body和html标签

获取body:document.body;返回body元素对象
获取html:document.document.Element;

事件三要素

事件由三部分组成:事件源、事件类型、事件处理程序
事件源(事件被触发的对象)
事件类型(如何触发,比如鼠标点击onclick)
事件处理程序(通过函数赋值方式完成)
例:

var btn=document.getElementById('btn');
btn.onclick=function(){
	alert('点秋香');
}
执行事件的步骤:
  1. 获取事件源
  2. 绑定事件
  3. 添加事件处理程序
改变元素内容:

element.innerText 从起始位置到终止位置,去除html标签,同时空格和换行也会去掉 不识别html标签
element.innerHTML 从起始位置到终止位置,包括html标签,同时保留空格和换行
div.innerHTML=‘今天是: 2019’;
这两个属性是可读写的,可以获取标签里的内容

改变元素属性
//1. 修改元素
var ldh=document.getElementById('ldh');
var zxy=document.getElementById('zxy');
var img=document.querySelector('img');
//2. 注册事件,处理程序
zxy.onclick=function(){
	img.src='url';
	img.title='张学友';
}
ldh.onclick=function(){
	img.src='url1';
	img.title='刘德华';
}
修改表单属性

innerHTML是普通标签的
表单是通过value修改的
input.value=“被点击了”;
按钮被禁用:btn.disabled=true;
this 指向事件函数的调用者 this.disabled=true;
案例:密码框隐藏与显示
修改样式:
this.style.backgroundColor=‘purple’; 驼峰命名法
js写的是行内样式

案例:叉号显示隐藏
循环精灵图
显示隐藏文本框内容 获得焦点onfocus onblur失去焦点
text.οnfοcus=function(){}
text.οnblur=function(){}

使用className修改样式属性

在css中定义类,在js中将this.className=‘change’; 将当前类名改为change,会覆盖之前类名
若要保留之前类名:this.className=‘first change’;

排他思想

所有按钮绑定事件,for循环
先所有元素清楚样式,再设置自己

for(var i=0;i<lis.length;i++){
	lis\[i].onclick=function(){
		for (var i=0;i<lis.length;i++){
			lis\[i].className=' ';
			}
		this.className='current';
		}
}

案例:表单隔行变色
鼠标经过:onmouseover 离开 onmouseout
表单全选
checked=‘checked’;
tbs[i].checked=this.checked; true or false;

获取属性:
element.属性; 获取内置属性(class,id)
element.getAttribute(‘属性’); 获取自定义属性(自己添加的属性)
设置属性:
element.属性=value;div.className=‘navs’;
element.setAttribute(‘属性’,‘值’);div.setAttribute(‘class’,‘navs’);
移除属性
element.removeAttribute(‘属性’);

tab栏切换:
for (var i=0;i< items.length;i++){
items[i].style.display=‘none’;
}
intems[index].style.display=‘block’;

自定义属性命名以data-(index)开头
新增获取属性方法:element.dataset.index; div.dataset[‘index’];(有兼容性,ie11以上)
dataset是一个集合,里面存放所有以data开头的自定义属性
data-list-name dataset[‘listName’];
若自定义属性命名有多个-链接单词,获取时采用驼峰命名法

节点操作-获取元素

节点node所有内容都是节点 nodename 、nametype、nodevalue
元素节点type1 、属性节点type2 、文本节点type3

节点层级:父子兄层级关系
父级节点 node.parentNode; 最近的父亲(亲爸爸) 不能得到爷爷,找不到返回空
子节点 node.childNodes; 得到所有子节点,包含元素节点和文本节点
检查节点类型:node.childNodes[0].nodeType
node.children; 获取所有子元素节点

节点操作第一个和最后一个元素
node.firstChild;返回第一个子节点
node.lastChild;最后一个子节点
node.firstElementChild;返回第一个子元素节点;ie9以上才支持
node.lastElementChild;返回最后一个子元素节点
实际上可以使用node.children[0] node.children[node.children.length-1];

节点操作:兄弟节点
node.nextSibling;下一个兄弟节点;(包含文本节点)
node.previousSibling;上一个兄弟节点
node.nextElementSibling;下一个兄弟元素节点
node.previousElementSibling;上一个兄弟元素节点

创建节点document.creatElement(‘li’);

添加节点node.appendChild(child);在后面添加
在指定元素前面添加node.insertBefore(child,指定元素);
案例:评论:

btn.onclick=function(){
	if (text.value==''){
		alert('您没有输入内容!');
		return false;
	}else{
	var li =document.createElement('li');
	li.innerHTML=text.value;
// 	ul.appendChild(li);
		ul.insertBefore(li,ul.children[0]);
	}
}
删除节点:

node.removeChild(child);
点击页面阻止页面跳转:<a href=‘javascript:;’>
案例:评论删除

复制节点

node.cloneNode();括号参数为空或false,只复制标签,不复制内容,括号内容为true,深拷贝,复制里面内容
ul.appendChild(li);
案例:动态生成表格
填充数据:td.innerHTML=datas[i][k];

三种动态创建元素方式

document.write(‘元素’);直接将内容写入页面,担当文档流执行完毕,会导致页面全部重绘
element.innerHTML=‘元素’;
采取数组形式效率更高(个位数):
var arr=[ ];
arr.push(‘元素’);
document.body.innerHTML=arr.join(’ ');
document.createElement(‘元素’);效率更高
element.appendChild();

DOM核心总结:

创建、增删改查、属性、事件操作

事件高级

传统注册事件:利用on开头的onclick 注册事件唯一性 后添加的会覆盖
方法监听注册方式:eventtaget.addEventListener(type,listener,useCapture)
type:事件类型,加引号,不用加on,listener为处理函数function(){} 同一个元素可以添加多个侦听器
eventtaget.attachEvent(‘onclick’,function(){}) ie9以前的支持

删除事件(解绑事件)

传统方法:
ventTarget.οnclick=function(){
alert(11);
eventTarget.οnclick=null;
}
侦听器方法
eventTarget.addEventListener(‘click’,fn)
function fn(){
alert(22);
eventTarget.removeEventListener(‘click’,fn);
}
ie9以前
divs[2].attachEvent(‘onclick’,fn1);
function fn1(){
alert(33);
divs[2].detachEvent(‘onclick’,fn1);
}

DOM事件流

三个阶段:捕获阶段(从父亲开始)、当前目标阶段、冒泡阶段(从子代开始)
js代码只能执行捕获或者冒泡中的一个阶段
onclick、attachEvent只能得到冒泡阶段,addEventListener第三个参数为true,则处于捕获阶段
例:

var son=document.querySelector('.son');
son.addEventListener('click',function(){
	alert('son');
},true);

冒泡阶段:
addEventListener第三个参数为false或省略,则处于冒泡阶段

var son=document.querySelector('.son');
son.addEventListener('click',function(){
	alert('son');
});

一般更关注事件冒泡

事件对象

div.οnclick=function(event){}
event就是一个事件对象,写到处理函数的小括号里,当形参看,系统自动创建,不需要传递参数,事件对象可以自己命名,e
事件对象是我们事件一系列相关数据的集合,跟事件相关的
ie678 window.event
兼容写法:e=e||window.event;
e.target 返回触发事件元素
this 返回的是绑定事件的对象
e.type 返回事件类型

阻止默认行为,让链接不跳转,或提交按钮不提交

e.preventDefault();
例:

var a=document.querySelector('a');
a.addEventListener('click',function(e){e.preventDefault();})

传统注册方式:

a.onclick=function(e){
	e.preventDefault();
}
阻止冒泡:

事件冒泡:具体元素接受,逐级向上
e.stopPropagation();

var son=document.querySelector('.son');
son.addEventListener('click',function(e){
	alert('son');
	e.stopPropagation();
});

ie678:

var son=document.querySelector('.son');
son.addEventListener('click',function(e){
	alert('son');
	e.stopPropagation();
	window.event.cancelBubble=true;//属性
});

father 也需要添加

事件委托

事件委托的原理:不是单独给每个子节点添加侦听器,而是设置在父结点上,利用冒泡原理影响每个子节点

var ul=document.querySelector('ul');
ul.addEventListener('click',function(){
	alert('茅坡!');
	e.target.style.backgroundColor='pink';
})
禁止选中文字和禁止右键

contextmenu 禁用右键

document.addEventListener('contextmenu',function(e){
	e.preventDefault();
})

禁止选中selcetstart

document.addEventListener('selctstart',function(e){
	e.preventDefault();
})
鼠标事件对象MouseEvent
document.addEventListener('click',function(e){
	console.log(e.clientX);
	console.log(e.clientY);
})

clientX当前页面下x,y坐标

document.addEventListener('click',function(e){
	console.log(e.pageX);
	console.log(e.pageY);
})

pageX页面文档的x,y坐标

跟随鼠标

mousemove
绝对定位
每次鼠标移动,获得最新鼠标坐标,把这个x和y坐标作为图片的top和left值

document.addEventListener('mousemove',function(e){
   var x=e.pageX;
   var y=e.pageY;
   pic.style.top=y+'px';
   pic.style.left=x+'px';
})

键盘事件

onkeyup 松开时

document.onkeyup=function(){
})
document.addEventListener('keyup',function(){
})

onkeydown 按下时
onkeypress 按下时触发 不识别功能键ctr shift 箭头 alt不识别

键盘事件对象KeyBoardEvent

keyCode返回该键的ascll码值
keyup和keydown 不区分字母大小写,按大写A;keypress区分字母大小写

document.addEventListener('keyup',function(e){
   console.log(e.keyCode);
})

按s键,把光标定位到搜索框中
获取焦点:element.focus();

var search=document.querySelector('input');
document.addEventListener('keyup',function(e){
	if(e.keyCode==83){
		search.focus();
	}
})

注意:keydown两个事件触发时文字还未进入文本框中,而keyup弹起时,文字已经落入文本框了。

BOM

浏览器对象模型
核心(顶级)对象时window DOM中顶级对象为document
全局变量是window对象的一个属性
函数是window对象的一个方法,调用时省略window
name是window对象的一个特殊属性

页面加载事件

传统方式:后面的会覆盖前面的
<script>
window.οnlοad=function(){
里面填写script代码
}
</script>
推荐方式:没有限制
window.addEventListener(‘load’,function(){});
第三种:
document.addEventListener(‘DOMContentLoaded’,function(){});
load是页面所有元素全部加载完毕,包含dom元素,图片等等,
DOMContentLoaded 是DOM加载完毕,不包含图片等等,加载速度比load快

调整窗口大小事件

window.onsreize=function(){}
window.addEventListener(‘resize’,function(){});
window.innerWidth屏幕宽度的属性

定时器

window.setTimeout(调用函数,延迟时间);时间单位时毫秒 延迟调用函数,只调用一次
window调用时可以省略
调用函数可以直接写写函数,也可以写函数名,或者写为’函数名()'加引号
页面中有很多定时器,经常给他们加标识符(名字)
var timer=setTimeout(function(){},2000);
回调函数:一件事做完,再回头调用那个函数
案例:5秒后自动关闭广告
停止定时器:点击某个按钮停止定时器:btn.addEventListener(‘click’,function(){clearTimeout(timer);})
var setInterval(function(){},1000)定时器 每隔一秒调用一次 重复调用
开始定时器
var timer=null;(定义全局变量,赋值null)
begin.addEventListener(‘click’,function(){timer=setInterval(function(){},1000);})
清除定时器:stop.addEventListener(‘click’,function(){clearInterval(timer);})
案例:倒计时 setInterval()
button改值是通过innerHTML修改
案例:发送短信

this指向问题

一般情况下this指向那个调用它的对象
全局作用下this指向全局对象window
谁调用就指向谁

同步和异步

js是单线程
同步任务:主线程执行线
异步任务:通过回调函数实现,一般有三种类型:

  1. 普通事件,如:click、resize
  2. 资源加载,如:load、error
  3. 定时器,如:setInterval、setTimeout

异步任务回调函数添加到任务队列中

location对象

url:互联网上标准资源地址
语法格式:protocol://host[:port]/path/[?query]#fragment
protocol:通信协议
host:主机(域名)
port:端口号
path:路径
query:参数
fragment:片段
location.href:获取或设置整个url
location.host:返回主机(域名)
location.port:返回端口号
location.pathname:返回路径
location.search:返回参数&分开
location.hash 返回片段#后面的内容锚点
案例:点击之后跳转页面
location.href=“新url”
案例:5秒之后自动跳转
案例:获取url参数
跳转页面:location.assign(‘新的url’);记录浏览历史,可以实现后退效果
location.replace(‘url’)不记录浏览历史,不能实现后退功能
location.reload()重新加载页面相当于刷新,参数为true相当于强制刷新

navigator对象

useragent:返回一些值
if((navigator.userAgent.match(/phone)))
移动端或pc端

history对象

history.forward();
history.back();历史页面
history.go(1);前进一步

PC端网页特效

元素偏移量:offset

offset 得到元素的偏移位置,返回不带单位的数值
div.offsetTop 返回该元素相对带有定位父级元素上方的偏移
div.offsetLeft
element.offsetWidth offsetHeight返回元素的大小、宽度和高度包含padding、width
offsetParent 返回带有定位的父亲,否则返回body
parentNode 最近一级父亲,不管有无定位
offset和style区别:
style.width只能得到行内样式表的样式值,得不到内嵌样式表的值,并且style返回的带单位
offset是只读属性,不能改变,style是可以更改的
案例:模态框拖拽

client系列

element.clientTop 上边框大小
element.clientWidth 包含padding、width、不包含边框,offset包含边框
立即执行函数:不需要调用,可以立即执行的函数
语法:(function(a,b){})(1,2)或(function(){}()) 也可以传递参数 第二个小括号相当于调用函数 也可以加函数名
立即函数独立创建了一个作用域,里面所有变量为局部变量
淘宝flexible核心代码分析
load事件和pageshow事件

scroll系列

element.scrollWidth 返回自身实际宽度,不含边框,返回数值不带单位
element.scrollWidth 返回自身实际高度(包括超出的),不含边框,返回数值不带单位
element.scrollTop 返回被卷去的上侧距离,返回数值不带单位
window.pageYOffset获得页面被卷去的头部高度
scroll是元素被卷去的

mouseenter事件和mouseover事件

mouseover经过自身和子盒子都会触发(冒泡),mouseenter经过子盒子不会触发,mouseleave同样不会冒泡,搭配鼠标离开

动画原理

核心原理:通过setInterval()函数不断移动盒子距离

此元素要添加定位
例:

var timer=setInterval(function(){
	if(div.offsetLeft>=400){
// 		停止定时器
		clearInterval(timer);
	}
	div.style.left=div.offsetLeft+5+'px';
},30)
简单动画函数封装

function animation(obj,target){}

function animation(obj,target){
	clearInterval(obj.timer);//让对象只有一个定时器执行
	obj.timer=setInterval(function(){//给不同元素添加不同定时器
	if(obj.offsetLeft>=target){
// 		停止定时器
		clearInterval(obj.timer);
	}
	obj.style.left=obj.offsetLeft+5+'px';
},30)
}
缓动动画原理

让速度慢慢停下来
算法:(目标值-现在位置)/10

function animation(obj,target){
	clearInterval(obj.timer);//让对象只有一个定时器执行
	obj.timer=setInterval(function(){//给不同元素添加不同定时器
		var step=target-obj.offsetLeft)/10;//可以两个方向走,多个目标值之间移动
		step=step>0?Math.ceil(step):Math.floor(step);//解决倒着走的问题
	if(obj.offsetLeft>=target){
// 		停止定时器
		clearInterval(obj.timer);
	}
	obj.style.left=obj.offsetLeft+step+'px';
},15)
}
动画函数添加回调函数
function animation(obj,target,callback){
	clearInterval(obj.timer);//让对象只有一个定时器执行
	obj.timer=setInterval(function(){//给不同元素添加不同定时器
		var step=target-obj.offsetLeft)/10;//可以两个方向走,多个目标值之间移动
		step=step>0?Math.ceil(step):Math.floor(step);//解决倒着走的问题
	if(obj.offsetLeft>=target){
// 		停止定时器
		clearInterval(obj.timer);
		if (callback){
			callback();//相当于 callback && callback();
		}
	}
	obj.style.left=obj.offsetLeft+step+'px';
},15)
}
animation(span,800,function(){
	alert(11);
});//调用函数

动画函数分装到单独js文件中
<script src='js/animate.js'></script>

网页轮播图
节流阀

当上一个函数动画执行完毕,再执行下一个函数动画
利用回调函数,添加一个变量来控制
flag =false;
animate(ul,300,function(){
flag=true;
})

案例:返回顶部

window.scroll(x,y);返回到指定的坐标位置 里面x,y不跟单位
animate(window,0);

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值