## 一、BOM ### 1、定义 浏览器对象模型BOM(Browser Object Model),它使 JavaScript 有能力与浏览器进行“对话”,控制浏览器行为(跳转,前进,后退,获取屏幕大小等) ### 2、结构 - BOM是Browser Object Model的缩写,简称浏览器对象模型 - BOM提供了独立于内容而与浏览器窗口进行交互的对象 - 由于BOM主要用于管理窗口与窗口之间的通讯,因此其核心对象是window - BOM由一系列相关的对象构成,并且每个对象都提供了很多方法与属性 - BOM缺乏标准,JavaScript语法的标准化组织是ECMA,DOM的标准化组织是W3C(WHATWG,WebHypertextApplicationTechnologyWorkingGroup——网页超文本应用程序技术工作组目前正在努力促进BOM的标准化) - BOM最初是Netscape浏览器标准的一部分 结构图如下: ![](http://nhfcloms-deveopler.oss-cn-beijing.aliyuncs.com/dwwb/portal/project/1635153335572/01.png) BOM提供了可以访问窗口对象的一些方法,我们可以用它来移动窗口位置,改变窗口大小,打开新窗口和关闭窗口,弹出对话框,进行导航以及获取客户的一些信息如:浏览器品牌、版本,屏幕分辨率等。但BOM最强大的功能是它提供了一个访问HTML页面的入口——document对象,以使得我们可以通过这个入口来使用DOM的强大功能。 ### 3、BOM对象用法小结 #### (一) window 对象 window对象是BOM的顶层(核心)对象,所有对象都是通过它延伸出来的,也可以称为window的子对象。由于window是顶层对象,因此调用它的子对象时可以不显示的指明window对象,window对象表示整个浏览器窗口,但不必表示其中包含的内容。此外,window还可用于移动或调整它表示的浏览器的大小,或者对它产生其他影响。 ##### 1. window 对象的属性: 属性 | 描述 ---|--- closed | 返回窗口是否已被关闭 defaultStatus | 设置或返回窗口状态栏中的默认文本 frames| 返回窗口中所有命名的框架。该集合是 Window 对象的数组,每个 Window 对象在窗口中含有一个框架 length | 设置或返回窗口中的框架数量 name | 设置或返回窗口的名称 opener | 返回对创建此窗口的窗口的引用 parent | 返回父窗口 self | 返回对当前窗口的引用。等价于window属性 status | 设置窗口状态栏的文本 top | 返回最顶层的父窗口 screenX | 设定窗口距离屏幕左边界的像素长度 screenY | 设定窗口距离屏幕上边界的像素长度 screenLeft | 等价于window.screenX screenTop | 等价于window.screenY outerHeight | 返回窗口的外部高度 outerWidth | 返回窗口的外部宽度 innerHeight | 返回窗口的文档显示区的高度 innerWidth | 返回窗口的文档显示区的宽度 pageXoffset | 设置或返回当前页面相对于窗口显示区左上角的X位置(此方法只有IE支持) pageYoffset | 设置或返回当前页面相对于窗口显示区左上角的Y位置 (此方法只有IE支持) ##### 2. window 对象的方法: 方法 | 描述 ---|--- alert() | 弹出一个带有一段消息和确认按钮的窗体 confirm() | 显示带有一段消息以及确认按钮盒取消按钮的对话框 prompt() | 显示可提示用户输入的对话框 focus() | 把键盘焦点给予一个窗口 blur() | 把键盘焦点从顶层窗口移开 open() | 打开一个新的浏览器窗体 close() | 关闭浏览器窗口 forward() | 模拟用户点击浏览器上的“前进”按钮,将页面转到浏览器的下一页 back() | 模拟用户点击浏览器上的“后退”按钮,将页面转到浏览器的上一页 home() | 模拟用户点击浏览器上的“主页”按钮,将页面转到指定的页面上 stop() | 模拟用户点击浏览器上的“停止”按钮,终止浏览器的下载操作 print() | 模拟用户点击浏览器上的“打印”按钮,通知浏览器打开打印对话框打印当前页 resizeBy() | 按照指定的像素调整窗口的大小 resizeTo() | 把窗体的大小调整到指定的宽度和高度 moveBy() | 可相对窗口的当前坐标移动指定的像素 moveTo() | 把窗口的左上角移动到一个指定的坐标 scrollBy() | 按照指定的像素值来滚动内容 scrollTo() | 把内容滚动到指定的坐标 setInterval() | 按照指定的周期(毫秒)来调用函数或计算表达式 setTimeout() | 在指定的毫秒数后调用函数或表达式 clearInterval() | 取消由setInterval()设置的timeout clearTimeout() | 取消由setTimeout()方法设置的timeout 计时器: ``` <script> var timer = null; function printTime () { var d = new Date(); var h= d.getHours(); var m= d.getMinutes(); var s= d.getSeconds(); document.getElementById("time").innerHTML = h + ":" + m+ ":" + s; } function begin () { timer = setInterval(printTime,1000) } function pause () { clearInterval(timer) } </script> <div id="time"></div> <button onclick='begin()'>开始</button> <button onclick='pause()'>暂停</button> ``` #### (二) window的子对象 ##### 1. History 对象 History 对象包含用户(在浏览器窗口中)访问过的 URL **(1)对象属性:** 属性 | 描述 ---|--- length | 返回浏览器历史列表中的 URL 数量 state | 表示当前地址栏中网址对应的状态 **(2)对象方法:** 方法 | 描述 ---|--- history.back() | 回退一个地址,相当于浏览器的后退键;对第一个网址无效。 history.forward()| 前进一个地址,相当于浏览器的前进键;对最后一个网址无效。 history.go(n) | 当n>0时,前进n个历史记录;当n>history.length时,失效。当n=0时,go(0);刷新当前页面。当n<0时,后退n个历史记录;当n>history.length时,失效。 history.pushState(state, title, url) | 可以改变当前地址栏的url,且在历史记录中添加一条;不会刷新页面。 history.replaceState(state, title, url) | 功能是修改history对象的当前记录。其他参数和pushState相同,不会刷新页面。 ##### 2. Location 对象 Location 对象包含有关当前 URL 的信息。 **(1)对象属性:** 属性 | 描述 ---|--- hash | 设置或返回从井号 (#) 开始的 URL(锚)。 host | 设置或返回主机名和当前 URL 的端口号。 hostname | 设置或返回当前 URL 的主机名。 href | 设置或返回完整的 URL。 pathname| 设置或返回当前 URL 的路径部分。 port | 设置或返回当前 URL 的端口号。 protocol | 设置或返回当前 URL 的协议。 search| 设置或返回从问号 (?) 开始的 URL(查询部分)。 url 地址解析: ``` function getQueryString (name) { const reg = new RegExp('(^|&)' + name + '=([^&]*)(&|$)', 'i') const r = window.location.search.substr(1).match(reg) if (r != null) return (r[2]) return null } function createQueryString (data) { let dataStr = ''; Object.keys(data).forEach(key => { dataStr += key + '=' + data[key] + '&'; }) dataStr = dataStr.substr(0, dataStr.lastIndexOf('&')); return dataStr; } function parseQueryString () { let obj = {}; const temp = window.location.search.substr(1).split('&') || []; for (let item of temp) { obj[item.split('=')[0]] = item.split('=')[1] } return obj; } ``` **(2)对象方法:** 方法 | 描述 ---|--- assign() | 加载新的文档。 reload() | 重新加载当前文档。 replace() | 用新的文档替换当前文档。 ##### 3. Navigator 对象 Navigator 对象包含有关浏览器的信息。 **(1)对象属性:** 属性 | 描述 ---|--- appCodeName | 返回浏览器的代码名。 appMinorVersion | 返回浏览器的次级版本。 appName | 返回浏览器的名称。 appVersion | 返回浏览器的平台和版本信息。 browserLanguage | 返回当前浏览器的语言。 cookieEnabled | 返回指明浏览器中是否启用 cookie 的布尔值。 cpuClass | 返回浏览器系统的 CPU 等级。 onLine | 返回指明系统是否处于脱机模式的布尔值。 platform | 返回运行浏览器的操作系统平台。 systemLanguage| 返回 OS 使用的默认语言。 userAgent | 返回由客户机发送服务器的 user-agent 头部的值。 userLanguage | 返回 OS 的自然语言设置。 判断浏览器: ``` function goPage() { if ((navigator.userAgent.match(/(phone|pad|pod|iPhone|iPod|ios|iPad|Android|Mobile|BlackBerry|IEMobile|MQQBrowser|JUC|Fennec|wOSBrowser|BrowserNG|WebOS|Symbian|Windows Phone)/i))) { window.location.href="你的手机版地址"; } else { window.location.href="你的电脑版地址"; } } function judgeSystem () { var value if (ua.match(/phone|pad|pod|iPhone|iPod|ios|iPad/i)) { value = 'ios' } else if (ua.match(/Android/i)) { value = 'android' } return value } function isMobile () { if ((navigator.userAgent.match(/(phone|pad|pod|iPhone|iPod|ios|iPad|Android|Mobile|BlackBerry|IEMobile|MQQBrowser|JUC|Fennec|wOSBrowser|BrowserNG|WebOS|Symbian|Windows Phone)/i))) { return true } else { return false } } function isWeixin () { var ua = navigator.userAgent.toLowerCase(); return /micromessenger/i.test(ua) === true; } ``` **(2)对象方法:** 方法 | 描述 ---|--- javaEnabled() | 规定浏览器是否启用 Java。 taintEnabled() | 规定浏览器是否启用数据污点 (data tainting)。 ##### 4. Screen 对象 Screen 对象包含有关客户端显示屏幕的信息。 **(1)对象属性:** 属性 | 描述 ---|--- availHeight | 返回显示屏幕的高度 (除 Windows 任务栏之外)。 availWidth | 返回显示屏幕的宽度 (除 Windows 任务栏之外)。 width | 返回显示器屏幕的宽度。 height | 返回显示器屏幕的高度。 bufferDepth | 设置或返回调色板的比特深度。 colorDepth | 返回目标设备或缓冲器上的调色板的比特深度。 deviceXDPI | 返回显示屏幕的每英寸水平点数。 deviceYDPI | 返回显示屏幕的每英寸垂直点数。 fontSmoothingEnabled | 返回用户是否在显示控制面板中启用了字体平滑。 logicalXDPI | 返回显示屏幕每英寸的水平方向的常规点数。 logicalYDPI | 返回显示屏幕每英寸的垂直方向的常规点数。 pixelDepth | 返回显示屏幕的颜色分辨率(比特每像素)。 updateInterval | 设置或返回屏幕的刷新率。 ## 二、DOM ### 1、定义 DOM(文档对象模型)描述了处理网页内容的方法和接口,是HTML和XML的API,DOM把整个页面规划成由节点层级构成的文档。 ### 2、结构 **HTML DOM 树形结构:** ![](http://nhfcloms-deveopler.oss-cn-beijing.aliyuncs.com/dwwb/portal/project/1635153358333/02.png) ### 3、DOM对象用法小结 #### (1)查找节点 ##### 直接查找: - document.getElementById() &emsp;根据ID获取一个标签 - document.getElementsByClassName() &emsp;根据class属性获取(可以获取多个元素,所以返回的是一个数组) - document.getElementsByTagName() &emsp;根据标签名获取标签合集 ``` <div class="c1" id="d1"> 待到将军归来日,朕与将军解战袍! </div> <div class="c1" id="d2"> 日照香炉生紫烟,遥看瀑布挂前川! </div> var a = document.getElementById('d1'); //获取id属性值为d1的标签 拿到的直接是标签对象 var b = document.getElementsByClassName('c1'); //获取class值为c1的所有标签 拿到的是数组 var c = document.getElementsByTagName('div'); //获取所有div标签 拿到的是数组 ``` ##### 间接查找: - dom.parentElement &emsp;获取节点标签的父级标签 - dom.children &emsp;获取所有子标签 - dom.firstElementChild &emsp;获取第一个子标签元素 - dom.lastElementChild &emsp;获取最后一个子标签元素 - dom.nextElementSibling &emsp;获取下一个兄弟标签元素 - dom.previousElementSibling &emsp;获取上一个兄弟标签元素 ``` <div class="parent"> <span class="c1" id="d1"> 待到将军归来日,朕与将军解战袍! </span> <p class="c1" id="d2"> 日照香炉生紫烟,遥看瀑布挂前川! </p> </div> var a = document.getElementById('d1'); var b = document.getElementsByClassName('c1')[0]; var c = document.getElementsByClassName('c1')[1]; var d = document.getElementsByTagName('div')[0]; var p = document.getElementsByClassName('parent')[0]; console.log(a.parentElement.nodeName); // "DIV" console.log(Array.from(p.children).map(function(v){ return v.nodeName })); // ["SPAN", "P"] console.log(d.firstElementChild.nodeName); // "SPAN" console.log(d.lastElementChild.nodeName); // "P" console.log(b.nextElementSibling.nodeName); // "P" console.log(c.previousElementSibling.nodeName); // "SPAN" ``` #### (2)节点操作 - dom.createElement() &emsp;创建节点 - dom.appendChild() &emsp;在元素末尾插入节点 - dom.insertBefore() &emsp; 在某个节点之前插入节点 - dom.removeChild() &emsp;删除节点 - dom.replaceChild() &emsp;替换节点 ``` //动态创建script标签 function loadScriptString(code) { var script = document.createElement('script'); //创建一个script标签 script.type = 'text/javascript'; // script.setAttribute('src', ''); try { //IE浏览器认为script是特殊元素,不能再访问子节点;报错; script.appendChild(document.createTextNode(code)); } catch (ex) { script.text = code; } document.getElementsByTagName('head')[0].appendChild(script); } window.onload = function () { loadScriptString("alert('Hello World!!!')"); } ``` #### (3)文本操作 - dom.innerText &emsp;获取标签的文本内容 - dom.innerHTML &emsp;获取标签内的所有内容,包括文本和标签 #### (4)属性操作 - dom.setAttribute() &emsp;设置属性 - dom.getAttribute() &emsp;获取属性 - dom.removeAttribute() &emsp;删除属性 #### (5)值操作 - dom.value &emsp;获取值 - dom.value = ' ' &emsp;设置值 #### (6)class的操作 - dom.classList &emsp;获得这个标签的class属性的所有的值 - dom.classList.add() &emsp;添加class值 - dom.classList.remove() &emsp;删除class值 - dom.classList.contains() &emsp;判断是否含有有某个class值,有返回true,没有返回false - dom.classList.toggle() &emsp;切换class,有就删除,没有就增加 ``` const u = {}; u.isElement = function(obj){ return !!(obj && obj.nodeType == 1); }; u.hasCls = function(el, cls){ if(!u.isElement(el)){ console.warn('$api.hasCls Function need el param, el param must be DOM Element'); return; } if(el.classList.contains(cls)){ return true; }else{ return false; } }; u.addCls = function(el, cls){ if(!u.isElement(el)){ console.warn('$api.addCls Function need el param, el param must be DOM Element'); return; } if('classList' in el){ el.classList.add(cls); }else{ var preCls = el.className; var newCls = preCls +' '+ cls; el.className = newCls; } return el; }; u.removeCls = function(el, cls){ if(!u.isElement(el)){ console.warn('$api.removeCls Function need el param, el param must be DOM Element'); return; } if('classList' in el){ el.classList.remove(cls); }else{ var preCls = el.className; var newCls = preCls.replace(cls, ''); el.className = newCls; } return el; }; u.toggleCls = function(el, cls){ if(!u.isElement(el)){ console.warn('$api.toggleCls Function need el param, el param must be DOM Element'); return; } if('classList' in el){ el.classList.toggle(cls); }else{ if(u.hasCls(el, cls)){ u.removeCls(el, cls); }else{ u.addCls(el, cls); } } return el; }; ``` #### (7)css操作 - dom.style.backgroundColor - dom.style.height 注:有横杠的css属性,写法要去掉横杠,并且横杠后面的单词首字母大写 #### (8)事件 ``` onclick 当用户点击某个对象时调用的事件句柄。 ondblclick 当用户双击某个对象时调用的事件句柄。 onfocus 元素获得焦点。 应用场景:输入框 onblur 元素失去焦点。 应用场景:用于表单验证,用户离开某个输入框时,代表已经输入完了,我们可以对它进行验证 onchange 域的内容被改变。 应用场景:通常用于表单元素,当元素内容被改变时触发(select联动) onkeydown 某个键盘按键被按下。 应用场景: 当用户在最后一个输入框按下回车按键时,表单提交. onkeypress 某个键盘按键被按下并松开。 onkeyup 某个键盘按键被松开。 onload 一张页面或一幅图像完成加载。 onmousedown 鼠标按钮被按下。 onmousemove 鼠标被移动。 onmouseout 鼠标从某元素移开。 onmouseover 鼠标移到某元素之上。 onselect 在文本框中的文本被选中时发生。 onsubmit 确认按钮被点击,使用的对象是form。 ``` onblur和onfocus事件 ``` <input type="text" id="username" /> var inp = document.getElementById('username'); inp.onfocus = function () { this.style.backgroundColor = '#f00'; } inp.onblur = function () { this.style.backgroundColor = '#00f'; } ``` onchange事件,域内容发生变化时触发 ``` <input type="text" id="username" /> <select name="" id="book"> <option value="1">论语</option> <option value="2">大学</option> <option value="3">中庸</option> <option value="4">孟子</option> </select> var inp = document.getElementById('username'); var s = document.getElementById('book'); s.onchange = function () { inp.value = this.options[this.selectedIndex].innerText; } ```