助力软件开发企业降本增效 PHP / java源码系统,只需一次付费,代码终身使用! 广告
* JS 基础知识,规定语法 ECMA 262 标准 * JS Web API,网页操作的 API W3C 标准 ### DOM * DOM:Document Object Model * Vue 和 React 框架应用广泛,封装了 DOM 操作 #### DOM 节点操作 ```javascript const div1 = document.getElementById('div1') // 元素 const divLIst = document.getElementsByTagName('div') // 集合 const containerList = document.getElementsByClassName('.container') // 集合 const PList = document.querySelectorAll('p') // 集合 ``` **property:**修改 dom 结构的变量,不表现在 html 中 ```javascript const pList = document.querySelectorAll('p') const p1 = pList[0] // property 形式 p1.style.width = '100px' console.log(p1.style.width) p1.className = 'red' console.log(p1.className) ``` **attribute**:修改 dom 结构的属性,表现在 html 中 ```javascript const pList = document.querySelectorAll('p') const p = pList[0] p.getAttrbute('data-name') p.setAttribute('data-name','imooc') p.getAttribute('style') p.setAttribute('style','font-size:30px') ``` * property:修改对象属性,不会体现到 html 结构中 * attribute:修改 html 属性,会修改 html 结构 * 两者都有可能引起 DOM 重新渲染;优先选择 property #### DOM 结构操作 * 新增/插入节点 ```javascript const div1 = document.getElementById('div1') // 添加新节点 const p1 = document.createElement('p') p1.innerHTML = 'this is p1' div1.appendChild(p1) // 添加新创建的元素 // 移动已有节点。移动 const p2 = document.getElementById('p2') div1.appendChild(p2) ``` * 获取子元素列表、获取父元素 ```javascript // 获取子元素列表 const div1 = document.getElementById('div1') const child = div1.childNodes // 获取父元素 const div1 = document.getElementById('div1') const parent = div1.parentNode ``` * 删除节点 ```javascript const div1 = document.getElementById('div1') const child = div1.childNodes div1.removeChild(child[0]) ``` #### DOM 性能 * DOM 操作非常 “昂贵”,避免频繁的 DOM 操作 * DOM 查询作缓存 ![image-20210306115222530](https://image.mdashen.com/pic/image-20210306115222530.png) * 将频繁操作改为一次性操作 ![image-20210306115307526](https://image.mdashen.com/pic/image-20210306115307526.png) ### BOM * BOM:Browser Object Model #### navigator、screen ```javascript // navigator、浏览器标识 const ua = navigator.userAgent const isChrome = ua.indexOf('Chrome') console.log('isChrome') // screen 屏幕信息 screen.width screen.height ``` #### location、history ```javascript location.href // "https://coding.imooc.com/class/chapter/400.html#Anchor" location.protocol // 'https' location.pathname // '/class/chapter/400.html' location.search // url参数 location.hash // '#Anchor' // history history.back() // 后退 history.forward() // 前进 ``` ### 事件 #### 事件绑定 ```javascript const btn = document.getElementById('btn1') btn.addEventListener('click',event=>{ console.log('clicked') event.preventDefault() // 阻止默认行为 }) ``` #### 事件冒泡 * 基于 DOM 树形结构 * 事件会顺着触发元素向上冒泡 * 应用场景:事件代理 ```html <body> <div id="div1"> <p id="p1">激活</p> <p id="p2">取消</p> <p id="p3">取消</p> <p id="p4">取消</p> </div> <div id="div1"> <p id="p5">取消</p> <p id="p6">取消</p> </div> </body> <script> function bindEvent(elem, type, fn) { elem.addEventListener(type, fn) } const p1 = document.getElementById('p1') const body = document.body bindEvent(p1, 'click', (e) => { // e.stopPropagation() // 阻止冒泡;注释掉这一行,体会冒泡 alert('激活') }) bindEvent(body, 'click', (e) => { alert('取消') }) </script> ``` #### 事件代理 扩展阅读:[掘金:js中的事件委托或事件代理详解](https://juejin.cn/post/6844903589052153869) ![image-20210306191353215](https://image.mdashen.com/pic/image-20210306191353215.png) ### Ajax ```javascript // 手写一个简单的 ajax function ajax(url) { const p = new Promise((resolve, reject) => { const xhr = new XMLHttpRequest() xhr.open('GET', url, true) xhr.onreadystatechange = function () { if (xhr.readyState === 4) { if (xhr.status === 200) { resolve(JSON.parse(xhr.responseText)) } else { reject(new Error(xhr)) } } } xhr.send() }) return p } ``` #### XMLHttpRequest ```javascript // get 请求 const xhr = new XMLHttpRequest() xhr.open('GET', '/data/test.json', true) xhr.onreadystatechange = function () { if (xhr.readyState === 4) { if (xhr.status === 200) { alert(xhr.responseText) } } } xhr.send(null) // post 请求 const xhr = new XMLHttpRequest() xhr.open('POST', '/login', true) xhr.onreadystatechange = function () { if (xhr.readyState === 4) { if (xhr.status === 200) { alert(xhr.responseText) } } } const postData = { userName:'zhangsan', password:'xxx' } xhr.send(JSON.stringify(postData)) ``` ##### xhr.readySate * 0---未初始化,还没有调用 send() 方法 * 1---载入,已调用 send() 方法,正在发送请求 * 2---载入完成,sedn() 方法执行完成,已经接收到全部相应内容 * 3---交互,正在解析相应内容 * 4---完成,相应内容解析完成,可以在客户端调用 ##### xhr.status * http 状态码 * 2xx:表示成功处理请求,如 200 * 3xx:需要重定向,浏览器直接跳转,如 301 302 304 * 4xx:客户端请求错误,如 404 403 * 5xx:服务端错误 #### 跨域 ##### 同源策略 * ajax 请求时,**浏览器要求**当前网页和 server 必须同源(为了保证安全) * 同源:协议、域名、端口三者必须一致 * 加载图片 css js 可无视同源策略;img src、link href、script src ##### jsonp > JSONP是一种发送JSON数据而无需担心跨域问题的方法。 > > JSONP不使用该 `XMLHttpRequest` 对象。 > > JSONP使用 `<script>` 标记代替。 > > 由于跨域策略,从另一个域请求文件可能会导致问题。 > > 从另一个域请求外部脚本不会出现此问题。 > > JSONP利用了这一优势,并使用脚本标签而不是 `XMLHttpRequest` 对象来请求文件。 ```javascript // jQuery 实现 jsonp $.ajax({ url:'http://localhost:8882/x-origin.json', dataType:'jsonp', jsonCallback:'callback', success:function(data){ console.log(data) } }) ``` ##### CORS * 服务端设置 http header,服务端的设置 ```javascript // 跨域的域名称,不建议直接写 "*" response.setHeader('Access-Control-Allow-Origin', 'https://localhost:8011') response.setHeader('Access-Control-Allow-Headers', 'X-Requested-With') response.setHeader('Access-Control-Allow-Methods', 'PUT,POST,GET,DELETE,OPTIONS' ) // 接受跨域的 coolie response.setHeader("Access-Control-Allow-Credentials","true") ``` ### 存储 #### cookie * 本身用于浏览器和 server 通讯 * 被 ”借用“ 到本地存储来 * 可用 document.cookie = '...' 来修改 * 最大 4k * 默认跟随 http 请求,发送到服务器 #### localStorage 和 sessionStorage * HTML5 专门为存储而设计,最大可存 5M(每个域) * localStorage 数据会永久储存,触发代码或手动删除 * sessionStorage 数据只存在于当前会话,浏览器关闭则清空 * 一般用 localStorage 会更多一些