• 【前端知识体系-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

    1. document.getElementById :根据ID查找元素,大小写敏感,如果有多个结果,只返回第一个;
    2. document.getElementsByClassName :根据类名查找元素,多个类名用空格分隔,返回一个 HTMLCollection 。注意兼容性为IE9+(含)。另外,不仅仅是document,其它元素也支持 getElementsByClassName 方法;
    3. document.getElementsByTagName :根据标签查找元素, * 表示查询所有标签,返回一个 HTMLCollection 。
    4. document.getElementsByName :根据元素的name属性查找,返回一个 NodeList 。
    5. document.querySelector :返回单个Node,IE8+(含),如果匹配到多个结果,只返回第一个。
    6. document.querySelectorAll :返回一个 NodeList ,IE8+(含)。
    7. document.forms :获取当前页面所有form,返回一个 HTMLCollection ;

    节点创建API

    1. createElement创建元素
    2. createTextNode创建文本节点
    3. cloneNode 克隆一个节点
    4. createDocumentFragment

    节点修改API

    1. appendChild
    2. insertBefore
    3. insertAdjacentHTML
    4. Element.insertAdjacentElement()
    5. removeChild
    6. 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 跨域的几种实现方式以及底层的实现原理

    1. 服务器端的使用:response.setHeader(Access-Control-Allow-Origin, "http://www.baidu.com, http://www.52tech.tech")允许跨域
    2. 使用JSONP

    2.4.3 JSONP的实现原理

    [!NOTE]
    跨域:浏览器有同源策略,不允许ajax访问其他域接口

    • 跨域条件:协议、域名、端口,有一个不同就是跨域

    可以跨域加载资源的3个标签:

    <img src="">, <link href="">, <script src="">
    
    • img用途:主要用于打点统计,统计网站可能是其他域
    • link, script用途:可以使用CDN,可以使用其他域
    • script用途:可以用于JSONP

    2.4.3.1 跨域注意事项:

    1. 所有的跨域请求都必须经过信息提供方的允许才可以获取
    2. 如果未经允许就可以直接获取,就是浏览器的同源策略出现漏洞

    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 本地存储

    1. 存储量,只有4kb
    2. 所有的http请求都会带有cookie,会直接影响获取资源效率
    3. API,document.cookie

    localstorage

    1. localstorage.setItem(key, value);localstorage.getItem('key');
    2. 存储量5MB
    3. sessionStorage:会话级别

    [!WARNING]
    【坑】IOS safari的隐藏模式下,使用localStorage.getItem('key') 会报错,建议使用try{}catch(e){} 来实现可以防止报错

  • 相关阅读:
    第12月第30天 love2d
    第12月第29天 cocos quick manual
    cpu test
    learning armbian steps(10) ----- armbian 源码分析(五)
    Linux command nmon
    learning ddr Electrical Characteristics and AC Timing
    learning ddr tRP and tRP tRTP CL tRAS
    进入Windows之前发出警告
    向系统日志 写入自定义数据
    创建并写入自定义日志信息
  • 原文地址:https://www.cnblogs.com/fecommunity/p/11908767.html
Copyright © 2020-2023  润新知