mirror of
https://github.com/qianguyihao/Web.git
synced 2024-11-01 13:34:46 +08:00
722 lines
18 KiB
Markdown
722 lines
18 KiB
Markdown
---
|
||
title: 03-DOM操作练习:基础练习
|
||
publish: true
|
||
---
|
||
|
||
<ArticleTopAd></ArticleTopAd>
|
||
|
||
|
||
|
||
## DOM操作练习
|
||
|
||
### 举例1:点击按钮时,显示和隐藏盒子。
|
||
|
||
代码实现:
|
||
|
||
```html
|
||
<!DOCTYPE html>
|
||
<html>
|
||
<head lang="en">
|
||
<meta charset="UTF-8">
|
||
<title></title>
|
||
<style>
|
||
button {
|
||
margin: 10px;
|
||
}
|
||
|
||
div {
|
||
width: 200px;
|
||
height: 200px;
|
||
background-color: pink;
|
||
}
|
||
|
||
.show {
|
||
display: block;
|
||
}
|
||
|
||
.hide {
|
||
display: none;
|
||
}
|
||
</style>
|
||
|
||
</head>
|
||
<body>
|
||
<button id="btn">隐藏</button>
|
||
<div>
|
||
千古壹号
|
||
</div>
|
||
|
||
<script>
|
||
//需求:点击button,隐藏盒子。改变文字,在点击按钮,显示出来。
|
||
//步骤:
|
||
//1.获取事件源和相关元素
|
||
//2.绑定事件
|
||
//3.书写事件驱动程序
|
||
|
||
//1.获取事件源和相关元素
|
||
var btn = document.getElementById("btn");
|
||
var div1 = document.getElementsByTagName("div")[0];
|
||
//2.绑定事件
|
||
btn.onclick = function () {
|
||
//3.书写事件驱动程序
|
||
//判断btn的innerHTML属性值,如果为隐藏就隐藏盒子,并修改按钮内容为显示。
|
||
//反之,则显示,并修改按钮内容为隐藏
|
||
if (this.innerHTML === "隐藏") {
|
||
div1.className = "hide";
|
||
//修改按钮上的文字(innerHTML)
|
||
btn.innerHTML = "显示";
|
||
} else {
|
||
div1.className = "show";
|
||
//修改按钮上的文字(innerHTML)
|
||
btn.innerHTML = "隐藏";
|
||
}
|
||
}
|
||
|
||
</script>
|
||
|
||
</body>
|
||
</html>
|
||
|
||
```
|
||
|
||
代码解释:
|
||
|
||
当盒子是显示状态时,就设置为隐藏;当盒子是隐藏状态时,就设置为显示。注意这里的逻辑判断。
|
||
|
||
另外,这里用到了`innerHTHL`属性,它可以修改按钮上显示的文字。
|
||
|
||
代码最终显示的效果如下:
|
||
|
||
20180127_1518.gif
|
||
|
||
### 举例2:美女相册
|
||
|
||
这里推荐一个网站:
|
||
|
||
- 占位图片生成的在线网站:<https://placeholder.com/>
|
||
|
||
好处是:素材做出来之前,先留出空位,方便以后换图。比如<http://via.placeholder.com/400x300>这个链接可以生成400*300的占位图片。
|
||
|
||
需求:
|
||
|
||
- (1)点击小图片,改变下面的大图片的src属性值,让其赋值为a链接中的href属性值。
|
||
- (2)让p标签的innnerHTML属性值,变成a标签的title属性值。
|
||
|
||
|
||
为了实现美女相册,代码如下:
|
||
|
||
```html
|
||
<!DOCTYPE html>
|
||
<html>
|
||
<head lang="en">
|
||
<meta charset="UTF-8">
|
||
<title></title>
|
||
<style type="text/css">
|
||
body {
|
||
font-family: "Helvetica", "Arial", serif;
|
||
color: #333;
|
||
margin: 1em 10%;
|
||
}
|
||
|
||
h1 {
|
||
color: #333;
|
||
background-color: transparent;
|
||
}
|
||
|
||
a {
|
||
color: #c60;
|
||
background-color: transparent;
|
||
font-weight: bold;
|
||
text-decoration: none;
|
||
}
|
||
|
||
ul {
|
||
padding: 0;
|
||
}
|
||
|
||
li {
|
||
float: left;
|
||
padding: 1em;
|
||
list-style: none;
|
||
}
|
||
|
||
#imagegallery {
|
||
|
||
list-style: none;
|
||
}
|
||
|
||
#imagegallery li {
|
||
margin: 0px 20px 20px 0px;
|
||
padding: 0px;
|
||
display: inline;
|
||
}
|
||
|
||
#imagegallery li a img {
|
||
border: 0;
|
||
}
|
||
</style>
|
||
|
||
</head>
|
||
<body>
|
||
<h2>
|
||
美女画廊
|
||
</h2>
|
||
<a href="#">注册</a>
|
||
<ul id="imagegallery">
|
||
<li>
|
||
<a href="image/1.jpg" title="美女A">
|
||
<img src="image/1-small.jpg" width="100" alt="美女1"/>
|
||
</a>
|
||
</li>
|
||
<li>
|
||
<a href="image/2.jpg" title="美女B">
|
||
<img src="image/2-small.jpg" width="100" alt="美女2"/>
|
||
</a>
|
||
</li>
|
||
<li>
|
||
<a href="image/3.jpg" title="美女C">
|
||
<img src="image/3-small.jpg" width="100" alt="美女3"/>
|
||
</a>
|
||
</li>
|
||
<li>
|
||
<a href="image/4.jpg" title="美女D">
|
||
<img src="image/4-small.jpg" width="100" alt="美女4"/>
|
||
</a>
|
||
</li>
|
||
</ul>
|
||
|
||
|
||
<div style="clear:both"></div>
|
||
|
||
<img id="image" src="image/placeholder.png" width="450px"/>
|
||
|
||
<p id="des">选择一个图片</p>
|
||
|
||
<script>
|
||
//需求:
|
||
//(1)点击小图片,改变下面的大图片的src属性值,让其赋值为a链接中的href属性值。
|
||
//(2)让p标签的innnerHTML属性值,变成a标签的title属性值。
|
||
|
||
//1.获取事件源和相关元素
|
||
//利用元素获取其下面的标签。
|
||
var ul = document.getElementById("imagegallery");
|
||
var aArr = ul.getElementsByTagName("a"); //获取ul中的超链接<a>
|
||
|
||
// console.log(aArr[0]);
|
||
var img = document.getElementById("image");
|
||
var des = document.getElementById("des");
|
||
//2.绑定事件
|
||
//以前是一个一个绑定,但是现在是一个数组。我们用for循环绑定
|
||
for (var i = 0; i < aArr.length; i++) {
|
||
aArr[i].onclick = function () {
|
||
//3.【核心代码】书写事件驱动程序:修改属性值
|
||
img.src = this.href; //this指的是函数调用者,和i并无关系,所以不会出错。
|
||
// img.src = aArr[i].href; 注意,上面这一行代码不要写成这样
|
||
des.innerHTML = this.title;
|
||
return false; //return false表示:阻止继续执行下面的代码。
|
||
}
|
||
}
|
||
|
||
</script>
|
||
</body>
|
||
</html>
|
||
```
|
||
|
||
代码解释:
|
||
|
||
(1)获取事件源:我们通过`ul.getElementsByTagName("a")`来获取ul里面的a元素。
|
||
|
||
(2)绑定事件:因为要绑定一个数组,所以这里用for循环来绑定
|
||
|
||
(3)【重要】书写事件驱动程序:这里是用`img.src = this.href`,而不是用`img.src = aArr[i].href`。因为this指的是函数的调用者。如果写成后者,等i变成了4,就会一直是4。显然不能达到效果。
|
||
|
||
(4)代码的最后一行:`return false`表示:阻止继续执行下面的代码。
|
||
|
||
实现的效果如下:
|
||
|
||
20180127_1630.gif
|
||
|
||
工程文件:[2018-01-27-美女相册demo.rar](https://github.com/qianguyihao/web-resource/blob/main/project/2018-01-27-%E7%BE%8E%E5%A5%B3%E7%9B%B8%E5%86%8Cdemo.rar)
|
||
|
||
### 举例3:鼠标悬停时,显示二维码大图
|
||
|
||
```html
|
||
<!DOCTYPE html>
|
||
<html>
|
||
<head lang="en">
|
||
<meta charset="UTF-8">
|
||
<title></title>
|
||
<style>
|
||
.code {
|
||
width: 50px;
|
||
height: 50px;
|
||
}
|
||
|
||
.code a {
|
||
display: block;
|
||
width: 50px;
|
||
height: 50px;
|
||
background: url(http://img.smyhvae.com/20180127_QRcode_small.png) no-repeat -159px -51px;
|
||
position: relative;
|
||
|
||
}
|
||
|
||
.code-big {
|
||
position: absolute;
|
||
top: 10px;
|
||
left: 80px;
|
||
}
|
||
|
||
.hide {
|
||
display: none;
|
||
}
|
||
|
||
.show {
|
||
display: block;
|
||
}
|
||
|
||
|
||
</style>
|
||
|
||
<script>
|
||
window.onload = function () {
|
||
//需求:鼠标放到a链接上,显示二维码(添加show类名,去掉hide类名)
|
||
// 鼠标移开a链接,隐藏二维码(添加hide类名,去掉show类名)
|
||
|
||
|
||
//1.获取事件源和相关元素
|
||
var a = document.getElementsByTagName("a")[0];
|
||
var div = document.getElementsByClassName("code-big")[0];
|
||
//2.绑定事件
|
||
a.onmouseover = fn1; //鼠标悬停时
|
||
a.onmouseout = fn2; //鼠标离开时
|
||
|
||
//定义方法
|
||
function fn1() {
|
||
//3.书写事件驱动程序
|
||
div.className = "code-big show";
|
||
//div.className = div.className.replace("hide", "show");
|
||
|
||
}
|
||
|
||
function fn2() {
|
||
div.className = "code-big hide";
|
||
//了解,字符串操作,把字符串中的hide替换成show。
|
||
// div.className = div.className.replace("show","hide");
|
||
}
|
||
}
|
||
</script>
|
||
</head>
|
||
<body>
|
||
|
||
<div class="code">
|
||
<a href="#"></a>
|
||
<img src="http://img.smyhvae.com/2016040102.jpg" alt="" class="code-big hide"/>
|
||
</div>
|
||
|
||
</body>
|
||
</html>
|
||
|
||
```
|
||
|
||
|
||
实现效果:
|
||
|
||
20180127_1800.gif
|
||
|
||
|
||
## 表单元素的属性
|
||
|
||
表单元素的属性包括:type、value、checked、selected、disabled等。
|
||
|
||
|
||
### 举例1:禁用文本框/解禁文本框
|
||
|
||
|
||
```html
|
||
<body>
|
||
|
||
账号: <input type="text" value="千古壹号..."/><button>禁用</button><button>解禁</button><br><br>
|
||
密码: <input type="password" value="aaabbbccc"/>
|
||
|
||
<script>
|
||
|
||
var inp = document.getElementsByTagName("input")[0];
|
||
var btn1 = document.getElementsByTagName("button")[0];
|
||
var btn2 = document.getElementsByTagName("button")[1];
|
||
|
||
btn1.onclick = function () {
|
||
inp.disabled = "no"; //禁用文本框。属性值里随便写什么字符串都行,但不能为空。
|
||
}
|
||
btn2.onclick = function () {
|
||
inp.disabled = false; //解禁文本框。让disabled属性消失即可。
|
||
// inp.removeAttribute("disabled");
|
||
}
|
||
</script>
|
||
</body>
|
||
|
||
```
|
||
|
||
当文本框被禁用之后,文本框只读,不能编辑,光标点不进去。
|
||
|
||
|
||
上方代码可以看到,**禁用文本框**的代码是:
|
||
|
||
```javascript
|
||
inp.disabled = "no"; //让disabled属性出现,即可禁用
|
||
```
|
||
|
||
我们的目的时让`disabled`这个属性出现,即可禁用。所以,属性值里可以写数字,可以写任意一个字符串,但不能写0,不能写false,不能为空。一般我们写no。
|
||
|
||
|
||
|
||
**解禁文本框**的代码是:
|
||
|
||
|
||
```javascript
|
||
inp.disabled = false; // 方法1:让disabled属性消失,即可解禁。
|
||
inp.removeAttribute("disabled"); //方法2:推荐
|
||
|
||
```
|
||
|
||
|
||
我们的目的是删除`disabled`属性,即可解禁。属性值可以是false,可以是0。但我们一般采用方式2进行解禁。
|
||
|
||
实现效果:
|
||
|
||
|
||
|
||
|
||
|
||
### 举例2:文本框获取焦点/失去焦点
|
||
|
||
细心的读者会发现,京东和淘宝的搜索框,获取焦点时,提示文字的体验是不同的。
|
||
|
||
京东:
|
||
|
||
20180127_2000.gif
|
||
|
||
淘宝:
|
||
|
||
20180127_2005.gif
|
||
|
||
其实,**淘宝的提示文字,是用一个绝对定位的单独的标签来做的**。
|
||
|
||
京东是判断输入框是否获取焦点;淘宝是判断输入框内是否有用户输入的文字。
|
||
|
||
|
||
我们现在来实现一下。代码如下:
|
||
|
||
```html
|
||
<!DOCTYPE html>
|
||
<html>
|
||
<head lang="en">
|
||
<meta charset="UTF-8">
|
||
<title></title>
|
||
<style>
|
||
input {
|
||
width: 300px;
|
||
height: 36px;
|
||
padding-left: 5px;
|
||
color: #ccc;
|
||
}
|
||
|
||
label {
|
||
position: absolute;
|
||
top: 82px;
|
||
left: 56px;
|
||
font-size: 12px;
|
||
color: #ccc;
|
||
cursor: text;
|
||
}
|
||
|
||
.hide {
|
||
display: none;
|
||
}
|
||
|
||
.show {
|
||
display: block;
|
||
}
|
||
</style>
|
||
</head>
|
||
<body>
|
||
京东: <input id="inp1" type="text" value="微单相机"/><br><br>
|
||
淘宝: <label for="inp2">电动牙刷</label><input id="inp2" type="text"/><br><br>
|
||
placeholder: <input type="text" placeholder="我是placeholder"/>
|
||
|
||
<script>
|
||
//需求:京东的input按钮获取焦点后,立刻删除内容。失去后光标显示文字。
|
||
|
||
var inp1 = document.getElementById("inp1");
|
||
|
||
inp1.onfocus = function () {
|
||
//判断,如果input里面的内容是“微单相机”,那么把值赋值为“”;
|
||
if (this.value === "微单相机") {
|
||
inp1.value = "";
|
||
inp1.style.color = "#000";
|
||
|
||
}
|
||
}
|
||
//失去焦点事件
|
||
inp1.onblur = function () {
|
||
//判断:如果input内容为空,那么把内容赋值为微单相机。
|
||
if (this.value === "") {
|
||
inp1.value = "微单相机";
|
||
inp1.style.color = "#ccc";
|
||
|
||
}
|
||
}
|
||
|
||
|
||
//需求:在input中输入文字,label标签隐藏;当里面的文字变成空字符串,label显示。
|
||
|
||
var inp2 = document.getElementById("inp2");
|
||
var lab = document.getElementsByTagName("label")[0];
|
||
|
||
//2.绑定事件(输入文字、和删除文字时,都会触动这个事件)
|
||
inp2.oninput = function () {
|
||
//判断input中的值是否为空,如果为空,那么label显示,否则隐藏。
|
||
if (this.value === "") {
|
||
lab.className = "show";
|
||
} else {
|
||
lab.className = "hide";
|
||
}
|
||
}
|
||
</script>
|
||
</body>
|
||
</html>
|
||
```
|
||
|
||
|
||
实现效果如下:
|
||
|
||
20180127_2010.gif
|
||
|
||
如上方所示,我们还可以用placeholder来做,但是IE678并不支持,所以不建议使用。
|
||
|
||
|
||
### 举例3:用户注册信息错误时,输入框失去焦点后,高亮显示。
|
||
|
||
代码实现:
|
||
|
||
|
||
|
||
```html
|
||
<!DOCTYPE html>
|
||
<html>
|
||
<head lang="en">
|
||
<meta charset="UTF-8">
|
||
<title></title>
|
||
<style>
|
||
.wrong {
|
||
border: 2px solid red;
|
||
}
|
||
.right {
|
||
border: 2px solid #91B81D;
|
||
}
|
||
</style>
|
||
</head>
|
||
<body>
|
||
|
||
账号:<input type="text" onblur="fn(this)"/><br><br>
|
||
密码:<input type="password" onblur="fn(this)"/>
|
||
|
||
<script>
|
||
//需求:失去焦点的时候判断input按钮中的值,如果账号或密码在6-12个字符之间通过,否则报错。
|
||
|
||
function fn(aaa){
|
||
//html中的input标签行内调用function的时候,是先通过window调用的function,所以打印this等于打印window
|
||
// console.log(this)
|
||
//只有传递的this才指的是标签本身。
|
||
// console.log(aaa)
|
||
// console.log(this.value)
|
||
if(aaa.value.length < 6 || aaa.value.length>12){
|
||
aaa.className = "wrong";
|
||
}else{
|
||
aaa.className = "right";
|
||
}
|
||
}
|
||
</script>
|
||
</body>
|
||
</html>
|
||
```
|
||
|
||
代码解释:这次我们是在标签内调用function的,此时是先通过window调用的function。所以行内调用的时候要带this。
|
||
|
||
|
||
实现效果:
|
||
|
||
20180127_2035.gif
|
||
|
||
|
||
### 举例4:全选和反选
|
||
|
||
|
||
对应的代码如下:
|
||
|
||
|
||
```html
|
||
<!DOCTYPE html>
|
||
<html>
|
||
<head lang="en">
|
||
<meta charset="UTF-8">
|
||
<title></title>
|
||
<style>
|
||
* {
|
||
padding: 0;
|
||
margin: 0;
|
||
}
|
||
|
||
.my-table {
|
||
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 "微软雅黑";
|
||
}
|
||
|
||
tbody tr {
|
||
background-color: #f0f0f0;
|
||
}
|
||
|
||
tbody tr:hover {
|
||
cursor: pointer;
|
||
background-color: #fafafa;
|
||
}
|
||
</style>
|
||
|
||
<script>
|
||
|
||
window.onload = function () {
|
||
//需求1:点击上面的的input,下面全选或者反选。
|
||
//思路:获取了上面的input按钮,只需要判断,checked属性是true还是false,如果是true,下面的全部变成true;false同理。
|
||
|
||
var topInp = document.getElementById("title");
|
||
|
||
var tbody = document.getElementById("content");
|
||
var botInpArr = tbody.getElementsByTagName("input");
|
||
|
||
//绑定事件
|
||
topInp.onclick = function () {
|
||
//费劲版
|
||
// for(var i=0;i<botInpArr.length;i++){
|
||
// if(topInp.checked === true){
|
||
// botInpArr[i].checked = true;
|
||
// }else{
|
||
// botInpArr[i].checked = false;
|
||
// }
|
||
// }
|
||
|
||
//优化版(被点击的input按钮的checked属性值,应该直接作为下面的所有的input按钮的checked属性值)
|
||
for(var i=0;i<botInpArr.length;i++){
|
||
botInpArr[i].checked = this.checked;
|
||
}
|
||
}
|
||
|
||
//需求2:点击下面的的input,如果下面的全部选定了,上面的全选,否则相反。
|
||
//思路:为下面的每一个input绑定事件,每点击一次都判断所有的按钮
|
||
// checked属性值是否全部都是true,如果有一个是false,
|
||
// 那么上面的input的checked属性也是false;都是true,topInp的checked就是true;
|
||
|
||
|
||
for(var i=0;i<botInpArr.length;i++){
|
||
botInpArr[i].onclick = function () { //每一个input都要绑定事件
|
||
//开闭原则(用开关来控制)
|
||
var bool = true;
|
||
//检测每一个input的checked属性值。
|
||
for(var j=0;j<botInpArr.length;j++){
|
||
if(botInpArr[j].checked === false){
|
||
bool = false;
|
||
}
|
||
}
|
||
topInp.checked = bool;
|
||
}
|
||
}
|
||
}
|
||
|
||
</script>
|
||
|
||
</head>
|
||
<body>
|
||
<div class="my-table">
|
||
<table>
|
||
<thead>
|
||
<tr>
|
||
<th>
|
||
<input type="checkbox" id="title" />
|
||
</th>
|
||
<th>菜名</th>
|
||
<th>饭店</th>
|
||
</tr>
|
||
</thead>
|
||
<tbody id="content">
|
||
<tr>
|
||
<td>
|
||
<input type="checkbox" />
|
||
</td>
|
||
<td>菜品1</td>
|
||
<td>木屋烧烤</td>
|
||
</tr>
|
||
<tr>
|
||
<td>
|
||
<input type="checkbox" />
|
||
</td>
|
||
<td>菜品2</td>
|
||
<td>蒸菜馆</td>
|
||
</tr>
|
||
<tr>
|
||
<td>
|
||
<input type="checkbox" />
|
||
</td>
|
||
<td>菜品3</td>
|
||
<td>海底捞火锅</td>
|
||
</tr>
|
||
<tr>
|
||
<td>
|
||
<input type="checkbox" />
|
||
</td>
|
||
<td>菜品4</td>
|
||
<td>面点王</td>
|
||
</tr>
|
||
</tbody>
|
||
</table>
|
||
</div>
|
||
|
||
</body>
|
||
</html>
|
||
```
|
||
|
||
注意代码中的注释,需求2是比较难的地方,这里用到了两次for循环。第一次for循环是因为,要给每个input都要进行绑定事件。
|
||
|
||
实现的效果如下:
|
||
|
||
20180127_2320.gif
|
||
|
||
|
||
|
||
|
||
```javascript
|
||
|
||
```
|