JavaScript学习笔记(三)Js正则、DOM
学习目标
DOM
正则表达式
一、DOM
1、概述
DOM对象:Document Object Model 文档对象模型、作用、通过DOM对象可以访问和操作html文件的每个标签、
html文档加载到浏览器的内存中后、我们认为形成了一颗DOM树、而任何一个html签、标签属性和文本都是这个树上的节点元素。
我们可以通过js的DOM组件中的方法对内存中的DOM树上的结构和内容进行修改,即通过js动态修改内存中的那一份html及css的代码。
当浏览器把一个html文件加载到内存中之后,这个html文件,就是一个Document对象。可以使用js技术结合Document对象,对html文件中的所有标签,进行各种操作。
在浏览器把html文件加载完成之后,标签被称作标签对象(元素节点),标签中的文件称为文本节点(文本对象),标签的属性称为属性节点(属性对象)。
1、获取id
document.getElementById("ID名"); 返回指定的id对象
<input type="submit" value="点击" id="btn" />
<script>
window.onload = function () {
// id 编号
var btn = document.getElementById("btn");
btn.onclick = function () {
alert("获取成功!");
}
}
</script>
2、获取name值
document.getElementsByName("name名"); 返回指定name值的对象集合
<input type="text" name="tname" value="王者荣耀_1" /> <br />
<input type="text" name="tname" value="王者荣耀_2" /> <br />
<input type="text" name="tname" value="王者荣耀_3" /> <br />
<input type="button" name="ok" value="保存" />
<script>
window.onload = function () {
// name = tname 的标签
var inputs = document.getElementsByName("tname");
alert("inputs.length = " + inputs.length);
// 遍历
for (var i = 0; i < inputs.length; i++) {
// 取出每一个
alert(i + " = " + inputs[i].value);
// 给 input 每一个标签绑定一个 onchange 事件.
inputs[i].onchange = function () {
// 内容发生更改, 需要查询 `当前元素 this` 更改后的内容
alert(this.value);
}
}
}
</script>
2.1、获取类名:
document.getElementsByClassName("class名"); 返回指定class名的对象集合
<input type="text" name="tname" value="王者荣耀_1" class = "test"/> <br />
<input type="text" name="tname" value="王者荣耀_2" class="test" /> <br />
<input type="text" name="tname" value="王者荣耀_3" /> <br />
<input type="button" name="ok" value="保存" />
<script>
window.onload = function () {
// class = test 的标签
var inputs = document.getElementsByClassName("test");
alert("inputs.length = " + inputs.length);
}
</script>
2.2、获取标签名:
document.getElementsByTagName("标签名"); 返回指定标签名的对象集合
<select name="edu" id="edu">
<option value="博士">博士</option>
<option value="硕士">硕士</option>
<option value="本科">本科</option>
<option value="幼儿园">幼儿园</option>
</select>
<script>
window.onload = function () {
// tagName 标签名称
var options = document.getElementsByTagName("option");
alert(options.length);
for (var i = 0; i < options.length; i++) {
alert(i + " = " + options[i].value);
}
}
</script>
2.3、获取标签内容:
element.innerHTML; 获取标签内部的所有内容
element.innerText; 获取标签内部的文本内容
<body>
<div id="box">
来不来。
<h1>一起吃饭去!</h1>
</div>
</body>
<script>
window.onload = function () {
var box = document.getElementById("box");
// innerHTML (推荐使用)
alert(box.innerHTML); // <h1>内容<h1>
// innerText
alert(box.innerText);
}
</script>
3、节点/元素的操作
3.1、判断是否有子节点
hasChildNodes(); 判断是否含有子节点,返回true或false
<body>
<div id="go">
来不来。
<h1 id = "come">一起吃饭去!</h1>
</div>
<div id = "empty"></div>
</body>
<script>
window.onload = function () {
// hasChildNodes 是否包含子节点
// 1. go 标签
var go = document.getElementById("go");
alert(go.hasChildNodes()); // true
// 2. come 标签
var come = document.getElementById("come");
alert(come.hasChildNodes()); // true
// 3. empty 标签
var empty = document.getElementById("empty");
alert(empty.hasChildNodes()); // false
}
</script>
3.2、删除节点
remove(); 删除当前标签对象,等同于自杀
removeChild(childElement); 通过父标签对象删除子标签对象
parentElement 父标签对象
<body>
<ul id="city">
<li id="bj">北京</li>
<li id="sh">上海</li>
<li id="gz">广州</li>
</ul>
</body>
<script>
window.onload = function () {
// 直接删除北京 remove();
var bj = document.getElementById("bj");
bj.remove();
// 通过 city 删除上海 parent 调用 removeChild 删除孩子.
var city = document.getElementById("city");
var sh = document.getElementById("sh");
city.removeChild(sh);
// 通过父节点自杀
var gz = document.getElementById("gz");
gz.parentElement.removeChild(gz);
}
</script>
3.3、替换节点
replaceChild(newChild,oldChild); 替换父节点下的子节点. 注意: 需要使用父节点对象调用该方法
你喜欢的城市 : <br />
<ul id="city">
<li id="bj">北京</li>
<li id="sh">上海</li>
</ul>
你喜欢的游戏 : <br />
<ul>
<li id="fk" value="fankong">反恐精英</li>
<li id="ms" value="moshou">魔兽</li>
</ul>
<script>
window.onload = function () {
// 需求: 点击 `北京` 节点, 使用 `反恐精英` 节点实现替换
// replaceChild(newChild, oldChild); 注意: 该方法需要使用 `父节点` 实现调用.
// 1. 获取标签对象
var city = document.getElementById("city");
var bj = document.getElementById("bj");
var fk = document.getElementById("fk");
// 2. 调用方法
bj.onclick = function () {
city.replaceChild(fk, bj);
}
}
</script>
3.4、创建元素
document.createElement("tagName"); 创建标签对象
需要与appendChild() 或 insertBefore()方法联合使用
// 创建节点
document.createElement("li");
3.5、新增子节点
appendChild(newChild); 向父标签内部末尾处追加子节点
<ul id="city">
<li id="bj" value="beijing">北京</li>
<li id="sh" value="shanghai">上海</li>
<li id="cq" value="chongqing">重庆</li>
</ul>
<script>
window.onload = function () {
// 1. 创建节点
var newLi = document.createElement("li");
// 2. 设置内容
newLi.innerHTML = "天津";
// 3. 拼接节点
var city = document.getElementById("city");
city.appendChild(newLi);
}
</script>
insertBefore(newChild,refChild); 向父标签下指定的子节点前添加标签对象. 注意:使用父标签调用该方法
<script>
window.onload = function () {
// 1. 创建节点
var newLi = document.createElement("li");
// 2. 设置内容
newLi.innerHTML = "天津";
// 需求 : 将城市节点 <li>天津</li> 放置到北京和上海的中间
var city = document.getElementById("city");
var sh = document.getElementById("sh");
city.insertBefore(newLi, sh);
}
</script>
4、标签属性的操作
4.1、获取属性
element.getAttribute("name") 或者 element.属性名 :获得属性的值
一般来说,我们直接使用element.属性名即可,如果这种方法不行,就采用上述的方式来获取。
<input type="text" id="txt" value="请输入用户名" class="baidu" />
<script>
window.onload = function () {
// 1. 获取 input 标签
var input = document.getElementById("txt");
// 2. 获取属性
alert(input.value);
alert(input.getAttribute("value"));
alert(input.getAttribute("class"));
}
</script>
4.2、设置属性
element.setAttribute("name","value"):设置属性的值。以直接采用element.属性名通过单等号来赋值
// 需求 : 给input添加一个name属性 name="username"
<script>
window.onload = function () {
// 1. 获取 input 标签
var input = document.getElementById("txt");
// 需求 : 给input添加一个name属性 name="username"
// input.name = "username";
input.setAttribute("name", "username2");
}
</script>
<input type="text" id="txt" value="请输入用户名" class="baidu" />
在浏览器开发者工具里可以看到:如下图
4.3、删除属性
element.removeAttribute("name"); 删除某个属性
// 需求 : 删除 input 的 value 属性
<input type="text" id="txt" value="请输入用户名" class="baidu" />
<script>
window.onload = function () {
// 1. 获取 input 标签
var input = document.getElementById("txt");
// 需求 : 删除 input 的 value 值
input.removeAttribute("value");
}
</script>
5、css样式的修改
obj.style.样式名 获取值
obj.style.样式名=值 修改值 修改的值的格式必须跟css一模一样,也就是说有单位的必须加单位
<div id="box" style="width: 200px; height: 200px; background-color: pink;"></div>
<script>
window.onload = function () {
// 1. 获取 box 标签
var box = document.getElementById("box");
// 2. 设置 box 的属性值
box.style.width = "100px";
box.style.height = "100px";
box.style.backgroundColor = "skyblue";
}
</script>
6、案列
6.1、商品全选全不选反选
html代码:
<body>
<table id="table" border="1" width="100%" align="center" style="text-align: center;">
<tr>
<td colspan="5" align="left">
<input id="uncheckBtn" type="button" value="全不选" />
<input id="reverseBtn" type="button" value="反选" />
</td>
</tr>
<tr>
<th>全选<input id="all" type="checkbox" /></th>
<th>分类ID</th>
<th>分类名称</th>
<th>分类描述</th>
<th>操作</th>
</tr>
<tr>
<td><input type="checkbox" class="itemSelect" /></td>
<td>1</td>
<td>手机数码</td>
<td>手机数码类商品</td>
<td><a href="javascript:;">修改</a>|<a href="javascript:;">删除</a></td>
</tr>
<tr>
<td><input type="checkbox" class="itemSelect" /></td>
<td>2</td>
<td>电脑办公</td>
<td>电脑办公类商品</td>
<td><a href="javascript:;">修改</a>|<a href="javascript:;">删除</a></td>
</tr>
<tr>
<td><input type="checkbox" class="itemSelect" /></td>
<td>3</td>
<td>鞋靴箱包</td>
<td>鞋靴箱包类商品</td>
<td><a href="javascript:;">修改</a>|<a href="javascript:;">删除</a></td>
</tr>
<tr>
<td><input type="checkbox" class="itemSelect" /></td>
<td>4</td>
<td>家居饰品</td>
<td>家居饰品类商品</td>
<td><a href="javascript:;">修改</a>|<a href="javascript:;">删除</a></td>
</tr>
</table>
</body>
js代码实现:
<script>
window.onload = function () {
// 需求 : 全选
// 1.1 获取全选按钮的选择框元素
var all = document.getElementById("all");
// 1.2 获取所有的 itemSelect 标签
var itemSelects = document.getElementsByClassName("itemSelect");
// 2. 给全选按钮绑定单击事件
all.onclick = function () {
// 3. 获取全选按钮的当前状态属性值
// var checked = all.getAttribute("checked"); 不适用
var checked = all.checked;
// alert("checked = " + checked);
// 4. 遍历 itemSelects 数组
for (var i = 0; i < itemSelects.length; i++) {
itemSelects[i].checked = checked;
}
}
// 需求 : 全不选
var uncheckBtn = document.getElementById("uncheckBtn");
uncheckBtn.onclick = function () {
for (var i = 0; i < itemSelects.length; i++) {
itemSelects[i].checked = false;
}
all.checked = false;
}
// 需求 : 反选
var reverseBtn = document.getElementById("reverseBtn");
reverseBtn.onclick = function () {
// 定义一个 count 计算器
var count = 0;
// 遍历 itemSelects 数组
for (var i = 0; i < itemSelects.length; i++) {
// 方式一 : 判断
if (itemSelects[i].checked == true) {
itemSelects[i].checked = false;
} else {
itemSelects[i].checked = true;
// 计算为 true 的数量
count++;
}
// 方式二 : 取反
// itemSelects[i].checked = !itemSelects[i].checked;
// 方式三 : 让 checkbox 被点击一下. 方法: click();
// itemSelects[i].click();
}
// 遍历结束后, 实现判断
if (count == itemSelects.length) {
all.checked = true;
} else {
all.checked = false;
}
}
}
</script>
6.2、隔行换色
思路 : 获取 tr 行, 设置背景色.
html代码:同上
js代码:
<script>
window.onload = function () {
// getElementsByTagName(tr标签);
// 1. 获取所有的 tr 标签
var trs = document.getElementsByTagName("tr");
// alert("trs.length = " + trs.length);
// 2. 遍历 trs 数组
for (var i = 2; i < trs.length; i++) {
// 3. 判断
if (i % 2 == 0) {
trs[i].style.backgroundColor = "yellow";
} else {
trs[i].style.backgroundColor = "skyblue";
}
}
}
</script>
6.3、鼠标移入变色, 移除还原 : onmouseover, onmouseout
html代码同上:
js代码如下:
<script>
window.onload = function () {
// getElementsByTagName(tr标签);
// 1. 获取所有的 tr 标签
var trs = document.getElementsByTagName("tr");
// alert("trs.length = " + trs.length);
// 定义一个 color 属性
var color;
// 2. 遍历 trs 数组
for (var i = 2; i < trs.length; i++) {
// 3. 判断
if (i % 2 == 0) {
trs[i].style.backgroundColor = "yellow";
} else {
trs[i].style.backgroundColor = "skyblue";
}
// 4. 为每一行绑定一个 `鼠标移入 onmouseover` 事件
trs[i].onmouseover = function () {
// 记录当前行颜色
color = this.style.backgroundColor;
// trs[i].style.backgroundColor = "#ccc"; // 行不通. (在函数内部不能使用循环变量 i)
// 当前行实现变色
this.style.backgroundColor = "#ccc";
}
// 5. 为每一行绑定一个 `鼠标移出 onmouseout` 事件
trs[i].onmouseout = function () {
this.style.backgroundColor = color;
}
}
}
</script>
6.4、下拉列表、二级联动
效果图:
html代码:
<body>
<select id="province">
<option value="none">--请选择省--</option>
<option value="0">北京市</option>
<option value="1">上海市</option>
<option value="2">广州市</option>
</select>
<select id="city">
<option value="none">--请选择市--</option>
</select>
</body>
实现方案一 : city.innerHTML
<script>
window.onload = function () {
// 1. 先准备区县的数组
var cities = [
["朝阳区", "海淀区", "丰台区", "昌平区", "西城区", "东城区", "通州区", "大兴区"],
["浦东新区", "闵行区", "静安区", "徐汇区", "杨浦区", "嘉定区", "黄埔区"],
["白云区", "天河区", "花都区", "番禺区"]
];
// 2. 获取 `省` 和 `市` 的标签
var province = document.getElementById("province");
var city = document.getElementById("city");
// 3. 监听省份发生更改事件
province.onchange = function () {
// 注意: 清除 `区县` 信息
city.innerHTML = "<option value=\"none\">--请选择市--</option>";
// 4. 获取 `省份` 对应的value数值
var index = province.value;
// 5. 根据获取的 index, 遍历 cities 二维数组中对应的 `一维数组`.
for (var i = 0; i < cities[index].length; i++) {
// 方式一 : innerHTML
city.innerHTML += "<option value=\"none\">"+ cities[index][i] +"</option>";
}
}
}
</script>
实现方案二 : city.appendChild();
<script>
window.onload = function () {
// 1. 先准备区县的数组
var cities = [
["朝阳区", "海淀区", "丰台区", "昌平区", "西城区", "东城区", "通州区", "大兴区"],
["浦东新区", "闵行区", "静安区", "徐汇区", "杨浦区", "嘉定区", "黄埔区"],
["白云区", "天河区", "花都区", "番禺区"]
];
// 2. 获取 `省` 和 `市` 的标签
var province = document.getElementById("province");
var city = document.getElementById("city");
// 3. 监听省份发生更改事件
province.onchange = function () {
// 注意: 清除 `区县` 信息
city.innerHTML = "<option value=\"none\">--请选择市--</option>";
// 4. 获取 `省份` 对应的value数值
var index = province.value;
// 5. 根据获取的 index, 遍历 cities 二维数组中对应的 `一维数组`.
for (var i = 0; i < cities[index].length; i++) {
// 方式二 : appendChild();
// 创建一个 option 标签对象
var option = document.createElement("option");
// 设置内容
option.innerHTML = cities[index][i];
// 拼接标签
city.appendChild(option);
}
}
}
</script>
实现方案三 : city.options.add(option对象);
<script>
window.onload = function () {
// 1. 先准备区县的数组
var cities = [
["朝阳区", "海淀区", "丰台区", "昌平区", "西城区", "东城区", "通州区", "大兴区"],
["浦东新区", "闵行区", "静安区", "徐汇区", "杨浦区", "嘉定区", "黄埔区"],
["白云区", "天河区", "花都区", "番禺区"]
];
// 2. 获取 `省` 和 `市` 的标签
var province = document.getElementById("province");
var city = document.getElementById("city");
// 3. 监听省份发生更改事件
province.onchange = function () {
// 注意: 将 options 数组长度设置为 1
city.options.length = 1;
// 4. 获取 `省份` 对应的value数值
var index = province.value;
// 5. 根据获取的 index, 遍历 cities 二维数组中对应的 `一维数组`.
for (var i = 0; i < cities[index].length; i++) {
// 方式三 : select 标签中拥有一个 options 数组.
// 创建 option 对象, 使用 new 关键字.
var option = new Option(cities[index][i]);
// 将 option 对象添加到 options 数组中.
city.options.add(option);
}
}
}
</script>
二、正则表达式
1、概述
正则表达式是字符模式的对象、主要用来验证客户端的输入数据、。用户填写完表单单击按钮之后,表单就会被发送到服务器,在服务器端通常会用Java 、PHP、等服务器脚本对其进行进一步处理。因为客户端验证,可以节约大量的服务器端的系统资源,并且提供更好的用户体验
2、正则语法
2.1、创建正则表达式
方法一、采用new运算符、
var box = new RegExp('box'); //第一个参数字符串
var box = new RegExp('box', 'ig'); //第二个参数可选模式修饰符
方法二、采用字面量方式
注意:不用加双引号
var box = /box/; //直接用两个反斜杠
var box = /box/ig; //在第二个斜杠后面加上模式修饰符
模式修饰符可选 参数
2.2、测试正则表达式
/*使用new 运算符的test 方法示例*/
var pattern = new RegExp('box', 'i'); //创建正则模式,不区分大小写
var str = 'This is a Box!'; //创建要比对的字符串
alert(pattern.test(str)); //通过test()方法验证是否匹配
/*使用字面量方式的test 方法示例*/
var pattern = /box/i; //创建正则模式,不区分大小写
var str = 'This is a Box!';
alert(pattern.test(str));
/*使用一条语句实现正则匹配*/
alert(/box/i.test('This is a Box!')); //模式和字符串替换掉了两个变量
/*使用exec 返回匹配数组*/
var pattern = /box/i;
var str = 'This is a Box!';
alert(pattern.exec(str)); //匹配了返回数组,否则返回null
2.3、使用字符串的正则表达式方法
除了test()和exec()方法,String 对象也提供了4 个使用正则表达式的方法。
/*使用match 方法获取获取匹配数组*/
var pattern = /box/ig; //全局搜索
var str = 'This is a Box!,That is a Box too';
alert(str.match(pattern)); //匹配到两个Box,Box
alert(str.match(pattern).length); //获取数组的长度
/*使用search 来查找匹配数据*/
var pattern = /box/ig;
var str = 'This is a Box!,That is a Box too';
alert(str.search(pattern)); //查找到返回位置,否则返回-1
PS:因为search 方法查找到即返回,也就是说无需g 全局
/*使用replace 替换匹配到的数据*/
var pattern = /box/ig;
var str = 'This is a Box!,That is a Box too';
alert(str.replace(pattern, 'Tom')); //将Box 替换成了Tom
/*使用split 拆分成字符串数组*/
var pattern = / /ig;
var str = 'This is a Box!,That is a Box too';
alert(str.split(pattern)); //将空格拆开分组成数组
2.4、正则表达式元字符
(1)、常用元字符
(2)、常用限定符
(3)、常用反义词
(4)、元字符
案例
<script>
// 需求 : 校验用户名必须是 4~12 位字母数字下划线的组合, 不能以数字开头. (正则对象)
// [0-9] 可以使用 \d 表示.
// [a-zA-Z_0-9] 可以使用 \w 表示.
var regex = /^[a-zA-Z]\w{3,11}$/;
var result = regex.test("Jack_xie");
if (result == true) {
alert("用户名可用.");
} else {
alert("请更换用户名.");
}
</script>
3、表单验证
html代码
<body>
<form action="server" method="post" id="myform" onsubmit="return checkAll()">
<table class="main" border="0" cellspacing="0" cellpadding="0">
<tr>
<td>
<img src="../img/logo.jpg" alt="logo" />
<img src="../img/banner.jpg" alt="banner" width="350px" />
</td>
</tr>
<tr>
<td class="hr_1">新用户注册</td>
</tr>
<tr>
<td style="height:10px;"></td>
</tr>
<tr>
<td>
<table width="100%" border="0" cellspacing="0" cellpadding="0">
<tr>
<!-- 长度为4~16个字符,并且以英文字母开头 -->
<td class="left">用户名:</td>
<td class="center">
<input id="user" name="user" type="text" class="in" onblur="checkUser()"/>
<span style="color: red" id="userInfo"></span>
</td>
</tr>
<tr>
<!-- 不能为空, 输入长度大于6个字符 -->
<td class="left">密码:</td>
<td class="center">
<input id="pwd" name="pwd" type="password" class="in" onblur="checkPassword()"/>
<span style="color: red" id="pwdInfo"></span>
</td>
</tr>
<tr>
<!-- 不能为空, 与密码相同 -->
<td class="left">确认密码:</td>
<td class="center">
<input id="repwd" name="repwd" type="password" class="in" onblur="checkRepassword()"/>
<span style="color: red" id="repwdInfo"></span>
</td>
</tr>
<tr>
<!-- 不能为空, 邮箱格式要正确 -->
<td class="left">电子邮箱:</td>
<td class="center">
<input id="email" name="email" type="text" class="in" onblur="checkMail()"/>
<span id="emailInfo" style="color: red;"></span>
</td>
</tr>
<tr>
<!-- 不能为空, 使用正则表达式自定义校验规则,1开头,11位全是数字 -->
<td class="left">手机号码:</td>
<td class="center">
<input id="mobile" name="mobile" type="text" class="in" onblur="checkMobile()"/>
<span id="mobileInfo" style="color: red;"></span>
</td>
</tr>
<tr>
<!-- 不能为空, 要正确的日期格式 -->
<td class="left">生日:</td>
<td class="center">
<input id="birth" name="birth" type="text" class="in" onblur="checkBirth()"/>
<span id="birthInfo" style="color: red;"></span>
</td>
</tr>
<tr>
<td class="left"> </td>
<td class="center">
<input type="image" src="../img/register.jpg" />
</td>
</tr>
</table>
</td>
</tr>
</table>
</form>
</body>
表单验证js代码
<script>
// 检查所有 : 控制了表单的提交事件
function checkAll() {
return checkUser() && checkMail() && checkPassword()
&& checkRepassword() && checkMobile() && checkBirth();
}
// 校验用户名
function checkUser() {
<!-- 长度为4~16个字符,并且以英文字母开头 -->
var regex = /^[a-zA-Z]\w{3,15}$/;
return regexMethod(regex, "user");
}
// 校验邮箱
function checkMail() {
<!-- 不能为空, 邮箱格式要正确 -->
var regex = /^\[email protected]\w+(\.[a-zA-Z]{2,3}){1,2}$/;
return regexMethod(regex, "email");
}
// 校验密码
function checkPassword() {
var regex = /^[a-zA-Z0-9]{6,20}$/;
return regexMethod(regex, "pwd");
}
// 校验重复密码
function checkRepassword() {
// 1. 获取两次密码的数值
var pwd = document.getElementById("pwd").value;
var repwd = document.getElementById("repwd").value;
// 2. 判断
if (pwd != repwd) {
document.getElementById("repwdInfo").innerHTML = "两次密码不一致";
return false;
}
document.getElementById("repwdInfo").innerHTML = "<img src='../img/gou.png' width='15px' />";
return true;
}
// 校验手机号码
function checkMobile() {
var regex = /^1[34578]\d{9}$/;
return regexMethod(regex, "mobile");
}
// 校验生日
function checkBirth() {
// 1988-09-01
// 2008-12-31
var regex = /^((19\d{2})|(200\d))-(0?[1-9]|1[0-2])-(0?[1-9]|[1-2]\d|3[0-1])$/; // type=date
return regexMethod(regex, "birth");
}
// 定义一个函数 (正则封装)
function regexMethod(regex, name) {
var value = document.getElementById(name).value;
if (regex.test(value) == false) {
document.getElementById(name + "Info").innerHTML = "格式不正确!";
return false;
}
document.getElementById(name + "Info").innerHTML = "<img src='../img/gou.png' width='15px'/>";
return true;
}
</script>