一、验证码案例
【1.1 】 生成有字母、数字组合成的四位验证码
//随机验证码:数字和字母组合,(四个数字和字母)
/*
===> 1先把验证码准备好
===> 2随机获取相应的索引值
===> 3获取元素
*/
function getCode(){
var str="qwertyuiopasdfghjklzxcvbnm"+"QWERTYUIOPASDFGHJKLZXCVBNM"+"0123456789";
var result="";
//==> 索引值的范围:0---61
for(var i=0;i<4;i++){
var index=Math.round(Math.random()*61);
var item=str[index];
result+=item;
}
return result;
}
var code=document.getElementById("code");
var btn=document.getElementById("btn");
code.innerHTML=getCode();
btn.onclick=function(){
code.innerHTML=getCode();
}
【1.2】生成不重复的验证码
for(var i=0;i<4;i++){
var index=Math.round(Math.random()*61);
var item=str[index];
//===>新增一个判断
if(str.indexOf(item)>-1){
// 此次循环作废,总共四次,浪费了一次,所以需要
i--;
continue;
}
result+=item;
}
【1.3】 while 循环实现
只要条件成立,就一直执行,知道条件不成立的时候停止
while(条件){ 执行体 }
function getCode(){
var str="qwertyuiopasdfghjklzxcvbnm"+"QWERTYUIOPASDFGHJKLZXCVBNM"+"0123456789";
var result="";
//==> 索引值的范围:0---61
while(result.length<4){
var index=Math.round(Math.random()*61);
var item=str[index];
if(result.indexOf(item)==-1){
result+=item;
}
}
return result;
}
二、dom操作
2.1【dom树】:浏览器在加载页面的时候,首先就是dom的结构计算,它形式就像是一颗大树,有很多的分支,所以被称为 "dom tree"
【回流和重绘】
-
重绘(repaint):当元素样式的改变不影响布局时,浏览器将使用重绘对元素进行更新,此时由于只需要 UI 层面的重新像素绘制,因此损耗较少。
常见的重绘操作有:
-
- 改变元素颜色
-
- 改变元素背景色
-
- more ……
-
-
回流(reflow):又叫重排(layout)。当元素的尺寸、结构或者触发某些属性时,浏览器会重新渲染页面,称为回流。此时,浏览器需要重新经过计算,计算后还需要重新页面布局,因此是较重的操作。
常见的回流操作有:
-
- 页面初次渲染
-
- 浏览器窗口大小改变
-
- 元素尺寸/位置/内容发生改变
-
- 元素字体大小变化
-
- 添加或者删除可见的 DOM 元素
-
- 激活 CSS 伪类(:hover……)
-
- more ……
• 重点:回流必定会触发重绘,重绘不一定会触发回流。重绘的开销较小,回流的代价较高。
- more ……
-
2.2[常用的dom操作方法]
1)getElementById:通过元素的id获取元素.
document.getElementById("box");
【document】:
document 是上下文,限制范围的意思:在哪个范围下的 id名字是box的这个元素,不过这个上下文只能是 document
【id名字唯一性】:
id名字是唯一的,一个document文档中不能同时出现多个相同的id名字,如果设置了多个相同的id,只能获取到第一个。
[兼容性注意]:不要让name 和id的名字一样。因为在ie6-ie7 的时候,如果设置了name属性,通过id也可以获取到
<body>
<input type="text" name="text">
</body>
</html>
<script>
console.log(document.getElementById("text"));
// 在ie6或者ie7的时候可以获取到
</script>
2)【context].getElementsByTagName:在特定的上下文中,通过标签名,获取一组元素。
- 得到的是一个类数组,不能直接用数组的方法
- 得到的是一个集合,如果想要操作其中的某一项,可以基于索引获取。
var omain=document.getElementById("main");
var olis=omain.getElementsByTagName("li");
// 想要获取到第二个li:olis[1]
3) [context].getElementsByCalssName:通过类名获取元素集合
• 此方法在ie6--ie8下不兼容
4)document.getElementsByName:通过name名字获取一组元素集合
- 它的上下文也只能是document
- 另外,正常的规范中,咱们只会给表单元素起name值,如果给其它元素设置name,在ie9以下版本浏览器不兼容,是获取不到的,所以为了这种情况,咱们以后养成习惯,只给表单元素用name,非表单元素不用name
5)【context].querySelector("选择器")
通过选择器获取指定的元素,即使匹配的有多个,也只会对第一个起作用,获取到的是一个对象(给咱们平时写样式时候写选择器是一样的)
<div class="main">
<div class="box1"></div>
</div>
document.querySlector(".main>div")
6)【context】.querySelectorAll("选择器")
通过指定的选择器获取一组节点结合 注意:querySelector 和querySelector 在ie6-ie8 下不兼容
7)document.head
获取Head元素对象
8) document.body
获取body元素对象
9) document.documentElement
获取html元素对象
【需求:】获取一屏幕的宽度或者高度,兼容所有的浏览器
// 获取一屏幕的高度
var vH=document.documnentElement.clientHeight || document.body.clientHeight;
// 偶去一屏幕的宽度
var vW=document.documentElement.clientWidth || document.body.clientWidth;
2.3 练习题:
获取页面中所有name属性值为 "hehe" 的元素标签
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
<style>
</style>
</head>
<body>
<div class="box1">
<input type="text" name="he1">
</div>
<input class="box1" name="he1">
</body>
</html>
<script>
function getElementsByName(value){
var allTag=document.getElementsByTagName("*");
var names=[];
for(var i=0;i<allTag.length;i++){
var item=allTag[i];
if(item.name==value){
names.push(item);
}
}
return names;
}
var ary=getElementsByName("he1")
</script>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
</head>
<body>
<div id="main">
<div class="box1">
<input type="text" name="he1" id="input1">
<div name="he1" id="div2">111</div>
</div>
<input class="box1" name="he1">
</div>
</body>
</html>
<script>
var omain=document.getElementById("main");
function getName(contex,name,attr){
var tags=contex.getElementsByTagName("*");
var ary=[];
for(var i=0;i<tags.length;i++){
if(tags[i].getAttribute(name)==attr){
ary.push(tags[i])
}
}
return ary;
}
var res=getName(omain,"name","he1");
console.log(res);
</script>
关于id的一些鲜为人知的事情: 直接把id当成变量去用的时候,可以获取相应的id元素。(浏览器的机制)
console.log(box1)
2.4【节点】
1)、文档节点
-
nodeType:9
-
nodeName:"#document"
-
nodeValue:null document.nodeType;
document.nodeName
document.nodeValue;
2)、属性节点
- nodeType:2
- nodeName:属性名
- nodeValue:属性值
<a href="http://www.baidu.com" id="a1">百度</a>
var a1=a1.getAttributeNode("href");// 获取属性节点
console.log(a1.nodeType);//2
console.log(a1.nodeName);//"href"; 属性名
console.log(a1.nodeValue);//"http://www.baidu.com"; 属性值
3)、元素节点
- nodeType:1
- nodeName:大写的标签名
- nodeValue:null
4)、文本节点
- nodeType:3
- nodeName:"#text"
- nodeValue:文本内容
- 在标准浏览器中,换行和空格也属于文本节点
<a href="http://www.baidu.com" id="a1">百度</a>
var res=a1.childNodes[0];
console.log(res.nodeType);//3
console.log(res.nodeValue);//"百度";
console.log(res.nodeName);//"#text";
5)、注释节点
- nodeType:8
- nodeName:"#comment"
- nodeValue:注释的内容
<a href="http://www.baidu.com" id="a1">
<!--a标签 -->
百度
</a>
a1.childNodes; //NodeList(3) [text, comment, text]
a1.childNodes[1].nodeName;//"#comment"
a1.childNodes[1].nodeType;//8
a1.childNodes[1].nodeValue;//"a标签 "
2.5【节点的关系关系属性】
1)parentNode
获取当前节点唯一的父亲节点
2)childNodes
获取当前节点所有的子节点
<ul id="main">
<!-- 我是注释 -->
<li>你永远是最胖的</li>
<li>你永远是最胖的</li>
<li>你永远是最胖的</li>
<li>你永远是最胖的</li>
</ul>
<script>
console.log(main.childNodes);
</script>
3)children
获取当前元素所有的元素子节点,但是在ie6--ie8下不兼容
console.log(main.children);
4)previousSibling
获取上一个哥哥节点 main.previousSibling
5)previousElementSibling
ie6-ie8 不兼容
<span>1</span>
<ul id="main">
<!-- 我是注释 -->
<li>你永远是最胖的</li>
<li>你永远是最胖的</li>
<li>你永远是最胖的</li>
<li>你永远是最胖的</li>
</ul>
<script>
console.log(main.previousElementSibling);
//<span>1</span>
<script>
6)nextSibling
获取当前节点的下一个兄弟节点
<span id="span1">1</span>
<ul id="main">
<!-- 我是注释 -->
<li>你永远是最胖的</li>
<li>你永远是最胖的</li>
<li>你永远是最胖的</li>
<li>你永远是最胖的</li>
</ul>
<span>2</span>
7) nextElementSibling
获取当前节点的下一个元素兄弟节点 ie6-ie8 不兼容
8)firstChild
获取当前节点的第一个子节点
9)firstElementChild
获取当前节点的第一个元素子节点 ie6-ie8 不兼容
10)lastChild
获取当前节点的最后一个子节点
11) lastElementChild
获取当前节点的最后一个元素子节点 ie6-ie8 不兼容
三、练习题
1) 自己手动封装一个获取节点下面的所有子元素,要求考虑兼容性。
Document </style> 1- 选择珠峰的,都是明智的!
- 选择珠峰的,都是明智的!
- 选择珠峰的,都是明智的!
- 选择珠峰的,都是明智的!
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
<style>
</style>
</head>
<body>
<span id="span1">1</span>
<ul id="main">
<!-- 我是注释 -->
<li>你永远是最胖的</li>
<li>你永远是最胖的</li>
<li>你永远是最胖的</li>
<li>你永远是最胖的</li>
</ul>
<span id="span2">2</span>
</body>
</html>
<script>
function previousElmentSibling(ele){
var pre=ele.previousSibling;
while(pre&&pre.nodeType!==1){
pre=pre.previousSibling;
}
return pre;
}
previousElmentSibling(span2)
</script>
四、dom 的增删改
1) createElement:创建一个元素
documment.createElement("div");
2) createTextNode: 创建一个文本节点
var otext=document.createTextNode("哈哈!");
3) appendChild:把元素追加到一个容器的末尾
【context】.appendChild([元素]);
var odiv=documment.createElement("div");
document.body.appendChild(odiv);
4)insertBefore: 把一个元素插入到另一个元素的前面
把新元素添加到原有元素的前面
【context】.insertBefore(newEle,oldEle);
5) cloneNode:把某一个节点进行克隆
- 【ele】.cloneNode();浅克隆: 只是克隆了一个节点,里面的内容还有样式都没克隆
- 【ele】.cloneNode(true);深克隆:把节点包含的所有内容进行克隆
6)removeChild:移除某个节点
【context】.removeChild(ele);
7)set/get/removeAttribute
设置/获取/删除 当前元素的某一个自定义属性
- setAttribute
- getAttribute
- removeAttribute
<div id="box"></div>
//=======> setAttribute 设置
box.setAttribute("index",1);
box.getAttribute("index");
box.removeAttribute("index");
//========> 基于键值对操作
// 设置
box["aa"]=22;
// 获取
box["aa"]
//移除
delete box[aa];
基于键值对方式 增删改:修改当前对象的堆内存空间完成的(在堆内存空间可以看到) 基于Attribute dom方法增删改,是修改html结构来完成的(此种方法设置的在结构上可以看到)
以上两种方式不能混用
五、利用a标签的href来重新获取url参数
var str="www.zhufengpeixun.cn?name=lili&age=18#123" /* search: "?name=lili&age=18" hash: "#123" */
function queryParams(str){
var a=document.createElement("a");
a.href=str;
var obj={};
console.log(a.search); //?name=lili&age=18
console.log(a.hash); //#123
//[name=lili,age=18]
var search=a.search.substr(1);
obj.hash=a.hash?hash:null;
if(search){
var searchAry=search.split("&");
for(var i=0;i<searchAry.length;i++){
var itemAry=searchAry[i];
//[name,lili]
var item=itemAry.split("=");
var key=item[0];
var value=item[1];
obj[key]=value;
}
}
return obj;
}
var dd=queryParams(str);