Webcourse/07-前端基本功:CSS和DOM练习/03-DOM操作练习:基础练习.md

716 lines
18 KiB
JavaScript
Raw Permalink Normal View History

2018-02-01 22:58:37 +08:00
## 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;
2018-12-09 17:23:30 +08:00
return false; //return false表示阻止继续执行下面的代码。
2018-02-01 22:58:37 +08:00
}
}
</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显然不能达到效果
2018-12-09 17:23:30 +08:00
4代码的最后一行`return false`表示阻止继续执行下面的代码
2018-02-01 22:58:37 +08:00
实现的效果如下
20180127_1630.gif
工程文件
- [2018-01-27-美女相册demo.rar](http://download.csdn.net/download/smyhvae/10227161)
### 举例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
## 表单元素的属性
表单元素的属性包括typevaluecheckedselecteddisabled等
### 举例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下面的全部变成truefalse同理。
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;都是truetopInp的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
```