<!-- DOM树:二叉树 --> /* <?xml version="1.0" encoding="UTF-8"> // 告诉浏览器以哪种类型进行解析 <node> <child /> </node> */ <!DOCTYPE html> // 以html类型进行解析文档内容 <html> <body> </body> </html>
parentNode :每一个节点都有一个parentNode属性,它表示元素的父节点。Element的父节点多是Element,Document或DocumentFragment;
parentElement :返回元素的父元素节点,与parentNode的区别在于,其父节点必须是一个Element元素,若是不是,则返回null;html
children :返回一个实时的 HTMLCollection ,子节点都是Element,IE9如下浏览器不支持;node
childNodes :返回一个实时的 NodeList ,表示元素的子节点列表,注意子节点可能包含文本节点、注释节点等;面试
firstChild :返回第一个子节点,不存在返回null,与之相对应的还有一个 firstElementChild ;ajax
lastChild :返回最后一个子节点,不存在返回null,与之相对应的还有一个 lastElementChild ;express
previousSibling :节点的前一个节点,若是不存在则返回null。注意有可能拿到的节点是文本节点或注释节点,与预期的不符,要进行处理一下。json
nextSibling :节点的后一个节点,若是不存在则返回null。注意有可能拿到的节点是文本节点,与预期的不符,要进行处理一下。后端
previousElementSibling :返回前一个元素节点,前一个节点必须是Element,注意IE9如下浏览器不支持。api
nextElementSibling :返回后一个元素节点,后一个节点必须是Element,注意IE9如下浏览器不支持。跨域
一、setAttribute 给元素设置属性:
二、getAttribute
三、hasAttribute浏览器
elem.style.color = 'red'; elem.style.setProperty('font-size', '16px'); elem.style.removeProperty('color');
var style = document.createElement('style'); style.innerHTML = 'body{color:red} #top:hover{background-color: red;color: white;}'; document.head.appendChild(style);
三、classList获取样式属性
[!NOTE]
了解dom节点样式(classList)的remove, add, toggle, contains, replace等方法的使用。
四、window.getComputedStyle
经过 element.sytle.xxx 只能获取到内联样式,借助 window.getComputedStyle 能够获取应用到元素上的全部样式,IE8或更低版本不支持此方法。
var style = window.getComputedStyle(element[, pseudoElt]);
// proprty------>>>获取nodeName和nodeType(property实际上就是JS对象的一个属性)如:text : 3(#text), p : 1(p) console.log(pList[0].nodeName); // p console.log(pList[0].nodeType); // 1 // attribute------>>> 获取一个HTML标签的属性信息(设置和修改) var a = document.getElementsByTagName('a')[0]; console.log(a.getAttribute('data-origin')); console.log(a.getAttribute("href_name")); // 能够给一个HTML标签设置任意的属性名称,不管这个属性内部是否存在 a. setAttribute('sex', 'male') // 区别: // (JS对象&HTML标签)property其实是一个普通JS对象自己的基本属性,可是attribute其实是一个HTML标签上面的属性信息
[!NOTE]
区别:(JS对象&HTML标签)property其实是一个普通JS对象自己的基本属性,可是attribute其实是一个HTML标签上面的属性信息
var ua = navigator.userAgent; var isChrome = ua.indexOf('Chrome'); console.log('is Chrome?', isChrome > 0, navigator.userAgent); console.log('电脑屏幕大小:', screen.width, screen.height)
// location console.log(location.href); // 完整的url地址,http://localhost:8080/JS-Professional/begin/02-%E5%9F%BA%E7%A1%80%E8%BF%9B%E9%98%B6/01-%E4%BB%8E%E5%9F%BA%E7%A1%80%E5%88%B0%E8%BF%9B%E9%98%B6.html?_ijt=i8ctmkc87dvh03tdaf51rn5v1i console.log(location.protocol) // http/https console.log(location.host, location.hostname) // www.52tech.tech console.log(location.pathname); // host以后的所有内容,JS-Professional/begin/02-%E5%9F%BA%E7%A1%80%E8%BF%9B%E9%98%B6/01-%E4%BB%8E%E5%9F%BA%E7%A1%80%E5%88%B0%E8%BF%9B%E9%98%B6.html console.log(location.search); // search就是?以后的所有内容,?_ijt=i8ctmkc87dvh03tdaf51rn5v1i(包括?) console.log(location.hash); // #后面的内容(包括#)
function bindEvent(ele, type, selector, fn){ if (fn == null) { fn = selector; selector = null; } // addEventListener 的最后一个参数默认是false, 表示的是事件冒泡,自下向上去捕获事件,true:表示事件捕获,表示事件自外向里的方式 ele.addEventListener(type, function(e){ if (selector) { // 使用的是代理的方式的话 if (e.target.matches(selector)){ // 这里须要去判断当前点击的那个对象是否是我点击的那个对象 fn.call(e.target, e); } } else { // 不使用代理的话 fn(e); } }); } // 这里表示对这个div1 内部的全部的a标签使用事件冒泡 bindEvent(document.getElementById('div4'), 'click', 'p', function (e) { console.log(this.innerHTML + 'hahaah') }) 版本2: /** * 实现一个通用的事件绑定函数(代码简洁,减小了浏览器的占用) * @param element * @param type * @param selector * @param fn */ function bindEvent(element, type, selector, fn) { // if (fn === null || fn === undefined) // 这里能够直接优化为fn == null if (fn == null){ // 只有3个参数的话 fn = selector; selector = null; } element.addEventListener(type, function (e) { var target; // 若是selector有的话,说明此事element就是一个代理 if (selector) { target = e.target; // 若是当前的target知足这个选择器的话 // 若是元素被指定的选择器字符串选择,Element.matches() 方法返回true; 不然返回false。 // document.getElementById('div1').matches('div') true // matches里面的参数其实是一个HTML标签:a, p, div …………, 内容也是不区分大小写的,有点相似于nodeName 或者nodeType 这样的判断 if (target.matches(selector)){ // 修改this的指向 fn.call(target, e); } }else { fn(e); } }); }
[!NOTE]
"DOM2级事件”规定的事件流包含三个阶段:事件捕获阶段,处于目标阶段和事件冒泡阶段。首先发生的是事件捕获,而后是实际的目标接收到事件,最后阶段是冒泡阶段。
- 事件冒泡:
按照DOM树形结构向上冒泡(p --- >>> div --- >>> body --- >>> document),- 事件捕获
(document—>—>—>的顺序进行传播的)
// 代理(div3里面的全部a标签都须要进行事件的监听) var div3 = document.getElementById('div3'); bindEvent(div3, 'click', function (e) { e.preventDefault(); e.stopPropagation() // 能够获取真实触发的那个元素 var target = e.target; console.log(target.nodeName, target.nodeType); // 每一种页面标签实际上都有一个本身专属的nodeName // 这里的目的主要是用于过滤,只处理a标签的事件处理 if ('A' === target.nodeName) { // 若是当前点击的a标签就是本身 alert(target.innerHTML) } })
[!NOTE]
跨域:浏览器有同源策略,不容许ajax访问其余域接口
- 跨域条件:协议、域名、端口,有一个不一样就是跨域
能够跨域加载资源的3个标签:
<img src="">, <link href="">, <script src="">
//封装一个jsonp请求的函数 function query(opt) { let str = "" for (let key in opt) { str += key + "=" + opt[key] + "&" } return str } //设置默认回调函数的名字 const defaultOptions = { callbackName: "callback" } function jsonp(url, opt, options = defaultOptions) { //参数解析 URL为访问的接口 opt为传播的数据 option 为接受参数的回调函数 return new Promise((resolve, reject) => { //判断下这个?是否是存在 let index = url.indexOf("?"); url += index != -1 ? query(opt) : "?" + query(opt); url = url + `${options.callbackName}=${options.callbackName}`; //首先创造一个标签 带有src的 const scriptDom = document.createElement("script"); //设置其src属性 scriptDom.setAttribute("src", url); //在window系统上建立一个回调函数用来接受数据 window[options.callbackName] = (res) => { //在接受到了参数动态删除这个script节点和window上面的方法 delete window[options.callbackName]; document.body.removeChild(scriptDom) //接受成功后调用resolve if (res) { resolve(res) } else { reject("服务器暂没有获取到数据") } } //动态建立script标记,错误的监听 scriptDom.addEventListener('error', () => { delete window['jsonpCallback']; document.body.removeChild(script); reject('服务器加载失败!'); }); document.body.append(scriptDom) }) }
const url = require("url") router.get("/api", (req, res, next) => { //将script标签的src的URL请求转成对象 const opj = url.parse(req.url, true).query; //而后原理就是调用这个回调函数来进行传参 let { callback } = opj; //若是这个回调函数存在证实是jsonp请求 if (callback) { let resault = JSON.stringify({ code: 1, msg: "express框架传回去的参数" }); res.send(`${callback}(${resault})`) } })
sessionStorage:会话级别
[!WARNING] 【坑】IOS safari的隐藏模式下,使用localStorage.getItem('key') 会报错,建议使用try{}catch(e){} 来实现能够防止报错