JavaScript的组成
JavaScript由ECMAScript,和Web APIs(DOM和BOM)组成。
ECMAScript是语法标准。
DOM是文档对象模型,是一套操作页面元素的API。
BOM是浏览器对象模型,是操作浏览器功能的API,通过BOM可以操作浏览器窗口,比如:弹出框,控制浏览器跳转,获取分辨率等等。
学习网站MDN:developer.mozilla.org/zh-CN/docs/…
DOM的概念
文档对象模型(Dbcument0bjectMode巪简称DOM),是W3C组织推荐的处理可扩展标
记语言的标准编程接口。它是一种与平台和语言无关的应用程序接口(API),它可以动态地访问程序和脚本,更新其内容、结构和www文档的风格(目前,HTML和XML文档是通过说明部分定义的)。文档可以进一步被处理,处理的结果可以加入到当前的页面。DOM是一种基于树的API文档,它要求在处理过程中整个文档都表示在存储器中。
DOM又称为文档树模型,如下图。
- 文档:一个网页可以称为文档
- 节点:网页中的所有内容都是节点(标签、属性、文本、注释等)
- 元素:网页中的标签
- 属性:标签的属性
DOM 经常进行的操作:
- 获取元素
- 对元素进行操作(设置其属性或调用其方法)
- 动态创建元素
- 事件(什么时机做相应的操作)
DOM 获取页面元素
DOM有很多种获取页面元素的方法。下面一一介绍。
根据id获取元素
方法:调用document对象的getElementById方法。
返回的是元素对象。
- 注意1:由于id名具有唯一性,部分浏览器支持直接使用id名访问元素,但不是标准方式,不推荐使用。
- 注意2:代码执行顺序,如果js在html结构之前,会导致结构未加载,不能获取对应id的元素。
<p id="para">text0</p>
<p id="para">text1</p>
<p id="box">text2</p>
<p>text3</p>
<p>text4</p>
<script>
// 根据 id 获取元素
var para = document.getElementById("para");
// console.log(typeof para);
// 补充:在控制台打印具体的对象
// console.dir(para);
para.style.background = "pink";
// 代码书写顺序:js 中获取元素时,必须保证元素已经在浏览器中渲染成功
// 需要将 js 的代码写在 html 结构之后
// box.style.background = "blue"; 不推荐直接使用 id 名
</script>
根据标签名获取元素
方法:调用document对象的getElementsByTagName方法。
返回值:同名的元素对象组成的数组HTMLCollection。
- 注意1:操作数据时需要按照操作数组的方法进行。
- 注意2:getElementsByTagName方法内部获取的元素是动态增加的。
// 通过标签名获取元素
var ps = document.getElementsByTagName("p")
console.log(ps);
// HTMLCollection html 元素组成的集合 伪数
// 遍历数组
for (var i = 0 ; i <= ps.length - 1; i++) {
// 输出每一项
console.log(ps[i]);
}
ps[0].style.background = "pink";
在元素对象内部获取标签元素
获取的元素对象内部,本身也可以调用根据标签获取元素方法,例如div元素对象也可以调用getElementsByTagName方法。
目的:缩小选择元素的范围,类似css中的后代选择器。
var box1 = document.getElementById("box1");
// 我们习惯将连续调用方式拆开书写
var ps1 = box1.getElementsByTagName("p");
console.log(ps1);
根据name获取元素
方法:调用document对象的getElementsByName方法。
参数:字符串类型的name属性值。
返回值:name属性值相同的元素对象组成的数组。
不建议使用:在IE和0pera中有兼容问题,会多选中id属性值相同的元素。
// 通过标签的 name 属性获取元素
var ages = document.getElementsByName("age");
// NodeList 节点列表集合 类数组
// 获取的元素也是动态增加的
根据类名获取元素
方法:调用document对的getElementsByClassName方法。 参数:字符串类型的class属性值。 返回值:class属性值相同的元素对象组成的数组。 浏览器兼容问题:不支持IE8及以下的浏览器
// 获取 id 为 box1 的元素对象
var box1 = document.getElementById("box1");
// 元素对象内部也可以调用 getElementsByClassName 方法
var paras1 = box1.getElementsByClassName("para");
根据选择器获取元素
方法1:调用document对象的querySelector方法,通过css中的选择器去选取第一个符合条件的标签元素。
方法2:调用document对象的querySelectorAll方法,通过css中的选择器去选取所有符合条件的标签元素。
参数:字符串类型的css中的选择器。
浏览器兼容问题:不支持IE8以下的浏览器
// 在结构之后使用 选择器 选取方法
var para = document.querySelector("#box1 .para");
console.log(para);
var paras = document.querySelectorAll("#box1 .para");
console.log(paras);
总结
掌握,没有兼容问题
- getElementByid
- getElementsByTagName 了解
- getElementsByName
- getElementsByClassName
- querySelector
- querySelectorAll
事件
事件:在什么时候做什么事
执行机制:触发--响应机制
绑定事件(注册事件)三要素:
1、事件源:给谁绑定事件
2、事件类型:绑定什么类型的事件click单击
3、事件函数:事件发生后执行什么内容,写在函数内部
事件监听
JavaScript解析器会给有绑定事件的元素添加一个监听,解析器会一直监测这个元素,只要触发对应的绑定事件,会立刻执行事件函数。
常用的鼠标事件类型
- onclick 鼠标左键单击触发
- ondblclick 鼠标左键双击触发
- onmousedown 鼠标按键按下触发
- onmouseup 鼠标按键放开时触发
- onmousemove 鼠标在元素上移动触发
- onmouseover 鼠标移动到元素上触发
- onmouseout 鼠标移出元素边界触发
常用事件监听方法
- 方法1:绑定HTML元素属性。
// 获取元素
<input type="button" id="btn" value="点击有惊喜" onclick="alert('点我做什么?')">
- 方法2:绑定DOM对象属性。常用。
// 获取元素
var btn = document.getElementById("btn");
// 添加绑定事件
btn.onclick = function () {
// 定义的是事件被触发后要做的事情
alert("点我干嘛?");
};
<input type="button" id="btn" value="点击有惊喜" onclick="alert('点我做什么?')">
DOM元素属性操作
非表单元素的属性操作
- 例如:href、title、id、src等。
- 调用方式:元素对象打点调用属性名,例如obj.href
- 注意:部分的属性名跟关键字和保留字冲突,会更换写法。
class→className
for→htmlFor
rowspan→rowSpan
<a href="http://www.baidu.com" title="跳转到百度页面" id="link">跳转</a>
<img src="images/a.jpg" alt="美女" class="pic" id="pic">
<script>
// 获取元素
var link = document.getElementById("link");
var pic = document.getElementById("pic");
// 调用元素对象的属性,从而操作 HTML 中标签的属性
console.log(link.href);
console.log(link.title);
console.log(link.id);
console.log(pic.src);
console.log(pic.alt);
console.log(pic.className);
// 等号赋值,值必须是字符串类型的
pic.src = "images/b.jpg";
</script>
点击按钮切换图片案例
<input type="button" value="点击" id="btn"><br>
<img src="images/a.jpg" id="pic">
<script>
// 获取元素
var btn = document.getElementById("btn");
var pic = document.getElementById("pic");
// 通过一个变量作为判断条件,变量值为 1,认为加载的是 a 图片,
// 如果为 2 ,认为加载的是 b 图片
var num = 1;
// 给按钮添加点击事件
btn.onclick = function () {
// 给图片换 src 的属性值
// 通过 if 语句判断,如果是 a 图片,就换成 b 图片,反之换成 a 图片
if (num === 1) {
pic.src = "images/b.jpg";
// 数字要对应发生变化
num = 2;
} else {
pic.src = "images/a.jpg";
num = 1;
}
};
</script>
点击按钮显示或隐藏元素
先书写样式
<style>
* {
margin: 0;
padding: 0;
}
div {
width: 200px;
height: 200px;
background-color: pink;
}
.hide {
display: none;
}
.show {
display: block;
}
</style>
再在body中书写js事件。
<input type="button" value="点击隐藏" id="btn">
<div id="box"></div>
<script>
// 获取元素
var btn = document.getElementById("btn");
var box = document.getElementById("box");
// 点击按钮,让 div 显示或隐藏
// box.style.display = "none";//一般不用该方法
btn.onclick = function () {
// 元素 div 当前是显示的,需要让他隐藏
// 根据 按钮 的 value 值进行条件判断
if (btn.value === "点击隐藏") {
box.className = "hide";
btn.value = "点击显示";
} else {
box.className = "show";
btn.value = "点击隐藏";
}
};
</script>
事件函数内部的this
在事件函数内部 有一个 this ,指向事件源
区分一下不同函数内部 this 的指向
普通函数 -> window 对象
构造函数 -> 指向的是生成的实例对象
对象的方法 -> 指向的是对象本身
事件函数 -> 指向的是事件源
btn.onclick = function () {
if (this.value === "点击隐藏") {
box.className = "hide";
this.value = "点击显示";
} else {
box.className = "show";
this.value = "点击隐藏";
}
};
批量绑定事件
<div id="imagegallery">
<a href="images/1.jpg" title="美女A">
<img src="images/1-small.jpg" width="100px" alt="美女1" />
</a>
<a href="images/2.jpg" title="美女B">
<img src="images/2-small.jpg" width="100px" alt="美女2" />
</a>
<a href="images/3.jpg" title="美女C">
<img src="images/3-small.jpg" width="100px" alt="美女3" />
</a>
<a href="images/4.jpg" title="美女D">
<img src="images/4-small.jpg" width="100px" alt="美女4" />
</a>
</div>
<div style="clear:both"></div>
<img id="image" src="images/placeholder.png" alt="" width="450px" />
<p id="des">选择一个图片</p>
<script>
// 1.获取元素
var imagegallery = document.getElementById("imagegallery");
var links = imagegallery.getElementsByTagName("a");
var image = document.getElementById("image");
var des = document.getElementById("des");
// 2.遍历数组,添加点击事件
for (var i = 0 ; i <= links.length - 1 ; i++) {
links[i].onclick = function () {
// alert("aaa");
// 3.更改 image 内部的 src 属性值
// this 关键字指代的是触发事件的真正事件源
image.src = this.href;
// 4.更改 des 内部的文字内容
des.innerText = this.title;
// 5.取消 a 标签的默认跳转效果
return false;
};
}
// for 循环内部添加的绑定事件,在触发时,所有的批量添加的事件已经成功,触发事件时都是在循环结
// 批量绑定的事件的事件函数内部如果有 变量 i,要注意,函数执行时已经是在循环结束后
// 循环内部定义的变量是一个全局变量,在循环后执行的 i 变量的值是 i 跳出循环时的值
// image.src = links[i].href;
// console.log(i);
</script>
获取标签内部内容的属性
获取标签内部内容的属性有两个:innerHTML和innerText。
- innerHTML属性,在获取标签内部内容时,如果包含标签,获取的内容会包含标签,获取的内容包括空白换行等。
- innerText属性,在获取标签内部内容时,如果包含标签,获取的内容会去掉标签,获取的内容会用单个空格代替换行和缩进等空白。
还可以通过两个属性给双标签内部去更改内容: - innerHTML设置属性值,有标签的字符串,会按照HTML语法中的标签加载。
- innerText设置属性值,有标签的字符串,会按照普通的字符加载。 对比使用场景:
- innerText:在设置纯字符串时使用。
- innerHTML:在设置有内部子标签结构时使用
<div id="box">
这是一个 div 标签
<span>这是一个 span 标签</span>
</div>
<script>
// 获取元素
var box = document.getElementById("box");
// 打印 box 对象
console.dir(box);
// 调用标签内部内容
console.log(box.innerHTML);
console.log(box.innerText);
// 设置标签内部的内容
// box.innerHTML = "<h2>hello JS</h2>";
// box.innerText = "<h2>hello JS</h2>";
</script>
点开打印出的box结果如下:
表单元素属性操作
表单元素属性:
- value用于大部分表单元素的内容获取(option除外)
- type可以获取input标签的类型(输入框或复选框等)
- disabled禁用属性
- checked复选框选中属性
- selected下拉菜单选中属性 注意:在DOM中元素对象的属性值只有一个时,会被转成布尔值显示。 例如:txt.disabled=true。
<input type="button" value="按钮" id="btn"><br>
<input type="text" id="txt">
<select id="list">
<option value="beijing">北京</option>
<option value="shanghai">上海</option>
</select>
<script>
// 获取元素
var btn = document.getElementById("btn");
var txt = document.getElementById("txt");
var list = document.getElementById("list");
var opts = list.getElementsByTagName("option");
// value 属性
console.log(btn.value);
console.log(txt.value);
console.log(opts[0].value);
console.log(opts[0].innerHTML);
// 更改 input 标签的 value
btn.value = "点击";
txt.value = "请输入内容"
// 表单元素特有的一些属性,属性名和属性值是一致的
// console.log(txt.disabled);
btn.disabled = true;
</script>
验证表单输入
<input type="text" id="name"><br>
<input type="text" id="pw"><br>
<input type="button" id="btn" value="提交">
<script>
// 检测用户名是否是3-6位,密码是否是6-8位,如果不满足要求高亮显示文本框
// 1.获取元素
var btn = document.getElementById("btn");
// 2.给按钮添加点击事件,然后判断位数是否足够
btn.onclick = function () {
// 在事件触发后,去获取对象,内部的数据才是最新
var userName = document.getElementById("name");
var pw = document.getElementById("pw");
// 用户名位数是否在 3-6 位,不满足需要高亮显示
if (userName.value.length < 3 || userName.value.length > 6) {
userName.className = "bg";
return;
} else {
userName.className = "";
}
// 密码的位数必须在 6-8 位之间,否则高亮显示
if (pw.value.length < 6 || pw.value.length > 8) {
pw.className = "bg";
return;
} else {
pw.className = "";
}
// 提交数据
console.log("提交数据");
};
</script>
随机设置下拉菜单选中项
<input type="button" value="选择" id="btn">
<br>
<select id="food">
<option>烤肉</option>
<option>拉面</option>
<option>麻辣烫</option>
<option>小龙虾</option>
<option>火锅</option>
<option>外卖</option>
</select>
<script>
// 1.获取元素
var btn = document.getElementById("btn");
var food = document.getElementById("food");
var opts = food.getElementsByTagName("option");
// 2.给按钮添加点击事件
btn.onclick = function () {
// 3.随机选择一个 option
// 每次点击需要获取一个 opts 数组的随机下标
// Math.random() [0,1)
// Math.random()*6 [0,6)
var n = Math.floor(Math.random() * opts.length);
// console.log(n);
// 设置对应的随机项的属性
opts[n].selected = true;
};
</script>
搜索文本框案例
设置样式
<style>
.gray {
color: gray;
}
.black {
color: black;
}
</style>
绑定事件
<input type="text" class="gray" value="请输入搜索关键字" id="txtSearch">
<input type="button" value="搜索" id="btnSearch">
<script>
// 获取元素
var txtSearch = document.getElementById("txtSearch");
// 1.获得焦点时,可以使用一个 onfocus,如果文本框内容是默认 请输入搜索关键字,
// 需要清空文字,让文字加载黑色
txtSearch.onfocus = function () {
// 判断是否是默认的提示文字
if (this.value === "请输入搜索关键字") {
this.value = "";
this.className = "black";
}
};
// 2.失去焦点时,可以使用一个 onblur,如果文本框内容为空,
// 需要改为默认提示内容 请输入搜索关键字,让文字颜色变为灰色
txtSearch.onblur = function () {
// 如果用户输入的内容正好与默认提示文本相同,失去焦点时,也应该让文字颜色变为灰色
// 判断内容是否为空
if (this.value === "" || this.value === "请输入搜索关键字") {
this.value = "请输入搜索关键字";
this.className = "gray";
}
};
</script>
全选和反选
自定义属性操作
因为自定义属性,类型大小都未知,所以无法提前封装进元素对象,也就无法像操作自有属性一样使用“元素对象.属性名”来操作。
- getAttribute(name)获取标签行内属性
- setAttribute(name, value)设置标签行内属性
- removeAttr(name)移除标签行内属性
- 与element.属性的区别:上述三个方法用于获取任意的行内属性,包括自定义的属性。
<div id="box" age="18" sex="male">小明</div>
<script>
// 获取元素
var box = document.getElementById("box");
// 元素自有属性
console.log(box.id);
// 元素自定义的新属性不能用点语法直接调用
// 可以调用元素对象的获取自定义属性的方法
console.log(box.getAttribute("age"));
console.log(box.getAttribute("sex"));
// 也可以调用自有的属性
console.log(box.getAttribute("id"));
// 设置属性,添加新的自定义属性或者自有属性
box.setAttribute("age","20");
box.setAttribute("city","Beijing");
// 传的参数不需要进行属性名的修改
box.setAttribute("class","demo");
// 移除属性
box.removeAttribute("age");
box.removeAttribute("class");
</script>
style样式属性基本操作
- 使用style属性方式设置的样式显示在标签行内。
- element.style属性的值,是所有行内样式组成的一个样式对象。
- 样式对象可以继续点语法调用或更改css的行内样式属性,例如width、height等属性。
- 注意1:类似background-color这种复合属性的单一属性写法,是由多个单词组成的,要修改为驼峰命名方式书写backgroundColor。
- 注意2:通过样式属性设置宽高、位置的属性类型是字符串,需要加上px等单位。
PS: 每次写获取元素对象的命令太长,为了简化书写可以做如下操作。
- 将获取对象函数再封装成函数my$(id),放入common.js文件,将来方便调用。下面是common.js中的内容。
// 定义一个获取元素的函数
function my$(id) {
return document.getElementById(id);
}
- 在html文件中引用common.js,并调用my$(id),最后更改样式
<style>
.bg{
background-color: pink;
}
</style>
<script src="common.js"></script>
调用并更改样式
// 获取元素
var btn = my$("btn");
var box = my$("box");
// console.log(btn);
// 1.更改类名的方式去更改样式
// 2.根据对象的 style 属性去操作样式
console.log(btn.style);
// 元素对象的 style 属性的值是一个行内样式组成对象,
// 对象内部封装了所有的行内的样式属性及属性值
// 元素的样式属性对象可以继续打点调用,获取或设置相关的行内样式属性
console.log(box.style);
console.log(box.style.width);
// 注意:如果使用的 css 属性名是复合属性的单一属性,需要更改为驼峰命名法
console.log(box.style.backgroundColor);
box.style.width = "200px";
className 类名属性操作
修改元素的className属性相当于直接修改标签的类名。
如果需要修改多条css样式,可以提前将修改后的样式设置到一个类选择器中,后续通过修改类名的方式,批量修改css样式。
设置样式类:
.cls {
width: 100px;
height: 100px;
background-color: pink;
}
修改样式:
<input type="button" value="按钮" id="btn">
<div id="box">文字</div>
<script>
// 问题:实际工作中我们应该选择哪种方法?
// 获取元素
var btn = my$("btn");
var box = my$("box");
// 给按钮添加事件
btn.onclick = function () {
// 1.通过更改类名
// box.className = "cls";
// 2.通过元素对象的 style 属性进行设置
box.style.width = "100px";
box.style.height = "200px";
box.style.backgroundColor = "yellow";
};
</script>
开关灯案例
<input type="button" value="关灯" id="btn">
<script src="common.js"></script>
<script>
// 获取元素
var btn = my$("btn");
// console.log(btn);
// 定义一个判断变量,true 表示开灯状态,false 表示关灯状态
// var isOpen = true;
// 点击事件,控制 body 的背景
btn.onclick = function () {
// 开灯时,需要点击后让它关灯并切换文字为 开灯
// 直接使用 btn 的 value 值进行判断
if (this.value === "关灯") {
document.body.style.backgroundColor = "black";
this.value = "开灯";
} else {
document.body.style.backgroundColor = "white";
this.value = "关灯";
}
};
</script>
显示二维码案例
设置样式
<style>
.box {
width: 50px;
height: 50px;
background: url(images/bgs.png) no-repeat -159px -51px;
position: fixed;
right: 10px;
top: 40%;
}
.erweima {
position: absolute;
top: 0;
left: -150px;
}
.box a {
display: block;
width: 50px;
height: 50px;
}
.hide {
display: none;
}
.show {
display: block;
}
</style>
设置html骨架,并绑定修改样式事件
<div class="box" id="box">
<div class="erweima hide" id="er">
<img src="images/456.png" alt=""/>
</div>
</div>
<script src="common.js"></script>
<script>
// 获取元素
var box = my$("box");
var er = my$("er");
// 给 box 添加鼠标移上事件 onmouseover ,添加鼠标离开事件 onmouseout
box.onmouseover = function () {
// 让子级元素进行显示,就是将 hide 改为 show
// er.className = "erweima show";
er.className = er.className.replace("hide","show");
};
box.onmouseout = function () {
// 让子级元素进行隐藏,就是将 show 改为 hide
// er.className = "erweima hide";
er.className = er.className.replace("show","hide");
};
</script>
排他思想-文本框高亮显示案例
文本框高亮方便用户辨识输入。
<input type="text"><br>
<input type="text"><br>
<input type="text"><br>
<input type="text"><br>
<input type="text"><br>
<input type="text"><br>
<input type="text"><br>
<button id="btn">按钮</button>
<script>
// 获取元素
var txts = document.getElementsByTagName("input");
// 添加批量的获取焦点事件
for (var i = 0 ; i < txts.length ; i++) {
// 排他思想:1.排除其他 2.保留自己
// 给每一个input标签添加获取焦点事件
txts[i].onfocus = function () {
// 排除其他的方法:将所有的项包含自己都设置为默认样式
// 遍历数组,让所有的样式恢复默认
for (var j = 0 ; j < txts.length ; j++) {
txts[j].style.backgroundColor = "";
}
// 设置元素自己高亮显示
// 保留自己的特殊样式
// this 指代事件源自己
this.style.backgroundColor = "yellow";
};
}
</script>