【前端知识体系-JS相关】JS-Web-API总结
2.1 dom操作
2.1.1 dom的本质是什么?
<!-- dom树:二叉树 --> /* <?xml version="1.0" encoding="utf-8"> // 告诉浏览器以哪一种类型进行解析 <node> <child /> </node> */ <!doctype html> // 以html类型进行解析文档内容 <html> <body> </body> </html>
2.1.2 dom操作的常用api有哪些?
节点查找api
- document.getelementbyid :根据id查找元素,大小写敏感,如果有多个结果,只返回第一个;
- document.getelementsbyclassname :根据类名查找元素,多个类名用空格分隔,返回一个 htmlcollection 。注意兼容性为ie9+(含)。另外,不仅仅是document,其它元素也支持 getelementsbyclassname 方法;
- document.getelementsbytagname :根据标签查找元素, * 表示查询所有标签,返回一个 htmlcollection 。
- document.getelementsbyname :根据元素的name属性查找,返回一个 nodelist 。
- document.queryselector :返回单个node,ie8+(含),如果匹配到多个结果,只返回第一个。
- document.queryselectorall :返回一个 nodelist ,ie8+(含)。
- document.forms :获取当前页面所有form,返回一个 htmlcollection ;
节点创建api
- createelement创建元素
- createtextnode创建文本节点
- clonenode 克隆一个节点
- createdocumentfragment
节点修改api
- appendchild
- insertbefore
- insertadjacenthtml
- element.insertadjacentelement()
- removechild
- replacechild
节点关系api
- 1、父关系api
parentnode :每个节点都有一个parentnode属性,它表示元素的父节点。element的父节点可能是element,document或documentfragment;
parentelement :返回元素的父元素节点,与parentnode的区别在于,其父节点必须是一个element元素,如果不是,则返回null;
- 2、子关系api
children :返回一个实时的 htmlcollection ,子节点都是element,ie9以下浏览器不支持;
childnodes :返回一个实时的 nodelist ,表示元素的子节点列表,注意子节点可能包含文本节点、注释节点等;
firstchild :返回第一个子节点,不存在返回null,与之相对应的还有一个 firstelementchild ;
lastchild :返回最后一个子节点,不存在返回null,与之相对应的还有一个 lastelementchild ;
- 3、兄弟关系型api
previoussibling :节点的前一个节点,如果不存在则返回null。注意有可能拿到的节点是文本节点或注释节点,与预期的不符,要进行处理一下。
nextsibling :节点的后一个节点,如果不存在则返回null。注意有可能拿到的节点是文本节点,与预期的不符,要进行处理一下。
previouselementsibling :返回前一个元素节点,前一个节点必须是element,注意ie9以下浏览器不支持。
nextelementsibling :返回后一个元素节点,后一个节点必须是element,注意ie9以下浏览器不支持。
元素属性型api
1、setattribute 给元素设置属性:
2、getattribute
3、hasattribute
样式操作api(面试考点)
- 1、直接修改元素的样式
elem.style.color = 'red'; elem.style.setproperty('font-size', '16px'); elem.style.removeproperty('color');
- 2、动态添加样式规则
var style = document.createelement('style'); style.innerhtml = 'body{color:red} #top:hover{background-color: red;color: white;}'; document.head.appendchild(style);
-
3、classlist获取样式属性
[!note]
了解dom节点样式(classlist)的remove, add, toggle, contains, replace等方法的使用。 4、window.getcomputedstyle
通过 element.sytle.xxx 只能获取到内联样式,借助 window.getcomputedstyle 可以获取应用到元素上的所有样式,ie8或更低版本不支持此方法。
var style = window.getcomputedstyle(element[, pseudoelt]);
2.1.3 dom节点的attr和proerty的区别
// 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标签上面的属性信息
2.2 bom操作
2.2.1 如何检测浏览器的类型?
var ua = navigator.useragent; var ischrome = ua.indexof('chrome'); console.log('is chrome?', ischrome > 0, navigator.useragent); console.log('电脑屏幕大小:', screen.width, screen.height)
2.2.2 如何拆解url的各个部分?
// 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); // #后面的内容(包括#)
2.3 事件操作
2.3.1 编写一个通用的事件监听函数
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); } }); }
2.3.2 描述事件冒泡的流程
[!note]
"dom2级事件”规定的事件流包含三个阶段:事件捕获阶段,处于目标阶段和事件冒泡阶段。首先发生的是事件捕获,然后是实际的目标接收到事件,最后阶段是冒泡阶段。
- 事件冒泡:
按照dom树形结构向上冒泡(p --- >>> div --- >>> body --- >>> document),- 事件捕获
(document—>—>—>的顺序进行传播的)
2.3.3 对于一个无线下拉图片的页面,如何给每一个图片绑定一个事件
// 代理(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) } })
2.4 ajax操作
2.4.1 手动编写一个ajax,不依赖第三方库
2.4.2 跨域的几种实现方式以及底层的实现原理
- 服务器端的使用:response.setheader(access-control-allow-origin, "http://www.baidu.com, http://www.52tech.tech")允许跨域
- 使用jsonp
2.4.3 jsonp的实现原理
[!note]
跨域:浏览器有同源策略,不允许ajax访问其他域接口
- 跨域条件:协议、域名、端口,有一个不同就是跨域
可以跨域加载资源的3个标签:
<img src="">, <link href="">, <script src="">
- img用途:主要用于打点统计,统计网站可能是其他域
- link, script用途:可以使用cdn,可以使用其他域
- script用途:可以用于jsonp
2.4.3.1 跨域注意事项:
- 所有的跨域请求都必须经过信息提供方的允许才可以获取
- 如果未经允许就可以直接获取,就是浏览器的同源策略出现漏洞
2.4.3.2 浏览器端实现(提前定义一个回调函数)
//封装一个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) }) }
2.4.3.3 后端实现
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})`) } })
2.5 本地存储
2.5.1 cookie, sessionstorage, localstorage 的区别
cookie
- 存储量,只有4kb
- 所有的http请求都会带有cookie,会直接影响获取资源效率
- api,document.cookie
localstorage
- localstorage.setitem(key, value);localstorage.getitem('key');
- 存储量5mb
-
sessionstorage:会话级别
[!warning]
【坑】ios safari的隐藏模式下,使用localstorage.getitem('key') 会报错,建议使用try{}catch(e){} 来实现可以防止报错
上一篇: CSS字体属性