DOM:
通过 HTML DOM,使用 JavaScript访问 HTML 文档的所有元素。当网页被加载时,浏览器会创建页面的文档对象模型(Document Object Model)。
HTML DOM 模型被构造为对象的树:
通过可编程的对象模型,JavaScript 获得了足够的能力来创建动态的 HTML:
JavaScript 能够改变页面中的所有 HTML 元素。
JavaScript 能够改变页面中的所有 HTML 属性。
JavaScript 能够改变页面中的所有 CSS 样式。
JavaScript 能够对页面中的所有事件做出反应。
- 获取HTML元素:
操作 HTML 元素必须首先找到该元素
- 通过 id 找到 HTML 元素:
var x = document.getElementById();如果找到该元素,则该方法将以对象(在 x 中)的形式返回该元素;如果未找到该元素,则 x 将包含 null。
注:console.log(mydiv1); 不在官方规范中,但有效,都支持。
<body>
<div id="div1">内容1</div>
<div id="div2">内容2</div>
</body>
<script type="text/javascript">
var mydiv1 = document.getElementById("div1");
console.log(mydiv1);
console.log(mydiv1.constructor);
console.log(mydiv1.innerHTML);
var divs = document.getElementsByTagName("div");
console.log(divs);
console.log(divs.length);
for(var i=0;i<divs.length;i++){
console.log(divs[i]);
}
</script>
运行结果:
var divs = document.getElementsByTagName("div");
for (var i in divs) {//打印出了属性,不建议使用
console.log(divs[i]);
}
运行结果:
- 通过标签名找到 HTML 元素:
上文已有案例
查找 id="main" 的元素,然后查找 id="main" 元素中的所有 <p> 元素(父 --> 子):
var x=document.getElementById("main");
var y=x.getElementsByTagName("p");
- 通过类名找到HTML 元素:
查找 class="intro" 的元素:
<body>
<p class="tagp">p1</p>
<p class="tagp">p2</p>
</body>
<script type="text/javascript">
var ps = document.getElementsByClassName("tagp");
console.log(ps.length);
for(var i=0;i<ps.length;i++){
console.log(ps[i]);
}
</script>
运行结果:
- 改变HTML内容 :
<body>
<p class="tagp">p1</p>
<p class="tagp">p2</p>
</body>
<script type="text/javascript">
var ps = document.getElementsByClassName("tagp");
console.log(ps.length);
for(var i=0;i<ps.length;i++){
console.log(ps[i]);
if(i == 0){
ps[i].innerHTML = "<h3>春天来了</h3>";
}else{
ps[i].innerText = "<h3>春天来了</h3>";
}
}
</script>
运行结果:
- 改变HTML属性 :
<body>
<img id="timg" src="../img/timg (4).gif" />
<button id="btn" type="button" onclick="alterimg()">切换图片</button>
</body>
<script type="text/javascript">
function alterimg(){//可用于动态图
var timg = document.getElementById("timg");
// timg.src="../img/timg (5).gif";//两种方法都可行
// timg.setAttribute("src","../img/timg (5).gif");
timg.setAttribute("width","200px");
}
</script>
- 修改CSS样式:
document.getElementById("p1").style.fontSize="20px";
document.getElementById("p2").style.color="blue";
- 创建新元素 :
创建新的<p> 元素 ,创建文本节点 ,然后必须向 <p> 元素追加这个文本节点 ,最后必须向一个已有的元素追加这个新元素。
<div id="div1">
<p id="p1">这是一个段落。</p>
<p id="p2">这是另一个段落。</p>
</div>
<script type="text/javascript">
var element=document.createElement("p");
var textnode=document.createTextNode("这是一个新段落。");
element.appendChild(textnode);
var div1=document.getElementById("div1");
// div1.appendChild(element);//添加到最后
document.body.insertBefore(element,div1);//添加在之前
</script>
- 删除HTML 元素 :
<script type="text/javascript">
var p1=document.getElementById("p1");
p1.remove();
var p2=document.getElementById("p2");
var div1=document.getElementById("div1");
div1.removeChild(p2);
</script>
找到你希望删除的子元素,然后使用其 parentNode 属性来找到父元素:
var p2=document.getElementById("p2");
p2.parentNode.removeChild(p2);
body:
<script type="text/javascript">
var div1=document.getElementById("div1");//必须为直接子元素
document.body.removeChild(div1);
</script>
- 表格案例:
<body>
<table id="myTable" border="1px solid gtey" width="400px">
<tr>
<th>姓名</th>
<th>年龄</th>
<th>地址</th>
</tr>
</table>
<button type="button" onclick="add()">添加一行</button>
<button type="button" onclick="del()">删除一行</button>
</body>
<script type="text/javascript">
function add(){
var tab=document.getElementById("myTable");
// //创建tr
// var newTr=document.createElement("tr");
// //创建td
// var td1=document.createElement("td");
// var td2=document.createElement("td");
// var td3=document.createElement("td");
// //设置内容
// td1.innerHTML="张三";
// td2.innerHTML=20;
// td3.innerHTML="北京";
// //把td放入tr
// newTr.appendChild(td1);
// newTr.appendChild(td2);
// newTr.appendChild(td3);
// //把tr放入tab
// tab.appendChild(newTr);
//方法2:
var newTr=tab.insertRow(tab.rows.length);
var td0 = newTr.insertCell(0)
var td1 = newTr.insertCell(1);
var td2 = newTr.insertCell(2);
td0.innerHTML="张三";
td1.innerHTML=20;
td2.innerHTML="北京";
}
function del(){
var tab=document.getElementById("myTable");
// tab.rows[tab.rows.length-1].remove();//从表格底部开始删除
// tab.deleteRow();//从表格顶部开始删除
tab.deleteRow(tab.rows.length-1);
}
</script>
运行结果:
- DOM事件:
通过触发事件来执行代码。元素被点击,页面加载完成,输入框被修改等。
<h1 onclick="this.innerHTML='改变内容!'">点击文本!</h1>
<h1 id="id1">myH1</h1>
<button type="button"
onclick="document.getElementById('id1').style.color='red'">button
</button>
onload 和 onunload 事件会在用户进入或离开页面时被触发。
<body onload="alert('页面加载完毕')">
onchange 事件常结合对输入字段的验证来使用。
<input type="text" id="fname" onchange="upperCase()">
onmouseover 和 onmouseout 事件可用于在用户的鼠标移至 HTML 元素上方或移出元素时触发函数。
<div onmouseover="mOver(this)" onmouseout="mOut(this)"
style="background-color:#D94A38;width:120px;height:20px;padding:40px;">Mouse Over Me
</div>
<script type="text/javascript">
function mOver(obj){
obj.innerHTML="Thank You"
}
function mOut(obj){
obj.innerHTML="Mouse Over Me"
}
</script>
运行结果:
- EventListener:
<body>
<div id="text">yyyy</div>
<button type="button" id="btn">按钮</button>
</body>
<script type="text/javascript">
document.getElementById("btn").onclick=function(){//事件被覆盖
document.getElementById("text").innerHTML="xxxx1";
}
document.getElementById("btn").onclick=function(){
document.getElementById("text").innerHTML="xxxx2";
}
</script>
addEventListener() 方法用于向指定元素添加事件句柄,且不会覆盖已存在的事件句柄。
你可以向一个元素添加多个事件句柄,也可以向同个元素添加多个同类型的事件句柄,如:两个 "click" 事件。
你可以向任何 DOM 对象添加事件监听,不仅仅是 HTML 元素。如: window 对象。
当你使用 addEventListener() 方法时,JavaScript 从 HTML 标记中分离开来, 在没有控制HTML标记时也可以添加事件监听。
使用 removeEventListener() 方法来移除事件的监听。
<script type="text/javascript">
var btn = document.getElementById("btn");
btn.addEventListener("click",fn1);
function fn1(){
alert("事件1执行了");
document.getElementById("text").innerHTML="xxxx1";
}
btn.addEventListener("click",fn2);
function fn2(){
alert("事件2执行了");
document.getElementById("text").innerHTML="xxxx2";
}
btn.removeEventListener("click",fn2);
</script>
addEventListener() 方法:
第一个参数是事件的类型 (如 "click" 或 "mousedown"),把on去掉
第二个参数是事件触发后调用的函数。
第三个参数是个布尔值用于描述事件是冒泡还是捕获。该参数是可选的。
element.addEventListener(event, function, useCapture);
事件传递有两种方式:冒泡与捕获。
事件传递定义了元素事件触发的顺序。 如果你将 <p> 元素插入到 <div> 元素中,用户点击 <p> 元素, 哪个元素的 "click" 事件先被触发呢?
在 *冒泡 *中,内部元素的事件会先被触发,然后再触发外部元素,即: <p> 元素的点击事件先触发,然后会触发 <div> 元素的点击事件。
在 *捕获 *中,外部元素的事件会先被触发,然后才会触发内部元素的事件,即: <div> 元素的点击事件先触发 ,然后再触发 <p> 元素的点击事件。
默认值为 false, 即冒泡传递,当值为 true 时,事件使用捕获传递。
<body>
<div id="div1" style="width: 300px;height: 200px;background-color: #00BBFF;">div1
<p id="p1" style="width: 200px;height: 100px;background-color: #00FFFF;">p1</p>
</div>
</body>
<script type="text/javascript">
div1.addEventListener("click",function(){
alert("div1执行了");
event.stopPropagation();//停止传播(冒泡或捕获)
},true);
p1.addEventListener("click",function(){
alert("p1执行了");
},true);
</script>
运行结果:
BOM:
浏览器对象模型 (BOM) 使 JavaScript 有能力与浏览器"对话"。
浏览器对象模型 (BOM):(Browser Object Model)尚无正式标准。
由于现代浏览器已经(几乎)实现了 JavaScript 交互性方面的相同方法和属性,因此常被认为是 BOM 的方法和属性。
- window:
所有浏览器都支持 window 对象,它表示浏览器窗口。
所有 JavaScript 全局对象、函数以及变量均自动成为 window 对象的成员,全局变量是 window 对象的属性,JS全局函数(isNaN(),parseInt(),parseFloat(),String()等)是 window 对象的方法。window都可省略不写。
甚至 HTML DOM 的 document 也是 window 对象的属性之一:
<script type="text/javascript">
//window.document.getElementById("header");
//等同于document.getElementById("header");
var num = 10;
var name = "张三";
function fn1(){
alert("事件1执行了");
document.getElementById("text").innerHTML="xxxx1";
}
window.fn1();
console.log(window.num);
console.log(window.name);
</script>
获取窗口尺寸(实用的 JavaScript 方案(涵盖所有浏览器)):
//实时窗口尺寸
var w=window.innerWidth||document.documentElement.clientWidth||document.body.clientWidth;
var h=window.innerHeight||document.documentElement.clientHeight||document.body.clientHeight;
window.open();//打开新窗口
window.close();//关闭当前窗口
- Screen :
返回屏幕的实时宽度和高度,以像素计,减去界面特性,比如窗口任务栏。
document.write("可用宽度: " + screen.availWidth);
document.write("可用高度: " + screen.availHeight);
- Location :
- location.href 属性返回当前页面的 URL。
- location.hostname 返回 web 主机的域名
- location.pathname 返回当前页面的路径和文件名
- location.port 返回 web 主机的端口 (80 或 443)
- location.protocol 返回所使用的 web 协议(http:// 或 https://)
<script>
window.open("multi99.html");//在新页面打开
// window.location="multi99.html";//在当前页面打开
// window.location.href="multi99.html";//在当前页面打开
// window.location.assign("multi99.html");//在当前页面打开,加载一个新的文档
</script>
- History:
window.history 对象包含浏览器的历史。为了保护用户隐私,对 JavaScript 访问该对象的方法做出了限制。
window.history.back();//与在浏览器点击后退按钮相同
window.history.forward();//与在浏览器中点击按钮向前相同
<body>
<a href="multi99.html">跳转到九九乘法表</a>
<button type="button" onclick="getHistory()">获取历史纪录</button>
<button type="button" onclick="goback">后退</button>
</body>
<script type="text/javascript">
function getHistory(){
alert(window.history.length);
}
function goback(){
// window.history.back();
window.history.go(-1);
}
</script>
<body>
<a href="demo.html">跳转到历史记录页面</a>
</body>
- Navigator :
<script>
txt = "<p>浏览器代号: " + navigator.appCodeName + "</p>";
txt+= "<p>浏览器名称: " + navigator.appName + "</p>";
txt+= "<p>浏览器版本: " + navigator.appVersion + "</p>";
txt+= "<p>启用Cookies: " + navigator.cookieEnabled + "</p>";
txt+= "<p>硬件平台: " + navigator.platform + "</p>";
txt+= "<p>用户代理: " + navigator.userAgent + "</p>";
txt+= "<p>用户代理语言: " + navigator.systemLanguage + "</p>";
document.getElementById("example").innerHTML=txt;
</script>
Date对象:
<script type="text/javascript">
var d=new Date();
document.write(d);
document.write("<br/>")
//根据本地时间获取当前缩写年份(当前年份减去1900)
document.write("年份:"+(d.getYear(+1900)));
document.write("<br/>")
//根据本地时间获取当前年份(四位数字)
document.write("年份:"+d.getFullYear());
document.write("<br/>");
document.write("月份:"+(d.getMonth()+1))
document.write("<br/>");
document.write("日期:"+d.getDate());
document.write("<br/>");
document.write("小时:"+d.getHours());
document.write("<br/>");
document.write("分钟:"+d.getMinutes());
document.write("<br/>");
document.write("秒:"+d.getSeconds());
</script>
- JavaScript计时函数:
以下都是Window对象的方法。
//第一个参数是含有 JavaScript 语句的字符串
//这个语句可能诸如 "alert('5 seconds!')",或者对函数的调用,诸如 "alertMsg()"或alertMsg
//第二个参数指示从当前起多少毫秒后执行第一个参数
//第三个参数:第一个参数是有参函数的情况下,第一个函数的参数数组
setInterval(code: String, interval: Number, args: Array);
setTimeout(func: Function, delay: Number, args: Object);//延迟执行函数
clearInterval();//用于停止 setInterval() 方法执行的函数代码
//周期执行函数(相当于启动一个线程):间隔指定的毫秒数不停地执行指定的代码
var timer1 = setInterval("myTimer()",1000);
var timer2 = setInterval(myTimer,1000);
- 计时案例:
一个 setInterval 相当于开启一个线程,用户可能会多次点击 'Start Time' 按钮,此时会开启很多线程运行时间,但是clearInterval 只能关闭最后一个线程,导致动态时间无法关闭,此时需要在按钮函数中设置按钮的有效性控制用户的操作,达到按钮功能安全的实现。
<body>
<span id = "time"></span>
<button id="start" type="button" onclick="startTimer()">Start Time</button>
<button id="stop" type="button" onclick="stopTimer()">Stop Time</button>
</body>
<script type="text/javascript">
var timer;
function myTimer(){
var date = new Date();
var t = date.toLocaleString();
document.getElementById("time").innerHTML=t;
}
function startTimer(){
timer = setInterval(myTimer,1000);
alert(timer);
document.getElementById("start").disabled=true;
document.getElementById("stop").disabled=false;
}
function stopTimer(){
alert(timer);
clearInterval(timer);
document.getElementById("stop").disabled=true;
document.getElementById("start").disabled=false;
}
</script>
运行结果:
- setTimeout案例:
setTimeout(function(){
alert("恭喜中奖,请联系客服,电话:110");
},5000);
<script type="text/javascript">
var num = 0;
var id;
function show(){
document.write(num+"好好学习<br/>");
num++;
if(num != 10){
id = setTimeout(show,1000);
}
}
id = setTimeout(show,1000);
</script>
运行结果:
注意:这不是递归!!!而是多线程。递归是靠一个引用自我调用,底层是引用(指针)连接的方法的压栈与弹栈。这里是主线程运行时开启一个子线程,子线程运行时依次开启一个子线程,最后加上第一个子线程,一共有10个子线程,对应num的 0 到 9。