JavaScript基础篇
JS基础
数据类型
基本数据类型(简单,值)
复杂数据类型(引用)-----------------引用地址(一改全改)
分支结构
if-else-if
循环结构
for i
for in
打断循环的语句
数组
增删改查 删除splice(index,1)
遍历 for forEach
函数
语法 调用式 声明式 表达式(命名函数)
预解析 作用域链
对象
增删改查
遍历 for in
内置对象的方法
运算符
隐式转换
逻辑运算短路
js进阶(DOM和BOM)
DOM内容多一点
页面相关 html
元素的增删改查
事件----------人和浏览器交互
逻辑思维(套路)
BOM操作
浏览器自带的功能
动画-------------------------定时器(过一会在执行)
页面的回退和跳转
js进阶第01天
今日要点:
记住JavaScript的三大组成部分
了解什么是DOM
必须掌握获取元素几种的方式
必须掌握事件的基本格式以及常见的事件使用
事件源.on事件类型 = 事件处理程序
掌握如何为多个元素绑定事件(对象伪数组做for循环遍历)
掌握修改文本的方法
掌握修改样式的方法
掌握修改标签属性的方法(标签属性,对象属性 不一样的)
掌握事件中this的使用(重要)---------------------------事件源
一、Web API 概述
API(Application Programming Interface,应用程序编程接口)是一些预先定义的函数或方法,目的是提供应用程序与开发人员基于某软件或硬件得以访问一组例程的能力,而又无需访问源码,或理解内部工作机制的细节。
Web API:浏览器提供的一套操作浏览器功能和页面元素的API(BOM和DOM),此处的Web API特指浏览器提供的一组方法,Web API在后面的课程中有其它含义。如下是MDN中的列举的Web API:MDN文档
二、JavaScript组成

ECMAScript
ECMAScript 定义了JavaScript 的语法规范,是JavaScript的核心。它描述了语言的基本语法和数据类型,ECMAScript是一套标准,定义了一种语言的标准,它与具体实现无关。
BOM(Browser Object Model浏览器对象模型)其实是一套操作浏览器功能的API,通过BOM可以操作浏览器窗口,比如:弹出框、控制浏览器跳转、获取分辨率等 。
DOM(Document Object Model文档对象模型)其实是一套操作页面元素的API,JavaScript中的DOM把HTML看做是文档树,通过DOM提供的API可以对树上的节点进行操作。
三、DOM的概念
文档对象模型(Document Object Model,简称DOM),是 W3C 组织推荐的处理 可扩展标记语言(html或xml文档) 的标准 编程接口。它是一种与平台和语言无关的 API,它可以动态操作HTML文档,如 对html标签作增删改查操作。DOM 是一种基于树的 API 文档,在处理html文档的过程中,DOM以对象的形式存储在内存中。
因为DOM是基于树结构存储在内存中的,所以DOM又称为文档树模型,DOM的树结构如下图

DOM中的几个常用概念
1、文档:一个网页可以称为文档
2、节点:网页中的所有内容都是节点(标签、属性、文本、注释等)
3、元素:网页中的标签
4、属性:标签的属性
DOM经常进行的操作
1、获取元素
2、对元素进行操作(设置其属性或调用其方法)
3、动态创建元素
4、事件(什么时机做相应的操作)
四、获取元素几种的方式
语法:
document.getElementById('id') //通过ID获取元素,唯一一个
document.getElementsByTagName('标签名') //通过标签名称获取元素,[]集合
document.getElementsByClassName('类名') //通过类名获取元素,[]集合。兼容性问题
document.getElementsByName("name") //通过name属性值获取元素(表单)
// HTML5向Web API新引入了两个方法用来更方便地从DOM选取元素
// 功能类似于jQuery的选择器。
document.querySelector('selectors') //获取一组元素中第一个满足条件的元素,高版本浏览器支持
document.querySelectorAll('selectors') //获取所有满足条件的元素
// 这个参数selectors需要是合法的CSS选择语法,可以包含多个CSS选择器,用逗号隔开五、JS中的事件
事件是可以被控件识别的操作,如按下确定按钮,选择某个单选按钮或者复选框。每一种控件有自己可以识别的事件,如窗体的加载、单击、双击等事件,编辑框(文本框)的文本改变事件,等等。
事件是基于触发-响应 机制实现的,当用户对控件做某些操作时,如 点击,移入鼠标,输入文字等,控件会识别到该操作,并作出对应的响应。
5.1、事件三要素
1、事件源: 被触发的对象
2、事件类型: 用户的操作、例如:鼠标点击,鼠标经过,鼠标离开
3、事件处理程序: 事件触发后要执行的代码(函数形式)--就是我们要去做上面事情

唐僧念紧箍咒——疼在后(猴)头
事件源: 三藏
事件类型: 念紧箍咒
5.2、Javascript的书写位置
js 行内式:
<button onclick="alert('哈哈,我是行内式')">行内式</button>js 内嵌式:
<button onclick="fun()">内嵌式</button>
<script type="text/javascript">
function fun(){
alert("内嵌式");
}外部javascript:
第一步:先建立一个JS的文件 demo.js 书写JS代码
第二步:调用外部JS文件
<script type="text/javascript" src="demo.js"></script>
<button onclick="fun1()">外部JS</button>5.3、Javascript代码分离
行内事件绑定语法:
<button onclick="fun()">点击</button>
<script>
function fun(){
alert("您点击了我");
}
</script>行内事件绑定的写法没有体现出 结构样式行为代码分离 的特性,所以这种用法大家会用即可
我们重点掌握的是用代码分离的写法:
事件源.on事件=function(){要执行的处理程序;}代码示例:
var btn=document.getElementById("btn"); /*获取id为btn的元素*/
/*事件源.事件=function(){ }*/
btn.onclick=function(){
alert("您点击了我");
}六、常见内容修改
6.1、文本内容修改
element.innerHTML = '<p>xxx</p>' //向一个元素中插入一段 HTML
element.innerText = 'xxx' //修改元素的显示文本内容6.2、css样式修改
语法:
element.style.backgroundColor = "red";修改多个样式:
// 思路:将多个样式写成对象的形式作为参数,传递给一个函数
var obox = document.getElementById("box");
// 函数封装
function setCss(ele, css) {
for (var key in css) {
ele.style[key] = css[key];
}
}
// 调用函数,传递参数
setCss(obox, {
width: "300px",
height: "300px",
backgroundColor: "red"
})6.3、非表单元素的属性修改
所谓表单元素,就是可以放在form表单标签中存储用户输入的数据的标签,如 input、select标签,而非表单元素就是只能展示数据,不能存储用户输入的数据 的标签,如 a、img标签。
常用的非表单元素属性有 href、title、id、src、className,使用DOM对象操作属性,常用操作有 使用元素获取属性值,以及使用元素修改属性值。以下以a、img标签为例。
语法:
element.属性 = 'xxx';需求:点击按钮修改a标签的地址和文本显示
var btn = document.getElementById("btn");
btn.onclick = function () {
var aObj = document.getElementById("ak");
//根据id获取超链接,设置href属性
aObj.href = "http://www.wolfcode.cn";
//根据id获取超链接,设置文字内容
aObj.innerText ="叩丁狼";
}需求:点击按钮修改图片的title属性
<input type="button" value="显示效果" id="btn">
<img src="images/cangjingkong.jpg" alt="" title="嘎嘎">
<script>
var btn = document.getElementById("btn");
btn.onclick = function () {
var imgObjs = document.getElementsByTagName("img");
imgObjs[0].title = "哈哈";
}
</script>七、为多个元素绑定事件(this)
需求:点击按钮设置多个p标签的文字内容
var btn = document.getElementById("btn");//获取id为btn的元素
btn.onclick = function () {
//根据标签名字获取标签
var pObjs = document.getElementsByTagName("p");
//无论获取的是一个标签,还是多个标签,最终都是在数组中存储的,这行代码的返回值就是一个数组
console.log(pObjs);
//循环遍历这个数组
for(var i =0; i < pObjs.length; i++){
//每个p标签,设置文字
pObjs[i].innerText = "我们都是P标签";
}
};需求:点击不同的按钮,p标签展示对应按钮的内容
var btn = document.getElementsByTagName("button");
var op = document.getElementsByTagName("p")[0];
// 获取到的按钮是一个数组,不能直接绑定事件
console.log(btn);
// 遍历这个数组 挨个绑定事件
for (var i = 0; i < btn.length; i++) {
btn[i].onclick = function () {
// this指向是就是事件源
var text = this.innerText;
console.log(text);
op.innerText = '点击了' + text;
}
}排他思想案例:点击当前按钮高亮显示,其他同级按钮取消高亮显示
var btn = document.getElementsByTagName("button");
for(var i=0;i<btn.length;i++){
btn[i].onclick = function(){
// 1.先处理所有元素,做初始化操作
for(var j = 0;j<btn.length;j++){
btn[j].style.background = "none";
}
// 2.再修改当前元素
this.style.background = "#cfc";
}
}js进阶第02天
今日要点:
理解函数封装的思想
创建
调用
传参
返回
掌握表单元素属性值的获取及修改
表单的值
选中效果
禁用属性
了解其他类型的事件绑定
掌握如何动态设置class
理解开关思想的应用
掌握三元表达式的使用
掌握tab案例实现的思想---------jQuery还会讲
掌握全选反选功能实现----------先理解思路,再一行一行去看,再整体理解
一、封装获取元素的方法
封装思想——函数封装——代码复用
function get_id(id){
// 这个函数是专门来通过id获取元素
return document.getElementById(id)
}
function get_els(parentId, tagName){
// 这个函数是专门来获取某个父标签范围内的某些标签
return get_id(parentId).getElementsByTagName(tagName)
}二、表单元素属性
常用的表单元素包括 input、select、textarea、button等,下面我们学习这些表单元素中常用的属性。
value 用于获取和设置表单元素的内容
type 用于获取和设置input标签的类型
checked 复选框选中属性(true表示选中, false表示不选中)
disabled 用于禁用表单输入或选择操作
需求:点击按钮修改input的类型和内容
html和css代码
<input type="button" value="按钮" id="btn">JavaScript代码
var btnObj = document.getElementById("btn");
btnObj.onclick = function () {
//修改按钮的value属性
//btnObj.value = "我是按钮我被修改了";
this.value = "我是按钮我被修改了";
this.type = "text";
this.id = "btn2";//审查元素看到id也是可以被修改的
}需求:点击按钮修改单选框的值(性别男改成女)
html和css代码
<input type="button" value="修改性别" id="btn1">
<input type="radio" name="sex" id="rad0" checked="checked">男
<input type="radio" name="sex" id="rad1">女
<input type="radio" name="sex" >保密JavaScript代码
var btn1 = document.getElementById("btn1");
btn1.onclick = function () {
document.getElementById("rad1").checked = true;
}需求:点击按钮修改复选框的值(选中 #ck1 和 #ck2 )
html和css代码
<input type="button" value="选择兴趣" id="btn2"/>
<input type="checkbox" name="like" />吃饭
<input type="checkbox" name="like" />睡觉
<input type="checkbox" name="like" id="ck1" />打豆豆
<input type="checkbox" name="like" />打篮球
<input type="checkbox" name="like" />打足球
<input type="checkbox" name="like" id="ck2" />敲代码JavaScript代码
var btn2 = document.getElementById("btn2");
btn2.onclick = function () {
document.getElementById("ck1").checked = true;
document.getElementById("ck2").checked = true;
}需求:点击按钮禁止文本框输入
html和css代码
<input type="button" value="禁用文本框" id="btn">
<input type="text" value="文本框" id="txt">JavaScript代码
// 需求:点击按钮时,禁用文本框
//先根据id获取按钮,为按钮注册点击事件,添加事件处理函数
var btn = document.getElementById("btn");
btn.onclick = function () {
//根据id获取文本框,设置disabled属性
document.getElementById("txt").disabled = true;
}三、其他事件类型
之前的课程里,我们一直在用click点击事件,当然,点击事件也是我们使用最多的事件类型。那么,除了点击事件之外,我们今天再介绍几种常见的事件类型。
dblclick——双击事件
mouseover——鼠标移入事件
mouseout——鼠标移出事件
change——表单值改变事件
focus——表单聚焦事件
blur——表单失焦事件
input——表单输入事件
四、动态设置class
设置class的方法:
// 修改类名 可以同时修改多个
element.className = "name1 name2 ..."
// 在类名列表里添加类名
element.classList.add("active");
// 在类名列表里删除类名
element.classList.remove("active");3.1、开关思想
开关思想:定义一个变量, 这个变量决定了一个状态,事件触发的时候,根据这个变量的值,执行对应的操作,操作完还需要修改这个变量的值。
// 需要一个变量存储状态
var flag = true;
get_id("btn").onclick = function () {
// console.log("点击事件触发了");
// if(flag==true){
if (flag) {
// 把div的left值改成-200px
my$("box").style.left = "-200px";
// 需要把flag改成false,防止下一次点击这个flag还是true,如果flag还是true,就会一直走这里的代码
flag = false
} else {
my$("box").style.left = "0px";
// 防止下一次点击flag还是false,就还是会走这里的代码
flag = true
}
}开关灯案例:
<style>
.cls{
background-color: black;
}
</style>
<input type="button" value="开/关灯" id="btn">JavaScript代码
var btn = document.getElementById("btn");
btn.onclick = function () {
// document.body可以获取body标签
/* if (flag) {
document.body.className = "cls"
flag = false
} else {
document.body.className = ""
flag = true
} */
// 其实只需要判断当前body的类名是不是cls
// document.body.className = 条件 ? true : false
//叫做 三元表达式 三目运算符
document.body.className = document.body.className != "cls"?"cls":"";
}3.2、tab栏案例
描述:
鼠标点击对应按钮的时候,当前按钮高亮显示,对应的内容(盒子)也会跟着发生改变。
html与css代码:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Tab栏</title>
<style type="text/css">
div,
span,
ul,
li,
h2,
body {
padding: 0;
margin: 0;
list-style: none;
}
.all {
width: 440px;
border: 1px solid #000;
padding: 10px;
margin: 80px auto;
}
.all h2 {
height: 30px;
text-align: center;
display: flex;
justify-content: space-between;
}
.all h2 span {
width: 100px;
height: 30px;
background: #CCC;
text-align: center;
cursor: pointer;
}
.all h2 span.current {
background: #FF3366;
}
.all ul li {
display: none;
background: #FF3366;
height: 200px;
}
.all ul li.current {
display: block
}
</style>
</head>
<body>
<div class="all">
<h2>
<span class="current">新闻</span>
<span>娱乐</span>
<span>游戏</span>
<span>财经</span>
</h2>
<ul>
<li class="current">新闻</li>
<li>娱乐</li>
<li>游戏</li>
<li>财经</li>
</ul>
</div>
</body>
</html>JavaScript代码
var btns = document.getElementsByTagName("span");
var pages = document.getElementsByTagName("li");
for (var i = 0; i < btns.length; i++) {
btns[i].index = i;
btns[i].onmouseenter = function () {
for (var j = 0; j < btns.length; j++) {
btns[j].className = "";
pages[j].className = "";
}
this.className = "current";
pages[this.index].className = "current";
};
}五、全选反选功能
描述:
默认进来显示"全选",选框未选中
选择"全选"选框,列表的选框全部选中,文字变成"全不选"
点击"全不选"选框,列表所有选框取消选中,文字变回"全选"
点击列表对应的选框,如果全部都选中,触发"全选"选框选中,文字变成"全不选"
取消任意一个列表选框,逻辑变成没有全选,取消"全选"选框选中,文字变成"全选"
按钮"反选",选中与列表选框相反的选框,逻辑上遵循上述全选规则
html和css代码
<!DOCTYPE html>
<html lang="en">
<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>全选反选功能</title>
<style>
* {
padding: 0;
margin: 0;
}
.wrap {
width: 300px;
margin: 100px auto 0;
}
table {
border-collapse: collapse;
border-spacing: 0;
border: 1px solid #c0c0c0;
width: 300px;
}
th,
td {
border: 1px solid #d0d0d0;
color: #404060;
padding: 10px;
}
th {
background-color: #09c;
font: bold 16px "微软雅黑";
color: #fff;
}
td {
font: 14px "微软雅黑";
}
td:nth-of-type(1) {
text-align: center;
}
tbody tr,
tfoot tr {
background-color: #f0f0f0;
}
tbody tr:hover {
cursor: pointer;
background-color: #fafafa;
}
button {
width: 50px;
}
</style>
</head>
<body>
<div class="wrap">
<table>
<thead>
<tr>
<th>
<input type="checkbox" id="j_cbAll" />
<span id="txt">全选</span>
</th>
<th>菜名</th>
<th>饭店</th>
</tr>
</thead>
<tbody id="j_tb">
<tr>
<td>
<input type="checkbox" />
</td>
<td>红烧肉</td>
<td>好再来</td>
</tr>
<tr>
<td>
<input type="checkbox" />
</td>
<td>西红柿鸡蛋</td>
<td>好再来</td>
</tr>
<tr>
<td>
<input type="checkbox" />
</td>
<td>油炸榴莲</td>
<td>好再来</td>
</tr>
<tr>
<td>
<input type="checkbox" />
</td>
<td>清蒸助教</td>
<td>好再来</td>
</tr>
</tbody>
<tfoot>
<tr>
<td colspan="5"><button id="rev">反选</button></td>
</tr>
</tfoot>
</table>
</div>
</body>
</html>JavaScript代码
//获取全选的这个复选框
var ckAll = get_id("j_cbAll");
//获取文字显示span
var txt = get_id("txt");
//获取tbody中所有的小复选框
var cks = get_els("j_tb", "input");
//点击全选的这个复选框,获取他当前的状态,然后设置tbody中所有复选框的状态
ckAll.onclick = function () {
console.log(this.checked);
for (var i = 0; i < cks.length; i++) {
cks[i].checked = this.checked;
}
//顺便修改文本显示
txt.innerText = this.checked ? "全不选" : "全选";
};
//获取tbody中所有的复选框,分别注册点击事件
for (var i = 0; i < cks.length; i++) {
/* cks[i].onclick = function () {
var flag = true; //默认都被选中了
//判断是否所有的复选框都选中
for (var j = 0; j < cks.length; j++) {
if (!cks[j].checked) {
//没选中就进来了
flag = false;
break;
}
}
//全选的这个复选框的状态就是flag这个变量的值
ckAll.checked = flag;
//记得修改文本显示
txt.innerText = flag?"全不选":"全选";
}; */
cks[i].onclick = fn;
}
// 反选功能
// 获取按钮
var btn = get_id("rev");
btn.onclick = function () {
for (var i = 0; i < cks.length; i++) {
cks[i].checked = !cks[i].checked
}
fn();
}
// 代码复用,函数封装
function fn() {
var flag = true; //默认都被选中了
//判断是否所有的复选框都选中
for (var j = 0; j < cks.length; j++) {
if (!cks[j].checked) {
//没选中就进来了
flag = false;
break;
}
}
//全选的这个复选框的状态就是flag这个变量的值
ckAll.checked = flag;
//记得修改文本显示
txt.innerText = flag ? "全不选" : "全选";
}js进阶第03天
今日要点(DOM操作):
理解什么的节点以及节点的属性
掌握父子节点的获取
了解兄弟节点的获取
掌握属性节点的操作方法(自定义属性的三个方法)
掌握元素节点的常用操作方法(必考)
添加元素两个方法
删除节点方法
替换节点方法
创建 元素
思维: 1.初始化 2. 校验
一、什么是节点

回顾概念:
文档:document
元素:页面中所有的标签,元素---element, 标签----元素---对象
节点:页面中所有的内容(标签,属性,文本(文字,换行,空格,回车)),Node
根元素:html标签节点的属性:(可以使用标签--元素.出来,可以使用属性节点.出来,文本节点.点出来)
nodeType:节点的类型
nodeName:节点的名字
nodeValue:节点的值二、节点的获取(包含元素节点)
相关html代码
<div id="dv">
<span>这是div中的第一个span标签</span>
<p>这是div中的第二个元素,第一个p标签</p>
<ul id="uu">
<li>乔峰</li>
<li>鹿茸</li>
<li id="three">段誉</li>
<li>卡卡西</li>
<li>雏田</li>
</ul>
</div>获取父节点(属性):
// 获取某节点的父级节点
node.parentNode
// 获取某节点的父级元素
node.parentElement// 获取某节点的子节点
node.childNodes
// 获取某节点的子元素
node.children属性节点(方法):
// 获取属性节点
node.getAttributeNode("name")// 获取某节点的第一个子节点
node.firstChild;//-----------------------IE8中是第一个子元素
// 获取某节点的第一个子元素
node.firstElementChild;//----------------IE8中不支持
// 获取某节点的最后一个子节点
node.lastChild;//------------------------IE8中是第一个子元素
// 获取某节点的最后一个子元素
node.lastElementChild;//-----------------IE8中不支持
// 获取某节点的前一个兄弟节点
node.previousSibling;
// 获取某节点的前一个兄弟元素
node.previousElementSibling;
// 获取某节点的后一个兄弟节点
node.nextSibling;
// 获取某节点的后一个兄弟元素
node.nextElementSibling;案例:点击按钮设置div中p标签改变背景颜色(掌握)
html和css代码
<!DOCTYPE html>
<html lang="en">
<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>
div {
width: 300px;
height: 450px;
border: 1px solid red;
}
</style>
</head>
<body>
<input type="button" value="变色" id="btn" />
<div id="dv">
<span>这是span</span>
<p>这是p</p>
<span>这是span</span>
<p>这是p</p>
<span>这是span</span>
<p>这是p</p>
<span>这是span</span>
<a href="http://www.baidu.com">百度</a>
</div>
</body>
</html>JavaScript代码
get_id("btn").onclick = function () {
//先获取div
var dvObj = get_id("dv");
//获取里面所有的子节点
var nodes = dvObj.childNodes;
//循环遍历所有的子节点
for (var i = 0; i < nodes.length; i++) {
//判断这个子节点是不是p标签
if (nodes[i].nodeType == 1 && nodes[i].nodeName == "P") {
nodes[i].style.backgroundColor = "red";
}
}
};三、属性节点(自定义属性)
自定义属性操作方法:
//设置自定义属性:
element.setAttribute("属性名","属性值");
//获取自定义属性:
element.getAttribute("属性名");
//移除标签行内属性
element.removeAttribute("属性名");html和css代码
<!DOCTYPE html>
<html lang="en">
<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>
ul {
list-style: none;
cursor: pointer;
}
</style>
</head>
<body>
<ul id="uu">
<li>小明的成绩</li>
<li>小丽的成绩</li>
<li>小花的成绩</li>
<li>小李的成绩</li>
<li>乔峰的成绩</li>
</ul>
</body>
</html>JavaScript代码
//获取所有的li标签,然后为每个标签中动态的添加自定义属性和值
//点击的时候获取该标签的自定义属性的值
//根据id获取ul标签,并且或者该标签中所有的li
var list = get_els("uu","li");
//循环遍历
for(var i = 0; i < list.length; i++){
//先为每个li添加自定义属性
list[i].setAttribute("score",(i+1)*10);
//点击每个li标签,显示对应的自定义属性值
list[i].onclick = function () {
alert(this.getAttribute("score"));
// this.removeAttribute("score");
}
}四、创建元素的方式
4.1、document.write 创建(熟悉)
document.write() 方法可向文档写入 HTML 表达式或 JavaScript 代码。
html和css代码
<input type="button" value="创建一个p" id="btn"/>
JavaScript代码
//document.write("标签代码及内容");
get_id("btn").onclick=function () {
document.write("<p>这是一个p</p>");//会重写
};4.2、innerHTML 创建(掌握)
语法:
// 某个元素节点中间插入一段HTML代码
element.innerHTML=HTML案例:动态添加列表项
<input id="txt" type="text">
<button id="btn">添加</button>
<ul id="box"></ul>
get_id("btn").onclick = function(){
var txt = get_id("txt").value;
console.log(txt);
get_id("box").innerHTML = get_id("box").innerHTML + `<li> ${txt} </li>`
get_id("txt").value = "";
}案例:动态创建列表
<button id="btn">创建列表</button>
<div id="dv"></div>
var names = ["杨过", "郭靖", "张无忌", "张三丰", "乔峰", "段飞", "丁棚"];
get_id("btn").onclick = function () {
// 将整个列表看成一个字符串,先创建开头的ul
var str = "<ul>";
// 根据数据遍历循环创建li
for (var i = 0; i < names.length; i++) {
str += `<li>${names[i]}</li>`;
}
str += "</ul>"
console.log(str);
get_id("dv").innerHTML = str;
}4.3、createElement 创建(掌握)
语法:
// 第一步、先创建元素节点
chlidNode = document.createElement("p");
// 第二步,把元素追加到父级元素中
parentNode.appendChild(chlidNode);案例:动态创建列表
<button id="btn">创建列表</button>
<div id="dv"></div>
var names = ["杨过", "郭靖", "张无忌", "张三丰", "乔峰", "段飞", "丁棚"];
get_id("btn").onclick = function () {
// 先创建元素ul
var box = document.createElement("ul");
// 遍历循环数据,创建li
for(var i=0;i<names.length;i++){
var li = document.createElement("li");
// 写入文本
li.innerText = names[i];
// 每一次遍历都将li追加进ul中
box.appendChild(li);
}
console.log(box);
// 盒子追加元素ul
get_id("dv").appendChild(box);
}案例:动态创建表格
html和css代码
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<style>
table {
border: 1px solid black;
border-spacing: 0;
}
td {
border: 1px solid black;
}
</style>
</head>
<body>
行:<input type="text" id="row"><br>
列:<input type="text" id="col"><br>
<button id="btn">点击创建表格</button>
</body>
</html>JavaScript代码
//创建表格
var otab = document.createElement("table");
// 直接将表格插入到body中
document.body.appendChild(otab);
get_id("btn").onclick = function () {
var rowVal = Number(get_id("row").value);
var colVal = Number(get_id("col").value);
//创建tr 行
for (var i = 0; i < rowVal; i++) {
var otr = document.createElement("tr")
otab.appendChild(otr);
// 创建td 列
for (var j = 0; j < colVal; j++) {
var otd = document.createElement("td")
otr.appendChild(otd);
otd.innerText = `我是第${i+1}行${j+1}列`;
}
}
}五、元素节点的操作
语法:
//添加到容器(父级节点)的结尾,并返回新增节点
parentNode.appendChild(新节点);
//参照节点之前插入节点,并返回新节点
parentNode.insertBefore(新节点,参照节点)
//用新节点替换当前节点,并返回被替换节点(当前节点)
parentNode.replaceChild (新节点,当前节点 )
//移除节点,并返回移除的节点
//不能直接删除自己,是需要先到父级元素,再来删除自己
parentNode.removeChild(当前元素)
//克隆节点,返回一个被克隆的新节点
//一个布尔值参数,默认false为浅拷贝,只复制容器,true为深拷贝,包括内容全部复制
被克隆的元素.cloneNode(true|false)html和css代码
<button id="btn">最前插入新节点</button>
<ul id="uu">
<li>桃园豪杰三结义 <button class="rep">替换</button> <button class="del">删除</button></li>
<li>孙坚跨江击刘表 <button class="rep">替换</button> <button class="del">删除</button></li>
<li>吕奉先射戟辕门 <button class="rep">替换</button> <button class="del">删除</button></li>
<li>关公赚城斩车胄 <button class="rep">替换</button> <button class="del">删除</button></li>
<li>玄德荆州依刘表 <button class="rep">替换</button> <button class="del">删除</button></li>
<li>赵子龙单骑救主 <button class="rep">替换</button> <button class="del">删除</button></li>
<li>诸葛亮痛哭庞统 <button class="rep">替换</button> <button class="del">删除</button></li>
<li>关云长败走麦城 <button class="rep">替换</button> <button class="del">删除</button></li>
<li>武侯弹琴退仲达 <button class="rep">替换</button> <button class="del">删除</button></li>
<li>魏主政归司马氏 <button class="rep">替换</button> <button class="del">删除</button></li>
</ul>JavaScript代码
// 最前插入新节点
btn.onclick = function () {
var newli = document.createElement("li");
newli.innerText = "皇叔败走投袁绍";
uu.insertBefore(newli, uu.children[0])
}
var orep = document.querySelectorAll(".rep");
var odel = document.querySelectorAll(".del");
// console.log(orep);
// console.log(odel);
// 给每一条数据的替换和删除按钮绑定事件
for (var i = 0; i < orep.length; i++) {
orep[i].onclick = function () {
var newli = document.createElement("li");
newli.innerText = "定三分隆中决策";
uu.replaceChild(newli, this.parentElement)
}
odel[i].onclick = function () {
uu.removeChild(this.parentElement)
}
}演讲-------讲功能(全选反选/tab栏/DOM的增删改查),不需要写
js进阶第04天
今日要点:
说出来事件执行的三个阶段(面试)
说出来什么是事件冒泡(面试)
掌握怎样阻止事件冒泡和默认行为(至少能看懂, 下次找文档可以实现, 配得上软件的提醒)
掌握事件委托的使用(重点)
掌握DOM 2级事件的绑定和解绑------事件监听
语法
特点: 给同一个元素重复绑定同类事件
掌握入口函数的应用---------------------依赖DOM加载
掌握如何实现页面的跳转以及回退
一、事件详解
3.1、事件的三个阶段(事件冒泡)
首先来看一段代码:
<div id="dv">
<button id="btn">按钮</button>
</div>
get_id("btn").onclick = function(){
console.log(this);
}
get_id("dv").onclick = function(){
console.log(this);
}上述代码运行会发现,点击按钮的时候,不仅仅打印了按钮,还打印出了盒子div,这个行为就叫做事件冒泡:
多个元素有层次关系,这些元素都注册了相同的事件,如果里面的元素的事件触发了,外面的元素的该事件也会触发。

事件有三个阶段:
事件发生的时候,要经过事件的三个阶段,我们常常使用的是事件冒泡阶段,而其他两个阶段不能人为干预。
在JavaScript中,事件有以下三个阶段:
3.1.1、事件对象event
Event 对象代表事件的状态,比如事件在其中发生的元素、键盘按键的状态、鼠标的位置、鼠标按钮的状态
兼容处理:
get_id("btn").onclick = function(e){
var e=e || window.event // 兼容IE8
console.log(e);
}
//e.pageX——表示鼠标距离,网页左上角的水平距离
//e.pageY——表示鼠标距离,网页左上角的垂直距离
//e.target——返回触发此事件的元素(事件的目标节点)3.1.2、阻止事件冒泡
语法:
e.stopPropagation();//停止传播,不再派发事件,符合w3c标准,谷歌和火狐支持 IE8不支持
e.cancelBubble=true;//确定取消冒泡,IE特有 居然没兼容html和css代码:
<div id="dv1" style="width: 500px;height: 500px;background-color: gray;">
<div id="dv2" style="width: 300px;height: 300px;background-color: skyblue;">
<div id="dv3" style="width: 100px;height: 100px;background-color: pink;"></div>
</div>
</div>JavaScript代码
get_id("dv1").onclick = function (e) {
console.log(e);
// console.log(e.target);
}
get_id("dv2").onclick = function (e) {
console.log(this.id);
}
get_id("dv3").onclick = function (e) {
console.log(this.id);
// var e=e||window.event;
// e.cancelBubble=true;
e.stopPropagation();
}3.1.3、阻止事件默认行为
语法:
e.preventDefault()//阻止默认 符合w3c标准 只有IE8不支持
e.returnValue=false;//阻止默认行为 IE特有 火狐不支持(亲测支持)html和css代码:
<a id="wolf" href="https://www.wolfcode.cn">叩丁狼</a>JavaScript代码
get_id("wolf").onclick = function (e) {
console.log(this.id);
var e = e || window.event;
if (e.preventDefault) {
e.preventDefault();
} else {
e.returnValue = false;
}
}3.2、事件委托(掌握)
事件委托:又叫事件代理,原理就是利用事件冒泡的特点:当子元素的事件发生时,父元素的同名事件也会发生——指定一个事件处理程序,就可以管理某一类型的所有事件。
优点:1. 给父元素绑定一个事件,可以管理一类子元素事件
2. 给动态添加的元素绑定事件(功能)
html和css代码
<ul id="ul">
<li>西施</li>
<li>貂蝉</li>
<li>昭君</li>
<p>凤姐</p>
<span>芙蓉姐姐</span>
</ul>JavaScript代码
//事件冒泡的应用(事件委托)
get_id('ul').onclick = function (e) {
//e.target:获取真正触发事件的那个元素
//console.log(e.target);
var target = e.target;
// 只操作li元素
if (target.nodeName == "LI") {
target.style.backgroundColor = '#cfc';
}
}3.3、DOM 2级事件(掌握)
事件源.on事件=function(){要执行的处理程序;}
我们之前学习的事件绑定叫做DOM的0级事件,缺点是重复绑定会覆盖之前的事件,
而2级事件可以实现一种事件绑定多个事件处理函数,适合多人开发。
2级事件定义:将指定的监听器注册到 EventTarget(事件目标)上,当该对象触发指定的事件时,指定的回调函数就会被执行。说白了,就是2级事件可以将事件监听器注册到btn按钮上,当事件发生时,调用事件处理函数。
3.3.1、事件绑定:
又叫事件监听:使同一个事件源一次获多次触发事件函数
//谷歌和火狐支持,IE8不支持(掌握)
对象.addEventListener("事件类型",事件处理函数,false);
//谷歌不支持,火狐不支持,IE8支持(了解)
对象.attachEvent("on事件类型",事件处理函数);代码示例:
<div id="dv">
<button id="btn">按钮</button>
</div>
//对象.addEventListener("事件类型",事件处理函数,false);
//参数1:事件的类型---事件的名字,没有on
//参数2:事件处理函数---函数(命名函数,匿名函数)
//参数3:布尔类型,默认false-----指定事件是否在捕获(true )或冒泡(false)阶段执行
//为同一个元素绑定多个相同的事件
get_id("btn").addEventListener("click", function () {
console.log("我是第一个点击事件");
}, false);
//为同一个元素绑定多个相同的事件
get_id("btn").addEventListener("click", function () {
console.log("我是第二个点击事件");
}, false);
//为同一个元素绑定多个相同的事件
get_id("btn").addEventListener("click", function () {
console.log("我是第三个点击事件");
}, false);
//验证第三个参数
get_id("dv").addEventListener("click", function () {
console.log("我是div的点击事件");
}, true);如果想支持所有浏览器,则想办法解决兼容性问题即可,现在只需了解兼容性问题的解决,将来会使用框架,框架已经帮我们解决了浏览器兼容性问题。
3.3.2、事件解绑:
在开发中,如果想让按钮的事件处理函数只能执行一次,怎么办?如何移除元素的事件?
语法:
// 0级事件解绑:直接将dom.onclick = null;
// addEventListener对应的事件解绑(掌握)
对象.removeEventListener("事件类型",事件处理函数,false);
// attachEvent对应的事件解绑(了解)
对象.detachEvent("on事件类型",事件处理函数);html和css代码
<button id="btn1">绑定事件</button>
<button id="btn2">解绑事件</button>JavaScript代码
// get_id("btn1").addEventListener("click", function () {
// console.log("第一个");
// }, false);
// get_id("btn1").addEventListener("click", function () {
// console.log("第二个");
// }, false);
// //点击第二个按钮把第一个按钮的第一个点击事件解绑
// get_id("btn2").onclick = function () {
// get_id("btn1").removeEventListener("click", function () {
// console.log("第一个"); //这样就没解绑成功,因为是两个匿名函数,不是同一个函数
// }, false)
// }
//解绑事件的时候,需要在绑定事件的时候,使用命名函数,否则解绑的不是一个函数
function f1() {
console.log("第一个");
}
function f2() {
console.log("第二个");
}
get_id("btn1").addEventListener("click", f1, false);
get_id("btn1").addEventListener("click", f2, false);
//点击第二个按钮把第一个按钮的第一个点击事件解绑
get_id("btn2").onclick = function () {
get_id("btn1").removeEventListener("click", f1, false);
}二、入口函数(window.onload)
window.onload 方法用于在网页加载完毕后立刻执行的操作。
为什么要使用这个方法呢?
因为 JavaScript 中的函数方法需要在 HTML 文档渲染完成后才可以使用,如果没有渲染完成,此时的 DOM 树是不完整的,这样在调用一些 JavaScript 代码时就可能报出"undefined"错误。
比如事件绑定写在body之前:
window.onload = function () {
//此时body还没渲染,btn是不存在的
var btn = document.getElementById("btn");
btn.onclick = function () {
alert("哈哈");
}
}三、BOM介绍
window对象:是浏览器的顶级对象,全局对象。
alert 等一系列弹框方法
open方法:打开新窗口
close方法:关闭当前窗口
document对象:HTML 文档
location对象:包含当前网页文档的URL信息
history对象:包含浏览器窗口访问过的URL信息
navigator对象:包含有关浏览器的信息,如名称,版本和系统等。
定时器
3.1、Location 对象
Location 对象是 Window 对象的一个部分,包含当前网页文档的URL信息,可通过 window.location 属性来访问。默认全局对象就是window,所有window可以不写。
重点掌握:
location.href——获取完整URL
重写location.href可以跳转页面
3.2、History 对象
History 对象是 window 对象的一部分,包含浏览器窗口访问过的URL信息(历史记录),可通过 window.history 属性对其进行访问。这个对象包含几个常用属性(方法):
length属性——历史记录的长度(个数)。
back() 方法——向后跳转,加载 history 列表中的前一个 URL。
forward()方法——向前跳转,加载 history 列表中的下一个 URL。
go()方法——加载 history 列表中的某个具体页面,参数 1 表示向前跳转,-1表示向后跳转。
代码示例:
=============== first.html ===============
<h1>这是第1个页面</h1>
<a href="last.html">跳去last</a>
<button id="btn">跳去last</button>
<script>
console.log(window.history);
var oBtn = document.getElementById('btn');
oBtn.onclick = function () {
if (history.length == 1) {
location.href = "last.html"
} else {
history.forward(); // 向前跳转
// history.go(1);
}
}
</script>=============== last.html ===============
<h1>这是第2个页面</h1>
<button id="btn">回去first</button>
<script>
console.log(history);
var oBtn = document.getElementById('btn');
oBtn.onclick = function () {
history.back(); // 向后跳转
// history.go(-1);
}
</script>js进阶第05天
今日要点:
一、三大家族
1.1、偏移量offset(掌握)
offset是偏移、位移、补偿的意思(取整数值四舍五入),表示元素的偏移量。
offsetHeight和offsetWidth
元素盒子模型的宽高(width/height + padding+border)
offsetLeft和offsetTop
1、表示当前元素距离它最近的相对父级(定位元素)的水平或者垂直距离。
2、如果它一直没有相对父级元素,默认指向body
offsetParent和parentNode
offsetParent 指的是最近的一个相对父级元素(默认指向body)
parentNode 就是直接父级(标签结构中的父子关系 )
html和css代码
<!DOCTYPE html>
<html lang="en">
<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>
* {
margin: 0;
padding: 0;
border: 0;
list-style: none;
}
div {
width: 300px;
height: 300px;
border: 1px solid #000;
margin: 100px;
position: relative;
}
span {
width: 100px;
height: 100px;
border: 1px solid #000;
position: absolute;
left: 120px;
top: 30px;
}
</style>
</head>
<body>
<div>
<span></span>
</div>
</body>
</html>JavaScript代码
var oBox = document.getElementsByTagName('div')[0];
console.log(oBox.offsetLeft); // 到文档左侧的距离
console.log(oBox.offsetTop); // 到文档顶部的距离
console.log(oBox.offsetWidth); // 获取盒子的实际占位宽度(border+contentWidth+padding)
console.log(oBox.offsetHeight); // 获取盒子的实际占位高度(border+contentHeight+padding)
console.log("-------------------------------------");
var spanTag = document.getElementsByTagName('span')[0];
console.log(spanTag.offsetLeft); // 到父盒子左侧的距离(前提是父盒子有定位,没定位则直接索引到body)
console.log(spanTag.offsetTop); // 到父盒子顶部的距离(前提是父盒子有定位,没定位则直接索引到body)
console.log(spanTag.offsetWidth); // 获取span的实际占位宽度(border+contentWidth+padding)
console.log(spanTag.offsetHeight); // 获取span的实际占位高度(border+contentHeight+padding)
console.log(spanTag.offsetParent); // 相对父级元素(默认指向body)1.2、滚动scroll(掌握)
scroll是长卷纸,卷轴的意思,表示浏览器滚动时元素的卷曲值。
scrollHeight和scrollWidth
代表获容器内部可滚动的宽度和高度(width/height + padding)
包括由于溢出而无法展示在网页的不可见部分
scrollTop和scrollLeft
相对父盒子,元素 向上/向左 卷曲出去(滚出去)的距离
html和css代码
<!DOCTYPE html>
<html lang="en">
<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>
* {
margin: 0;
}
#box {
width: 200px;
height: 200px;
overflow: auto;
}
#content {
width: 300px;
height: 300px;
background: #ccf;
border: 1px solid #000;
padding: 2px;
}
</style>
</head>
<body>
<div id="box">
<div id="content">
<p> 客户:“这个图下班之前必须发给我!” 设计师:“好的!”
第二天清早。 客户:“图怎么还没发过来?” 设计师:“我还没下班呢…”。
客户:“这个图下班之前必须发给我!” 设计师:“好的!”
第三天清早。客户:“图怎么还没发过来?” 设计师:“我还没下班呢…”</p>
</div>
</div>
<button id="btn">按钮</button>
</body>
</html>JavaScript代码
var oBox = document.getElementById('box');
var oContent = document.getElementById('content');
var oBtn = document.getElementById("btn")
console.log(oContent.scrollWidth); // 内容盒子的可滚动宽度
console.log(oContent.scrollHeight); // 内容盒子的可滚动高度
console.log(oBox.scrollWidth); // 限定了宽高的父盒子中,其内容盒子可滚动的宽度
console.log(oBox.scrollHeight); // 限定了宽高的父盒子中,其内容盒子可滚动的高度
oBtn.onclick = function () {
console.log("-------------------------");
console.log(oBox.scrollTop); // 获取内容盒子相对于父盒子已经滚动了多少高度
console.log(oBox.scrollLeft); // 获取内容盒子相对于父盒子已经滚动了多少宽度
}1.3、客户区client(拓展)
client获取的是元素的可视区域
clientWidth和clientHeight
不包含border在内的实际宽度(width/height + padding)
clientLeft和clientTop
打印出盒子 左侧边框/顶部边框 的厚度
几乎不用
案例:吸顶导航
html和css代码
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>吸顶导航</title>
<style>
* {
margin: 0;
padding: 0;
}
div {
width: 100%;
height: 100px;
line-height: 100px;
text-align: center;
background: skyblue;
}
</style>
</head>
<body>
<section>
<p>段落</p>
...
<p>段落</p>
<div id="box">吸顶导航</div>
<p>段落</p>
...
<p>段落</p>
</section>
</body>
</html>JavaScript代码
// 获取盒子的Y坐标
var boxTop = box.offsetTop;
console.log(boxTop);
// scroll 滚动事件
window.onscroll = function () {
// 获取文档滚出的距离
var winTop = document.documentElement.scrollTop;
console.log(winTop);
// 每当滚动的时候都需要获取超出窗口的范围 然后和盒子Y坐标做对比
// 如果滚动距离大于等于盒子Y坐标,就设置成固定定位,否则去掉盒子定位
if (winTop >= boxTop) {
box.style.position = "fixed";
box.style.top = 0;
} else {
box.style.position = "static";
}
}二、定时器(重点)
2.1、单次定时器
语法:
// 单次定时器,只能执行一次
setTimeout(function () { },time);
// - 参数1:function 必需。函数,过time时间之后执行的业务逻辑。
// - 参数2:time 可选。执行或调用 function 需要等待的时间,以毫秒ms计。默认为 0。1s=1000ms
// 清除setTimeout单次定时器
clearTimeout(定时器名称);代码示例:
var timer = setTimeout(function () {
console.log("单次定时器");
}, 2000);
//点击按钮清除定时器
var btn = document.getElementById("btn");
btn.onclick = function () {
clearTimeout(timer);
console.log("已经清除");
}2.2、循环定时器
语法:
// 循环定时器,不停歇,每过一段时间time,执行一次。
setInterval(function () { },time);
// 参数同setTimeout
// 清除setInterval循环定时器
clearInterval(定时器名称);代码示例:
var timer = setInterval(function () {
alert("循环定时器");
},2000);
//点击按钮清除定时器
var btn = document.getElementById("btn");
btn.onclick = function () {
clearInterval(timer);
}案例:设置div的宽度
html和css代码
<!DOCTYPE html>
<html lang="en">
<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>
* {
margin: 0;
padding: 0;
}
div {
width: 200px;
height: 150px;
background-color: red;
border-radius: 100px;
}
</style>
</head>
<body>
<button id="btn">变宽</button>
<div id="dv"></div>
</body>
</html>JavaScript代码
get_id("btn").onclick = function () {
// 初始宽度
var width = 200;
// 开启定时器
var timer = setInterval(function () {
// 每次加10
width += 10;
// 设置临界值,最大只能是800
if (width >= 800) {
// 清除定时器
clearInterval(timer);
}
// 实时设置div宽度
get_id("dv").style.width = width + "px";
}, 20);
};案例:随机点名系统
html和css代码
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>随机点名系统</title>
<style>
body {
background-color: hotpink;
}
.box {
width: 1000px;
height: 240px;
margin: 0 auto;
margin-top: 100px;
clear: both;
}
#btn {
width: 100px;
height: 30px;
margin-left: 600px;
margin-top: 50px;
}
.name {
width: 100px;
height: 30px;
float: left;
background-color: antiquewhite;
margin-left: 10px;
margin-top: 10px;
text-align: center;
line-height: 30px;
}
h1 {
text-align: center;
}
</style>
</head>
<body>
<h1>随机点名系统</h1>
<div class="box" id="box"></div>
<button id="btn">点名</button>
</body>
</html>JavaScript代码
//创造虚拟后台数据
var arrs = ["宋江", "卢俊义", "吴用", "公孙胜", "林冲", "花荣", "鲁智深", "武松", "李逵", "晁盖", "燕青", "潘金莲", "阎婆惜", "关胜", "秦明", "呼延灼", "陈达", "张青", "刘唐", "李俊", "张顺", "高俅", "孙二娘", "戴宗", "朱仝", "方腊", "阮小二", "李瓶儿", "庞春梅", "白胜", "吕方", "董平", "穆春", "宋清", "柴进", "施恩", "李忠", "周通", "杜兴", "时迁", "曹正", "宋万", "杨志", "镇关西", "西门庆"];
// 创建姓名列表
arrs.forEach(function (item, index) {
// console.log(item,index);
var nameNode = document.createElement("div");
nameNode.innerText = item;
nameNode.className = "name";
get_id("box").appendChild(nameNode);
})
// 点名功能
var timer =null;
get_id("btn").onclick = function () {
if (this.innerText === "点名") {
// 开启定时器
timer = setInterval(function () {
// 清空所有颜色 排他
for (var i = 0; i < arrs.length; i++) {
get_id("box").children[i].style.background = "";
}
// 留下当前颜色
var random = parseInt(Math.random() * arrs.length);
get_id("box").children[random].style.background = "red";
}, 10);
this.innerText = "停止";
} else {
//清除计时器
clearInterval(timer);
this.innerText = "点名";
}
}