美文网首页
DOM&BOM个人笔记

DOM&BOM个人笔记

作者: Peter_2B | 来源:发表于2021-11-02 14:14 被阅读0次

    https://developer.mozilla.org/zh-CN/docs/Web/JavaScript

    • DOM (Document Object Model): 文档对象模型, 通过DOM可以改变页面内容、结构和样式.
    var ele = document.getElementById('box');
    console.log(ele);           标签元素
    console.log(typeof ele)     object
    consoe.dir( ele )           直接查看元素对象的属性和方法
    
    document.documentElement    // <html>
    document.head               // <head>  
    document.body               // <body>
    
    • 获取元素节点
    • ul.children[1]
    • liTwo.parentNode;
    <ul id="ul-box">
      <li>1</li>
      <li>2</li>
      <li>3</li>
    </ul>
    
    <script>
    document.getElementById('ul-box');
    document.getElementsByTagName('ul-box')[0];
    document.getElementsByClassName('ul')[0];
    
    document.querySelector('#ul-box');   // h5
    document.querySelectorAll('li);      // h5
    
    
    // 利用节点的树结构 获取元素节点------------------------------
    
    
    var ul = document.getElementById('ul-box');
    ul.children[1];
    ul.firstElementChild;
    ul.lastElementChild;
    
    var liTwo = document.getElementsByTagName('li')[1];
    liTwo.previousElementSibling
    liTwo.nextElementSibling;
    liTwo.parentNode; == liTwo.parentElement;          
    
    
    // ------------------------------------------------------------
    
    
    nodeType:  9-document; 1-element; 2-attribute; 3-text(文本&空格); 8-comment(注释);
    console.log( ul.firstElementChild.nodeType );  
    console.log( ul.firstElementChild.nodeName );  
    </script>
    

    注意: elem.style.width 只能获取内联样式,无法获取外部样式

    var btn = document.getElementById('btn');
    var img = ele.getElementByClassName('img')[0];
    var inp = document.querySelector('input');
    var check = document.getElementById('checkbox');
    
    btn.onclick = function(){
      this.style.backgroundColor = 'orange';
      this.className = 'btn btn-orange';
    
      img.src = './img/1.png';
      img.alt = '这是一张图片';
    
      inp.type = 'password';
      inp.value = '123456';
      inp.disable = true;
      
      check.checked = !check.checked;
    
      this.innerHTML = `<span>123</span>`; //1.可赋值html标签,2.空格和3.换行
      this.innerText = '你好';             // 只有文本
    }
    
    • 获取标签上所有属性
    <input type="text" v-model="msg">
    
    var inp = document.querySelector('input');
    console.log( inp.attributes );  // { 0: type, 1: v-model }
    //console.log(inp.nodeValue );
    
    • 获取/修改/移除 标签上属性 \ 自定义属性data
    <div id="box" class="bg" data-index="1" data-list-name="hh"> hello </div>
    
    <script>
      var box = document.getElementById('box');
    
      1.元素本身的属性可直接获取
      console.log(box.id);
    
      2.存取class 需使用 className
      if(box.className == 'bg'){
        box.className = 'change-bg'
      }
    
      3.或
      console.log( box.getAttribute('id') );
    
      H5元素规定自定义属性 data- 开头作为自定义属性名
    
      //获取自定义的属性
      if(box.getAttribute('data-index') == 1){
          box.setAttribute('data-index', 2); 
    
          H5新增 定义属性dataset集合, 不再需要前缀data- ;   (ie 11才支持) 
          console.log( box.dataset.listName); 
      }else{
          box.removeAttribute('data-index');
      }
    </script>
    
    • 克隆节点
    var ul = document.querySelector('ul');
    
    //node.cloneNode(false); 不传参或传false-浅拷贝, true-深拷贝
    //1.复制节点,2.复制里面的所有子节点;
    
    var li = ul.children[0].cloneNode();
    ul.appendChild(li);
    
    • 创建/插入节点
    <ul>
        <li>2</li>
    </ul>
    
    
    var li = document.reateElement('li');
    var ul = document.getSelector('ul');
    
    li.innerHTML = '1';
    ul.appendChild(li);
    ul.insertBefore( li, ul.chidren[0] );
    ul.removeChild( ul.children[1] );
    
    var tbody = document.querySelector('tbody');
    
    for(var i = 0; i < datas.length; i++){
      var tr = document.createElement('tr');
          tbody.appendChild(tr);
          
          var row =  datas[i];
          for(var k in row){
              var td = document.createElement('td');
              td.innerHTML = `<a href="javascript:;"> ${row[k]} </a>`;
              tr.appendChild(td);
          }
    }
    
    var as = document.querySelectorAll('a');
    for(var i = 0; i < as.length; i++){
    
        as[i].onclick = function(){
    
            tbody.removeChild(this.parentNode.parentNode);  // this-a标签, .parent-td, .parent-tr;
        }
    }
    
    • fragment 文档片段:
      每次使用appendChild( ), Dom树会重新绘制, 浏览器都会重新渲染页面。频繁更新DOM节点,会非常消耗内存,影响用户体验;

      把所有需要构造的 节点都放到文档片段中执行,这样可以不影响文档树,也不会造成页面渲染。
      当节点都构造完成后, 再将文档片段对象 添加到页面中, 一次性渲染出来, 减少浏览器负担,提高渲染速度;

    var f = document.createDocumentFragment();
    
    for(var i = 0; i < 3; i++){
        var p = document.createElement('p');
            p.innerHTML = i;
        f.appendChild(p);
    }
    
    父元素.appendChild(f);
    
    • 移除事件
    elem.onclick = null    
    or    
    elem.removeEventListener("事件名", 原处理函数)      
    
    • 事件流 -- 捕获&冒泡


    <div class="father">
        <div class="son"></div>
    </div>
    
    <script>
    var father = document.querySelector('.father');
    var son = document.querySelector('.son');
    
    son.addEventListener('click', function(e){
        alert('false/省略 是冒泡');
        e.preventDeafult()                   // 阻止默认事件;
        window.event.returnValue;            // ie 6/7/8阻止默认事件
    
        e.stopProgagation()                  // 阻止冒泡;
        window.event.cancelBubble = true;    // ie 6/7/8阻止冒泡
    }, false);
    
    
    father.addEventListener('click', function(e){
        alert('true 是捕获');
        console.log(e.type);                     // click 点击事件名字
        var e = e || window.event;               // ie 6/7/8需要(了解);
        var target = e.target || e.srcElement;   // ie 6/7/8需要(了解);
    
    }, true);
    
    </script>
    
    • 事件委托/事件代理
    var ul = document.querySelector('ul');
    ul.addEventListener('click', function(e){
        var allNodes = this.children;
        for(var i of allNodes){
            i.style.background = '#fff';
        }
        var currentNode = e.target;
        currentNode.style.background = 'yellow';
    })
    
    • 键盘事件对象
    document.addEventListener('keydown',function(e){
        console.log(e.keyCode);
    });
    document.addEventListener('keypress',function(e){
        console.log(功能键(ctrl,shift,↑↓↔)无法触发'keypress');
    });
    document.addEventListener('keyup',function(e){
        console.log('keydown & keyup 无法区分大小写;  keypress可识别');
    });
    
    • 鼠标事件
    // 禁用右键菜单(了解)
    document.addEventListener('contextmenu', function(e){
        e.preventDefault();
    })
    
    // 禁用选中文字(了解)
    document.addEventListener('selectstart', function(e){
        e.preventDefault();
    })
    
    • 鼠标事件对象
      注意:鼠标返回距离和绑定事件的元素无关
    document.addEventListener('click', function(event){
        // 返回鼠标相对于最近元素的偏移距离;
        console.log(event.offsetX);
    
        // 返回鼠标相对于浏览器窗口的可视区域(不包括scroll滚出部分); 
        console.log(event.clientX);
    
        // 返回鼠标相对于文档页面的距离(包括scroll滚出部分);
        console.log(event.pageX);
    
        // 返回相对于电脑屏幕的距离(了解)
        console.log(event.screenX);
    })
    

    • 元素偏移量 .offsetLeft .offsetTop;
      获取某元素相对于最近父级定位元素的坐标, 否则相对于body

    • offsetWidth (width + 左右padding + 左右border)

      • 包含了可能会出现滚动条的宽高;
    • clientWidth (width + 左右padding)

      1. 只有可视区域,不会计算出现的滚动条的宽高;
    • scrollWidth (width + 左右padding)

      1. 内容大小没有超出元素大小时,也就是没有滚动条时 = clientWidth;
      2. 注意:会包含父元素设置了超出了边界而隐藏的宽度
    var div = document.querySelector('div');
        div.offsetLeft /  div.offsetTop;
    
    元素border宽度: div.clientLeft / clientTop;    
    
    console.log('左滚动的距离:', box.scrollLeft);  
    console.log('下滚动的距离:', box.scrollTop); 
    
    // 获取元素尺寸:
    offsetWidth / offsetHeight:  width + 左右padding + 左右border;
    clientWidth / clientHeight:  width + 左右padding;
    scrollWidth / scrollHeight:  width + 左右padding;   (内容大小没有超出元素大小也就和clientWidth一样);
    
    获取带有定位的父级元素,否则相对于body元素
    console.log(div.offsetParent)    // <body></body>
    
    不管父级有没有定位,返回最近的父级元素
    console.log(div.parentNode)
    
    scrollWidth

    元素偏移量 & style区别:

    • 图片跟随鼠标移动
    var pic = document.querySelector('img');
    
    document.addEventListener('mousemove', function(e){
        var x = e.pageX;
        var y = e.pageY;
    
        var width = pic.offsetWidth;
        var height = pic.offsetHeight;
    
        pic.style.left = x - width/2 + 'px';
        pic.style.top = y - height/2 + 'px';
    })
    
    • 求鼠标点击位置距离box元素多有像素
    <style type="text/css">
        *{
            margin: 0;
            padding: 0;
        }
        div{
            width: 100px;
            height: 100px;
            border: 2px solid orange;
            margin: 100px;
        }
    </style>
    <script type="text/javascript">
    
    var box = document.querySelector('div');
    
    box.addEventListener('click', function(e){
        var e = e || window.event;
    
        var x = e.pageX - this.offsetLeft;
        var y = e.pageY - this.offsetTop;
    
        console.log('x:', x, 'y:', y);
    })
    </script>
    
    求鼠标点击位置距离box元素多有像素
    • 求出当前元素在页面的偏移量
        <style type="text/css">
            *{
                margin: 0;
                padding: 0;
            }
            .grandfather{
                width: 300px;
                height: 300px;
                border: 10px solid #ccc;
                left: 50px;
                position: absolute;
            }
            .father{
                width: 200px;
                height: 200px;
                border: 10px solid green;
                margin-left: 50px;
                position: relative;
            }
            .son{
                width: 100px;
                height: 100px;
                border: 10px solid orange;
                margin-left: 50px;
            }
        </style>
    <script type="text/javascript">
    
    var son = document.querySelector('.son');
    console.log(son.offsetLeft);
    console.log( getElementLeft(son) );
    
    function getElementLeft(eleObj){
        // 当前元素距有定位的父元素的左偏移量
        var currentLeft = eleObj.offsetLeft;
    
        // 找到当前元素有定位的父元素
        var parent = eleObj.offsetParent;
    
        // 最外层是/没有定位父级就是基于<body/>, body.offsetParent是null.
        while(parent != null){
            // 当前元素做偏移量 + 父元素的border-left + 父元素的左偏移量
            currentLeft = currentLeft + parent.clientLeft + parent.offsetLeft;
            console.log(parent);
            parent = parent.offsetParent;
        }
        return currentLeft;
    }
    </script>
    
    例如: box宽高100px, padding10px; 
    
    console.log('padding+width',box.scrollWidth); 
    
    box.addEventListener('scroll',function(){
        console.log(box.scrollTop);   // 滚出去内容的距离
    })
    

    • 滚动到一定距离就固定
    <script>
    var slidebar = document.querySelector('.slide-bar');
    var header = document.querySelector('.header');
    var goBack = document.querySelector('.go-back');
    
                  // css设置的距离500px高度 - header的高度100;
    var slidebarTop = slidebar.offsetTop - header.offsetHeight;
    
    document.addEventListener('scroll', function(){
    
        // console.log(window.scrollTop);   // undefined;
        console.log(window.pageYOffset);// 获取document滚出距离需用pageYOffset;
    
        if(window.pageYOffset >= header.offsetHeight){
            slidebar.style.position = 'fixed';
            slidebar.style.top = slidebarTop + 'px';
            goBack.style.display = 'block';
        }else{
            slidebar.style.position = 'absolute';
            slidebar.style.top = '500px';
            goBack.style.display = 'none';
    
        }
    })
    
    goBack.addEventListener('click',function(){
        window.scrollTo(0,0)
    });
    </script>
    
    <style type="text/css">
        *{
            margin: 0;
            padding: 0;
        }
        .header{
            width: 80%;
            height: 100px;
            background-color: pink;
            margin: 0 auto;
        }
        .wrapper{
            width: 80%;
            height: 1000px;
            background-color: yellowgreen;
            margin: 0 auto;
        }
        .slide-bar{
            width: 50px;
            height: 100px;
            background-color: orange;
            position: absolute;
            right: 20px;
            top: 500px;
        }
        .go-back{
            display: none;
        }
    </style>
    

    BOM
    • window.onload 窗口加载事件 - 当文档内容(图片, 脚本文件, css, 外部文件)完全加载完会触发该事件
    <head>
        <title></title>
        <script type="text/javascript">
        
        /*
        window.onload = function(){
            var btn = document.querySelector('button');
    
            btn.addEventListener('click', function(){
                console.log('最后的 window.onload 注册事件会覆盖以前的');
            })
        }
        */
    
        window.addEventListener('load',function(){
            var btn = document.querySelector('button');
    
            btn.addEventListener('click', function(){
                console.log('addEvent方式则不会');
            })
        })
    
        window.addEventListener('load',function(){
            alert(22)
        })
    
        document.addEventListener('DOMContentLoaded',function(){
            alert('DOMContentLoaded事件是 DOM加载完毕就执行')
        })
    </script>
    </head>
    <body>
    
    
      <button>btn</button>  
    
    
    </body>
    
    • window.onresize 窗口大小事件 - 窗口大小发生像素变化触发事件
      var div = document.querySelector('div');
    
      window.onresize = function(){
        if(window.innerWidth <= 800){  // 当前屏幕的宽度;
    
            div.style.display = 'none';
        }else{
            div.style.display = 'block';
        }
      }
    
    • setTimeout & setInterval 定时器

    • window.locatin: 解析/获取/设置访问的URL的对象

      属性:
           location.href        完整url
           location.protocol    http/https/tcp 协议
           location.host        主机名+端口号: 比如localhost:3000
           location.hostname    主机名: 比如localhost
           location.port        端口号: 3000
           location.pathname    相对路径
           location.hash        #锚点链接地址
           location.search      ?name=tom&password=123查询字符串
    
      方法: 
       location.assign("新url")  也可实现在当前窗口打开,可后退
       location.href="新url"
       location.replace("新url")  实现禁止后退      原理: 用新url替换history中旧的url
       
      刷新: 
       history.go(0) == location.reload()     1. 普通刷新: 优先从浏览器本地缓存中获取资源。缓存中没有或过期,才去服务器下载新的。
       location.reload(true)                  2. 强制刷新: 跳过浏览器缓存,总是从服务器下载最新的资源
    
    • window.navigator: 浏览器保存的配置信息对象
    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))){
        console.log('手机');
    }else{
        console.log('pc')
    }
    
    属性: 
     cookieEnabled: 判断当前浏览器是否启用了cookie。     
     plugins: 保存浏览器安装的所有插件信息的集合 
     userAgent: 保存浏览器名称和版本号的字符串
     geolocation: 该对象提供用户地理位置信息,通过getCurrentPosition获取;    navigator.geolocation.getCurrentPosition(position=>{ console.log('用户地理信息:', position) })
          latitude 维度    longitude 经度  accuracy经纬度精确度  altitude海拔高度 altitudeAccuracy海拔高度经度 heading设备方向 speed速度    
    
    • window.history: 保存当前窗口打开后,成功访问过的url的历史记录栈的对象
    history.forward()  ==  history.go(1) 前进一步
    history.back()   ==  history.go(-2) 后退两步
    history.go(0) 刷新
    

    相关文章

      网友评论

          本文标题:DOM&BOM个人笔记

          本文链接:https://www.haomeiwen.com/subject/pizhwltx.html