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>