javaScript 是运行在浏览器上的脚本语言
作用 : 增强与用户的交互性
目录
变量
含义: 变量是容器
作用: 存储数据的
格式:
var a = 10 //关键字 变量名 = 值
标识符
含义:凡是自己起的名字都是标识符
变量名是由数字 字母 _ $ 组成的 数字不能开头 不能是关键字
变量一般采用驼峰命名方式 如: myAge 首字母小写后面的单词首字母大写
注释
// 单行注释
/*
多行注释
*/
基本数据类型
5种基本数据类型
Number Boolean String Undefined Null
typeof 测试数据类型的关键字 typeof 变量名
Number 数值类型
转换为Number类型的方式
1 Number(变量名) 如果只字符串类型则返回NaN
2 Number.parseInt(变量名) 常用 从刚开始识别知道遇到字符
3 Number.parseFloat(变量名)
4 +变量名 注:通过运算符转换
Boolean 布尔类型
转换boolean类型的方式
1:Boolean(变量名)
2:!!变量名 注:通过运算符转换
String 字符串类型
转换为String类型的方式
1 变量名.toString() 朱undefined和null没有toString()方法
2 String(变量名)
3 变量名+"" 注:通过运算符转换 任何类型通过加好和字符串拼接都会进行隐士转换
Undefined类型
只有不赋值时才是Undefined类型
Null类型
只有变量赋值为null时才为null
运算符
有括号的运算符优先级最高
算数运算符
+ - * / 分别是加减乘除 %代表于数
比较运算符
> 大于
>= 大于等于
< 小于
<= 小于等于
== 等于不比较数据类型
var a=10
var b="10"
console.log(a==b) //true
=== 全等于 比较数据类型
逻辑运算符
|| 或 && 与 ! 取反
|| 看true 如果有一个为true 则为true
&& 看false 如果有一个false 则为false
! 取反
一元运算符
只有一个操作运算付的叫一元运算符
++a 先加一在执行操作
a++ 先执行操作在加一
// var a = 1; var b = ++a + ++a; console.log(b); //5
// var a = 1; var b = a++ + ++a; console.log(b); //4
// var a = 1; var b = a++ + a++; console.log(b); //3
// var a = 1; var b = ++a + a++; console.log(b); //4
如果是单独写就是一样的结果
var i=1
var a= ++i
var b= i++
console.log(++2) //这种写法是错误的
console.log(a)//2
console.log(b)//2
语句
if 语句 判断
//基本语句
if(表达式){
//分支语句
}
//if else 语句
if(表达式){
//分支语句
}else{
//分支语句
}
//if(表达式) else if(表达式) else
if(表达式){
//分支语句
}else if(表达式){
//分支语句
}else{
分支语句
}
表达式的结果是true或者false
如果执行一个分支语句其他的都不会执行
switch语句
switch 表达式{
case 值 : //分支语句 break;
case 值 : //分支语句 break;
case 值 : //分支语句 break;
default : //分支语句
}
表达式的值和case 的常量值 做全等判断
三元表达式
是if else 的简写
表达式一 ? 表达式二 :表达式三
如果表达式一为true 则返回表达式二 如果为false 则返回表达式三
注:if()括号里的表达式会做隐士Boolean转换 null undefined NaN 0 "" 都为false 技巧 有值为true 无值为false
循环结构
while(条件){
执行语句
}
do{
循环体
}while(条件)
for(初始化表达式1; 判断表达式2; 自增表达式3){
4循环体
}
要用逗号分开
执行顺序 1243----243---243 直到条件不满足
函数
是一种功能
function 函数名(){
函数体
}
函数体的代码不会自动执行;需要函数被调用时才执行
通过 函数名() 调用
通过return来返回结果值
返回值详解: 1、如果函数中没有使用 return语句 ,那么函数有默认的返回值:undefined 2、如果函数使用 return语句,但是return后面没有任何值,那么函数的返回值也是:undefined 3、如果函数使用 return语句,那么跟在return后面的值,就成了函数的返回值 4、函数使用return语句后,这个函数会在执行完 return 语句之后停止并立即退出,也就是说return后面的所有其他代码都不会再执行。
arguments
是javaScript内置的一个属性是一个伪数组具有数组的方法 作用存储实参
匿名函数
没有名字的函数称作匿名函数。如下函数表达式等号右边部分的函数没有名字,是匿名函数。
var fn = function() { // 函数体 }
作用域
全局作用域 局部作用域
在全局作用域下行程的变量都是全局变量
在局部作用域下形成的变量叫局部变量 函数体中的var 声明的变量和形参都是局部变量
**在函数内部声明没有var的变量 也是修改或者定义一个全局变量
内置对象
Arrary 数组
var arr = [数据类型,数据类型] 一般存储相同的数据类型
var arr=new Arrary(2,3,1) 通过构造函数创建数组对象 如果是一个参数代表数组长度 不存在元素
通过 arr instanceof Array 来判断是不是数组
arr.push(参数) 向数组最后添加元素
arr.unshift(参数) 向数组前面添加元素
arr.pop() 删除最后一个元素
arr.shift() 删除前面一个元素
arr.indexof(数组元素) 查看该元素索引值 如果是两个参数 第二个参数是从什么地方开始找
arr.join("-") 数组拼接返回字符串
arr.reverse() 数组反转
sort()进行数组排序 默认是字节码排序
//sort()对数组进行排序;默认按照Unicode排序
/**
* 我们可以自己指定排序
* sort()方法中添加一个回调函数有两个参数
* 浏览器会分别使用数组中的元素作为实参调用回调函数
* 如果返回一个大于0;则元素交换位置
* 如果返回一个小于0的值;则元素位置不变
* 如果返回一个0;则元素相等;不交换位置
* 如果升序就用a-b;如果降序就用b-a
*/
var arr3=[2,3,11,33,4,3];
arr3.sort(function(a,b){
/* if(a>b){
return 1;
}else if(a<b){
return -1;
}else{
return 0;
} */
return b-a;
});
arr.slice(n,m) 从索引n开始获取到索引m不包括 这个不会影响原来的数组返回新的数组
arr.splice (x,y,a/b/c) 从x索引开始删除y个元素 后面是替代的元素
七大方法都是改变原数组的
String
当我们给String变量重新赋值的时候,栈中的临时变量的值会被修改成另一个地址,此时这个变量就指向了另一块堆内存,旧的内存空间将不再被引用,浏览器将自动回收旧值所占的内存空间(我们不能确定该内存什么时候被回收)。这个字符串的重新赋值的过程,并没有修改旧的内存中的值,而是将变量指向了一块新的内存,这就是字符串的不可变特性!
//字符串拼接问题
var s1 = '0';
for (var i = 0; i < 10000000; i++) {
s1 += i;
}
console.log(s1);
以上代码存在大量拼接字符串的操作,将会导致内存不断被开辟,占用大量内存,造成程序性能降低的问题。所以在开发中应避免大量拼接字符串!
var str="hello"
str.charAt(索引) 返回指定索引的字符串
str.length 获取字符串长度
str.concat(字符串一,字符串二) 进行字符串拼接
str.indexOf(字符串,从某个位置找) 要找的字符串的索引值 找不到返回-1
str.replace("原有字符串","替换后的字符串")
str.split(字符) 以什么子符拆分 返回数组
str.slice(n,m) 字符串切割 从下包n取到m不包括m
str.substr(开始位置,个数) 截取新的字符串
Date 日期
var date=new Date() 获取系统当前时间
var time=new Date().getTime() 获取一个时间戳
var date=new Date(time) 通过时间戳获取时间
date.getFullYear() 获取年
date.getMonth()+1+"").padStart(2,0) 获取月份要加以 padStart(长度,要加的参数)是字符串的方法保持字符串几位如果不符合用0代替
date.getDay() 获取周
(date.getDate()+"").padStart(2,0) 获取日
date.getHours() 获取时
date.getMinutes() 获取分
date.getSeconds(获取秒)
Math对象
Math.cel(12.03)向上取整
math不是构造函数所以直接点方法
预解析
浏览器在解析js之前会进行预解析 作用是进行变量提升
自上而下执行
把当前变量声明提升到当前作用域的最前面
把函数声明提升到当前作用域的最前面
特点:
当函数和变量同名 先输出函数声明 不管变量声明是放在前面还是后面
如果是匿名函数,则只将前面的变量声明提升,函数不动。
没有声明就报错 a is not defined
形参相当于局部变量
DOM(Document Object Model,简称DOM )
DOM是节点的一些方法
作用:标签、属性、文本、注释等所有html的内容在DOM中被封装成了类型为节点类型的对象,称为节点对象Node。标签、属性、文本、注释分别对应的节点对象是元素节点(Element)、属性节点(Atrr)、文本节点(Text)、注释节点(Comment)。
JavaScript组成
DOM常用的概念
文档:一个网页可以被称为文档
节点:网页中的所有内容(标签 属性 文本 注释)
元素:页面中的标签
属性 :标签属性
DOM经常进行的操作
获取元素
对元素进行操作(设置属性或调用方法)
创建元素
事件
获取事件的过程
获取元素 document(文档对象)
通过id获取元素 document.getElementById()
通过标签名获取 document.getElementsByTagName() 获取的是一个伪数组
通过类名获取 document.getElementsByClassName() 获取的是一个伪数组
通过document.querySelector("#*") 获取的是第一个元素
通过document.querySelectorAll("#*") 获取的是一个伪数组
通过document.documentElement获取html
通过document.body获取body
这两个都是通过属性来获取的
操作非表单属性
获取标签元素
标签.属性=值
不加值就是获取属性
如果是修改class 标签.className=值 这个值可以是多个class名
修改标签的属性样式 标签.style.css属性名=值 只能获取内联元素的样式
js变量中不能有横杠 全部是驼峰模式
非表单元素属性 href title src alt 等
表单属性
-
value 用于获取和设置表单元素的内容
-
type 用于获取和设置input标签的类型
-
checked 复选框选中属性(true表示选中, false表示不选中)
事件的排它思想
<span>span标签1</span>
<span>span标签2</span>
<span>span标签3</span>
<span>span标签4</span>
<span>span标签5</span>
<script>
var arr=document.getElementsByTagName("span")
for(var i=0;i<arr.length;i++){
//为每个标签添加事件
arr[i].onclick=function(){
//排它思想 为每个标签的样式恢复的原始样式
for(var j=0;j<arr.length;j++){
arr[j].style.color="#000"
}
//点击执行代码相当于在全局执行 所以不能用arr[i].style.color
this.style.color="red"
}
}
</script>
代码优化(封装思想)
获取父类型下的所有子元素
function get_els(parent_id,child_tag){
return document.getElementById(parent_id).getElementsByTagName(child_tag);
}
修改样式可以通过修改class来修改
通过return false来阻止超链接跳转
点击小图变大图 通过return false来实现
<a href="images/1.jpg" id="oa"><img src="images/1-small.jpg" alt=""></a>
<img src="" alt="" id="big">
<script>
my$("oa").onclick = function(){
my$("big").src=this.href;
return false
}
</script>
美女相册练习
<ul id="oul">
<li>
<a href="images/1.jpg" title="美女A">
<img src="images/1-small.jpg" width="100" alt="">
</a>
</li>
<li>
<a href="images/2.jpg" title="美女B">
<img src="images/2-small.jpg" width="100" alt="">
</a>
</li>
<li>
<a href="images/3.jpg" title="美女C">
<img src="images/3-small.jpg" width="100" alt="">
</a>
</li>
<li>
<a href="images/4.jpg" title="美女D">
<img src="images/4-small.jpg" width="100" alt="">
</a>
</li>
</ul>
<img id="big" src="images/placeholder.png" alt="" width="450">
<p id="op">选择一个图片</p>
<script>
var oas = get_els("oul","a");
for(var i=0;i<oas.length;i++){
// oas[i] 就是每一个a标签
oas[i].onclick = function(){
// 更改大图片的路径
my$("big").src=this.href;
// 更改底部文字
my$("op").innerHTML = this.title;
return false
}
}
</script>
自定义属性
设置行内样式
getAttribute() 获取行内属性
setAttribute() 设置行内属性
removeAttribute() 移除行内属性
修改文本内容
通过innerHTML修改内容能够解析标签来修改内容
通过innerText 不能够解析标签修改内容
获取节点(不常用)
parentNode 获取父节点
parentElement获取父元素
childNodes获取子节点
children获取子元素
previousSibling 获取前一个兄弟节点
previousElementSibing 获取前一个兄弟元素
nextSibling 获取后一个兄弟节点
nextElementSibing 获取后一个兄弟元素
全选全不选练习
<body>
<form method="post" action="">
你爱好的运动是?<input type="checkbox" id="checkedAllBox"/>全选/全部选
<br/>
<input type="checkbox" name="items" value="足球"/>足球
<input type="checkbox" name="items" value="篮球"/>蓝球
<input type="checkbox" name="items" value="羽毛球"/>羽毛球
<input type="checkbox" name="items" value="乒乓球"/>乒乓球
<br/>
<input type="button" id="checkedAllBtn" value="全选" />
<input type="button" id="checkedAllNoBtn" value="全不选" />
<input type="button" id="checkedRevBtn" value="反选" />
<input type="button" id="sendBtn" value="提交" />
</form>
<script>
var items= document.getElementsByName("items")
//全选/全不选
document.getElementById("checkedAllBox").onclick=function(){
for(let i=0;i<items.length;i++){
items[i].checked=!items[i].checked
if(items[i].checked===false){
document.getElementById("checkedAllBox").checked=false
}
}
}
//全选
document.getElementById("checkedAllBtn").onclick=function(){
for(let i=0;i<items.length;i++){
items[i].checked=true
}
//全选/全不选按钮选中
document.getElementById("checkedAllBox").checked=true
}
//全不选
document.getElementById("checkedAllNoBtn").onclick=function(){
for(let i=0;i<items.length;i++){
items[i].checked=false
}
//全选/全不选按钮不选中
document.getElementById("checkedAllBox").checked=false
}
//反选
document.getElementById("checkedRevBtn").onclick=function(){
//刚开始就选中 如果有false就不选中
document.getElementById("checkedAllBox").checked=true
for(let i=0;i<items.length;i++){
items[i].checked=!items[i].checked
if(items[i].checked==false){
document.getElementById("checkedAllBox").checked=false
}
}
}
//为四个按钮非别绑定
for(let i=0;i<items.length;i++){
items[i].onclick=function(){
//首先设置全选/全不选按钮选中
document.getElementById("checkedAllBox").checked=true
//遍历每一项是否有没有选中的 一但没有选中就不选
for(let j=0;j<items.length;j++){
if(!items[j].checked){
document.getElementById("checkedAllBox").checked=false
break;
}
}
}
}
</script>
</body>
创建元素
**document.write()**:将一个文本字符串写入到由 document.open() 打开的一个文档流中;
**innerHTML**:设置或获取HTML语法表示的元素的后代;
**document.createElement( tagName )**:创建由 tagName 指定的HTML元素;(重要)
1 先创建元素 document.createElement("标签名字") 返回一个对象
2 把元素追加到父级元素汇总 把元素追加到父元素appendChild()
动态创建列表
<body>
<input type="button" value="添加" id="btn">
<ul class="box" id="content"
></ul>
<script src="js/public.js"></script>
<script>
var arr=["张子凡","李星云","姬如雪","师妹","女帝"]
//点击按钮添加数组元素要循环获取所有内容
my$("btn").onclick=function(){
for(var i=0;i<arr.length;i++){
//创建动态元素
var liArr= document.createElement("li")
//添加内容
liArr.innerHTML=arr[i]
//把li添加到ul元素中
my$("content").appendChild(liArr)
//给li添加事件是放在for循环中还是在外面?
//要在for循环中添加因为在外面刚开始加载无法获取元素
liArr.onmousemove=function(){
this.style.backgroundColor="pink"
}
liArr.onmouseout=function(){
this.style.backgroundColor=""
}
}
}
</script>
</body>
动态添加表单
<button id="btn">添加表单</button>
<div class="box"></div>
<script>
//创建数据
var theadArr=["姓名","性别","职业"];
//创建表体
var body=[
{name:"张子凡",sex:"男",occupation:"通文馆少主"},
{name:"李星云",sex:"男",occupation:"唐朝太子"},
{name:"袁天罡",sex:"男",occupation:"占卜师"}
]
document.getElementById("btn").onclick=function(){
//创建一个表格
var table=document.createElement('table')
var thead=document.createElement("thead")
var tbody=document.createElement("tbody")
var ttr=document.createElement("tr")
for(let i=0;i<theadArr.length;i++){
var th=document.createElement("th")
th.innerHTML= theadArr[i]
ttr.appendChild(th)
}
for(let j=0;j<body.length;j++){
//有三行所以要放到for循环中
var tbtr=document.createElement("tr")
for (let key in body[j]) {
var td=document.createElement("td")
td.innerHTML=body[j][key]
tbtr.appendChild(td)
}
tbody.appendChild(tbtr)
}
thead.appendChild(ttr)
table.appendChild(thead)
table.appendChild(tbody)
var box= document.getElementsByTagName("div")[0]
box.appendChild(table)
table.border="1px"
//表单单元格之间的间隙
table.cellSpacing=0
// table.setAttribute("cellspacing",0)
}
</script>
注册事件
之前绑定事件如果同一个元素绑定多个事件后面的时间会把前面的事件覆盖掉(相同的事件)
通过addEventListener来注册监听事件 可以绑定多个事件(相同的事件)
第一个参数----事件名字
第二个参数----事件处理函数
第三个参数----boolean类型 false 代表冒泡
解绑事件
//第一种:解绑事件的方式
my$("btn2").onclick = function () {
my$("btn").onclick = null;//执行这行代码之后,事件就被清掉了,在点击第一个按钮也不起作用了
}
//解绑事件的时候,需要在绑定事件的时候,使用命名函数,就是复制上面代码改下
/*
* 1.解绑事件
* 事件源.on事件名字=事件处理函数--->绑定事件
* 事件源.on事件名字=null;
*/
function f1() {
console.log("第一个");
}
function f2() {
console.log("第二个");
}
my$("btn").addEventListener("click",f1,false);
my$("btn").addEventListener("click",f2,false);
//点击第二个按钮把第一个按钮的第一个点击事件解绑
my$("btn2").onclick = function () {
my$("btn").removeEventListener("click",f1,false);
}
注意:用什么方式绑定事件;就应该用对应的方式解绑事件
onclick 让难就的时间处理函数只执行一次
事件的三个阶段
1 捕获阶段
2 目标阶段 (执行当前点击的元素 )
3 冒泡阶段
多层元素嵌套;里面的元素事件触发外面元素事件的也会触发(相同的)
如何阻止事件冒泡:window.event.cancelBubble=true; IE特有的,谷歌支持,火狐不支持
e.stopPropagation();//5、谷歌和火狐支持
注意,注册事件有三种,其中onclick、attachEvent没有第三个参数,实际上我们无法通过onclick、attachEvent来干预事件的第一阶段和第二阶段, 因为onclick、attachEvent都只有两个参数, 而且onclick、attachEvent注册的事件默认是冒泡阶段。很多时候我们只关心事件的第三阶段,即冒泡阶段。
事件委托
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<style>
.box{
width: 200px;
height: 400px;
border: 1px solid rgb(255, 0, 0);
}
</style>
</head>
<body>
<button id="btn">按钮</button>
<div class="box"></div>
<script>
// 一个元素,如果不是原本网页所有的,而是通过后期添加进来的,那么你就无法正常获取到这个元素并给他添加事件。如果想要给他添加事件,就需要把这个事件寄托到父级(原理就是使用了事件冒泡)
var box=document.getElementsByClassName("box")[0]
document.getElementById("btn").onclick=function(){
var li=document.createElement("li")
li.innerHTML="这是一个li标签"
box.appendChild(li)
}
box.onclick=function(event){
//target代表目标对象
var mylist=event.target;
mylist.style.backgroundColor="red"
}
</script>
</body>
window.οnlοad=function(){js代码} 等DOM对象渲染完在执行 如果不渲染完就获取不到元素
BOM
浏览器窗口(window)的一些方法,属性
偏移量offset(掌握)
元素属性
offsetWidth:获取元素的宽(边框;内边距;内容) 数值
offsetHeight: 获取元素的高(边框;内边距;内容)
offsetLeft 获取距离左边遍框的距离
offsetTop 获取距离右边遍框的距离
clientX 代表事件触发时的水平坐标 数值 可视区域的横坐标
clientY 代表事件触发时的垂直坐标 数值
通过style标签中设置的样式属性可以通过style属性样式获取到
一般通过offset系列来获取
Scroll系列
获取元素滚动的距离
* offset系列:获取元素的宽,高,left,top, offsetParent
* offsetWidth:元素的宽,有边框
* offsetHeight:元素的高,有边框
* offsetLeft:元素距离左边位置的值
* offsetTop:元素距离上面位置的值
*
* scroll系列:卷曲出去的值
* scrollLeft:向左卷曲出去的距离---被卷去的左边
* scrollTop:向上卷曲出去的距离----被卷去的上面
* scrollWidth:元素中内容的实际的宽(如果内容很少,没有内容,元素自身的宽),没有边框
* scrollHeight:元素中内容的实际的高(如果内容很少或者没有内容,元素自身的高),没有边框
*
*
* client系列:可视区域
* clientWidth:可视区域的宽(没有边框),边框内部的宽度
* clientHeight:可视区域的高(没有边框),边框内部的高度
* clientLeft:左边边框的宽度
*clientTop :上面的边框的宽度