EMCAScript的定义,更多的是在编程语言的方面进行定义,如果在Web中使用JavaScript,则BOM模型才是JavaScript语言的核心.BOM模型提供了很多对象,用于访问浏览器的很多功能,这些功能与网页的内容是无关的.BOM学习博客地址
BOM模型
BOM(Browser Object Model)模型是浏览器对象模型.
window对象
window对象表示浏览器的一个窗口的实例.也是ECMAScript规定的全局对象.网页中定义的任何一个全局变量,对象,函数,都是window对象的属性.
属性或者方法 |
说明 |
window.innerHeight |
浏览器窗口的内部高度 |
window.innerWidth |
浏览器窗口的内部宽度 |
window.open() |
打开新窗口,open可以加第一个参数表示URL,第二个参数表示窗口名,第三个参数用于一些控制 |
window.close() |
关闭当前窗口 |
navigator对象
浏览器对象,通过这个对象可以判定用户所使用的浏览器,包含了浏览器相关信息。是window的子对象.通过navigator取得的信息并不精准,因为浏览器设置可以伪造这些信息.
属性或者方法 |
说明 |
navigator.appName |
Web浏览器全称 |
navigator.appVersion |
Web浏览器厂商和版本的详细字符串 |
navigator.userAgent |
客户端信息 |
navigator.platform |
浏览器所在的操作系统 |
screen对象
表示屏幕对象,不常用.
screen.availWidth - 可用的屏幕宽度
screen.availHeight - 可用的屏幕高度
history对象
window.history 对象包含浏览器的历史。浏览历史对象,包含了用户对当前页面的浏览历史,但我们无法查看具体的地址,可以简单的用来前进或后退一个页面。
history.forward() // 前进一页
history.back() // 后退一页
location对象
window.location 对象用于获得当前页面的地址 (URL),并把浏览器重定向到新的页面。
location.href 获取URL
location.href="URL" // 跳转到指定页面
location.reload() 重新加载页面
弹出框
浏览器通过alert(), confirm(), prompt()三个方法调用系统对话框向用户显示消息.这些对话框与网页没有关系,也不包含HTML和CSS,在显示对话框的时候,HTML页面内的代码是停止执行的,说明对话框程序是同步的.
属性或者方法 |
说明 |
alert() |
内部参数是字符串,会在提示框中显示出来,一般用在向用户通知他们无法控制的消息 |
confirm() |
参数也是字符串,这个框除了OK按钮之外 ,还有一个Cancel按钮,用户点击了哪个,就会通过confirm()返回对应的布尔值 |
prompt() |
除了OK和Cancel之外,还有一个文本输入区域,用于提示用户输入一些内容.Prompt接受两个参数,一个是显示的提示信息,一个是文本输入区域的默认值.如果用户单击了OK,会返回文本区域的值,如果用户单击了Cancel,会返回Null. |
定时器
定时器有两个函数,用法类似:
var timer = setTimeout(function(){alert(123);}, 3000)
clearTimeout(timer);
第一个语句的setTimeout函数接受两个参数,第一个是JS语句或者是一个函数,第二个数值是以毫秒,一旦设置了timer,第一个参数中的JS代码就会在第二个参数指定后的时间后运行.将其赋给一个变量的话,就可以用clearTimeout(变量名)来取消该定时器.setTimeout是一次性的定时器,除此之外还有一个间隔一定时间反复执行的定时器:
// 每隔一段时间就执行一次相应函数
var timer = setInterval(function(){console.log(123);}, 3000)
// 取消setInterval设置
clearInterval(timer);
定时器也是由浏览器提供的功能,定时器本身的间隔受到浏览器的精确程度影响,比如ie的间隔最小为4ms.因此定时器不应该设置的过短.
DOM模型-选择和操作节点元素
DOM模型应该说是大家为什么要使用JavaScript的原因,也就是可以方便的操作HTML页面内的所有元素,以及做到HTML和CSS做不到的事情,就是动态的修改网页内容以及提供事件响应.
当网页被加载的时候,浏览器会创建页面的文档对象模型,是一个树结构.只要将一个JS文件引入HTML页面,则这个JS文件里的代码就可以操作这个页面的DOM模型.在DOM里提到元素和节点,基本是一个意思,都是指的被选中的HTML标签及其全部内容
DOM标准规定HTML文档中的每个成分都是一个节点(node):
- 文档节点(document对象):代表整个文档
- 元素节点(element 对象):代表一个元素(标签)
- 文本节点(text对象):代表元素(标签)中的文本
- 属性节点(attribute对象):代表一个属性,元素(标签)才有属性
- 注释是注释节点(comment对象)
JavaScript 通过DOM模型,可以改变页面内所有的HTML元素,内容,样式和响应事件,这样就可以创建动态网页.DOM是JavaScript作为前端开发语言最重要的内容.
查找节点
查找节点即定位节点,有若干种办法. 将查找的结果赋值给变量,该变量即存储了找到的节点.定位节点之后就可以针对该节点进行增删改操作.
直接查找 |
document.getElementById |
根据ID获取一个标签,由于ID是唯一的,直接返回的就是节点对象 |
document.getElementsByClassName |
根据class属性获取,由于一般类是多个,所以返回的是一个包含节点对象的数组 |
document.getElementsByTagName |
用标签名称选元素,返回的也是数组 |
间接查找 |
parentElement |
父节点标签元素,直接返回一个节点元素 |
children |
所有子节点元素,返回的是一个数组 |
firstElementChild |
第一个子元素,返回节点对象,如果不存在,返回undefined |
lastElementChild |
最后一个子元素,返回节点对象,如果不存在,返回undefined |
nextElementSibling |
返回下一个兄弟元素 |
previousElementSibling |
返回上一个兄弟元素 |
操作节点
创建节点 |
document.createElement("tagname"); |
创建一个标签元素,其中的tagname是符合HTML标准的标签名,创建节点常用原生的JS语句 |
添加节点 |
node.appendChild(newnode) |
这个是将newnode节点添加到node节点的子元素中,作为node节点的最后一个子元素.在定义了一个元素后,反复插入这个元素,会发现这个元素只能同时出现在一处,想要插入新元素,就必须再创建一个元素. |
fathernode.insertBefore(newnode,node); |
首先需要定位node的父标签,然后将newnode插入到node标签之前,做为node标签的上一个兄弟元素. |
删除节点 |
node.removeChild(targetnode) |
需要获得要删除的元素的父元素,然后采用该方法删除元素 |
替换节点 |
fathernode.replaceChild(newnode, targetnode); |
也需要定位需替换节点的父元素,然后替换该节点 |
修改节点属性和内容 |
divEle.innerText |
取得文本部分的值,可以对其进行设置,设置的时候全部是字符串,即使有标签字样也会解释成字符串.注意,如果对父元素使用,取值会取自己加所有子元素的文本内容 , 如果修改会影响所有的东西,包括嵌套的标签. |
divEle.innerHTML |
获取这个节点开始和结束标签之间的HTML内容.如果设置的话,值中如果有符合HTML标签的字样,会被解释成标签. |
node.内置属性名 = '值' |
对于内置属性名,可以直接通过属性名赋值,比如src,href等属性 |
node.setAttribute("age","18") |
Attribute用来操作自定义属性,这个是设置自定义属性与值 |
node.getAttribute("age") |
获取自定义属性 |
node.removeAttribute("age") |
删除自定义属性 |
获取值
获取值通过value属性,只能作用于input,select,textarea这三个表单元素.
value对于text获取的是输入的值或者被选中的选项标签里设置的value属性,对于select是菜单选项标签的value,对于textarea是输入的值,经常用在表单提交的事件中,对表单元素的值进行验证.
操作节点的class属性
在选择到具体的节点之后,可以通过classList属性来操作这个标签的类属性.
操作class属性 |
node.className |
获取class属性的内容,是一个字符串,只能看,不能操作 |
node.classList |
返回一个类的列表,用空格区分开的类名是列表的一个元素,相比获得字符串,获得类列表可以用来操作类属性 |
classList.add(cls) |
给节点增加一个类 |
classList.contains(cls) |
判断这个元素是否属于某个类,也就是列表中是否包含类名,是则返回true,不是则返回false |
classList.toggle(cls) |
切换类,每次执行,如果类列表内有类名,就会删除该类,如果没有类名,就会添加类.通常用来实现一些在两种样式之前切换的效果. |
操作节点的CSS属性
操作CSS属性 |
node.style |
获取一个节点的所有css属性的集合,如果在浏览器里可以看到,是一个很长的列表,一般不单独使用 |
node.style.CSS属性名='值' |
操作CSS属性,注意css属性中用短横线连接,在JS里改成了驼峰命名 |
DOM模型-事件
目前通过JS已经可以操作一个页面所有的HTML标签的内置属性以及CSS样式了,即可以操作静态页面的所有内容.为了让页面实现动态交互,很重要的就是对事件的捕捉和处理.
JS处理事件的逻辑是--所有的标签都有一些事件--选择需要侦听哪些事件--当事件发生的时候,用JS函数来处理--处理的结果呈现在页面上.
常用事件 |
onclick |
当用户点击某个对象时调用的事件句柄 |
ondblclick |
当用户双击某个对象时调用的事件句柄 |
onfocus |
当元素获得焦点,通常使用在输入框上 |
onblur |
元素失去焦点,常用在用户输入完之后移动到其他地方,这个时候可以对输入内容进行验证 |
onchange |
域的内容被改变,常用在select元素里边的内容改变的时候 |
onsubmit |
表单中的submit按钮被按下的时候,常用在表单与后端交互的时候 |
onkeydown |
某个键被按下 |
onkeypress |
某个键按下以后松开的时候 |
onkeyup |
某个键被松开,这些侦听按键的事件,通常用在写一些web游戏中 |
onmousedown |
鼠标按键被按下 |
onmousemove |
鼠标移动 |
onmouseout |
鼠标从某元素上移动开 |
onmouseover |
鼠标移动到某元素之上,这一系列鼠标的效果经常用在弹出菜单等特效上 |
onselect |
在文本框中的文本被选中时发生 |
onselect |
在文本框中的文本被选中时发生 |
操作事件的例子
<!--点击某个元素会变色-->
<div id="change" onclick="changeColor(this)">div</div>
<script>
function changeColor(ths) {
ths.style.backgroundColor="green";
}
</script>
在JS语句内,定义的是函数,ths是形参,表示调用这个函数的对象,调用的时候,这个函数绑定的对象就是这个标签.ths形参指的是这个标签对象.
在实际使用该函数的时候,在标签内部的需要把事件名称和函数关联起来,且给函数传递实参. 这里的实参this是一个关键字,就表示当前的对象自己(类似于python里的self).
这段代码的意思就是div标签的onclick事件发生的时候,调用changeColor函数,将自己传入给这个函数,修改自己的CSS背景颜色属性为绿色.
定时器实例
// 让一个文本框里显示时间.两个按钮,一个启动显示时间,一个停止并且清除文本框.
// 先建立三个元素
<input type="text" id="in">
<input type="button" id="start" onclick="refreshTimer()" value="开始">
<input type="button" id="stop" onclick="stopTimer()" value="停止">
<script>
// 因为不同的函数都要操作定时器,所以将定时器设置为全局变量
var input = document.getElementById('in');
var t = null;
// 修改input.value的函数
function startTimer() {
var current_time = new Date();
input.value = current_time.toLocaleString();
}
// 定时器函数,间隔1秒反复执行修改input.value的函数,绑定给开始按钮
function refreshTimer() {
t = setInterval(startTimer, 1000)
}
// 停止定时器且清空input.value的函数,绑定给停止按钮
function stopTimer() {
clearInterval(t);
input.value = '';
}
</script>
但这个程序其实有BUG,如果双击开始,则会发现停不掉定时器,这是因为点击两次的时候,虽然变量相同,但t等于对应了一个新的定时器,老的定时器依旧在运行,只不过t不再指向老的定时器,所以清除不掉.
这里只需要在生成定时器的时候判断一下t的值,如果t!==undefined,就不再设置新的定时器,然后在定时器结束的代码里,加上t=undefined即可.修改后的程序是这样的:
<body>
// 让一个文本框里显示时间.两个按钮,一个启动显示时间,一个停止并且清除文本框.
// 先建立三个元素
<input type="text" id="in">
<input type="button" id="start" onclick="refreshTimer()" value="开始">
<input type="button" id="stop" onclick="stopTimer()" value="停止">
<script>
// 因为不同的函数都要操作定时器,所以将定时器设置为全局变量
var input = document.getElementById('in');
var t;
// 修改input.value的函数
function startTimer() {
var current_time = new Date();
input.value = current_time.toLocaleString();
}
// 如果T是未定义,才启动定时器,如果T有值,就跳过.
function refreshTimer() {
if (t == undefined) {
t = setInterval(startTimer, 1000)
}
}
// 停止定时器,重新把t赋值undefined,绑定给停止按钮
function stopTimer() {
clearInterval(t);
input.value = '';
t = undefined;
}
</script>
这个例子说明一个页面内不要存在同种的多个定时器
改进一下,用一个按钮来控制,先修改标签名称然后进行判断,就不会启动多个定时器.:
<input type="text" id="in">
<input type="button" id="start" onclick="pressed()" value="开始">
<script>
const input = document.getElementById('in');
const button = document.getElementById('start');
var t = null;
function pressed() {
if (button.value === "开始") {
button.value = '停止';
refreshTimer();
} else {
stopTimer();
}
}
function startTimer() {
var current_time = new Date();
input.value = current_time.toLocaleString();
}
function refreshTimer() {
t = setInterval(startTimer, 1000)
}
function stopTimer() {
clearInterval(t);
input.value = '';
button.value = '开始'
}
</script>