前端学习笔记JavaScript - DOM

DOM开篇

  • window

是一个全局对象,代表浏览器中一个打开的窗口,每个窗口都是一个window对象

  • document

document是window的属性,这个属性是一个对象

document代表当前窗口的整个网页

通过document就可以拿到网页上的所有内容

  • DOM (文档模型对象)

DOM 定义了访问和操作HTML的标准方法

学习DOM就是学习如何通过document操作网页上的内容

获取DOM元素

  • 通过id获取

由于id不可以重复, 所以找到了就会将找到的标签包装成一个对象返回给我们, 找不到就返回Null
注意点: DOM操作返回的是一个对象, 这个对象是宿主类型对象(浏览器提供的对象

    let oDiv = document.getElementById("box");
    console.log(oDiv);
    console.log(typeof oDiv);
  • 通过class获取

由于class可以重复, 所以找到了就返回一个存储了标签对象的数组, 找不到就返回一个空数组

    let oDivs = document.getElementsByClassName("father");
    console.log(oDivs);
  • 通过name获取

由于name可以重复, 所以找到了就返回一个存储了标签对象的数组, 找不到就返回一个空数组
注意点:
getElementsByName 在不同的浏览器其中工作方式不同。在IE和Opera中, getElementsByName() 方法还会返回那些 id 为指定值的元素。

    let oDivs = document.getElementsByName("test");
    console.log(oDivs);
  • 通过标签名称获取

由于标签名称可以重复, 所以找到了就返回一个存储了标签对象的数组, 找不到就返回一个空数组

    let oDivs =  document.getElementsByTagName("div");
    console.log(oDivs);
  • 通过选择器获取1(常用)

querySelector只会返回根据指定选择器找到的第一个元素

    // let oDiv = document.querySelector("#box");
    // let oDiv = document.querySelector(".father");
    let oDiv = document.querySelector("div>form");
    console.log(oDiv);
  • 通过选择器获取2(常用)

querySelectorAll会返回指定选择器找到的所有元素

    let oDivs = document.querySelectorAll(".father");
    console.log(oDivs);
  • 获取指定元素所有子元素

chiddren

chiddren获取到的是指定元素中的所有子元素

childNodes

childNodes属性获取到的是指定元素中所有的节点

节点

DOM对象(document), 这个对象以树的形式保存了界面上所有的内容
HTML页面每一部分都是由节点(标签(元素),文本,属性)

    let oDiv = document.querySelector("div");
    // children属性获取到的是指定元素中所有的子元素
    // console.log(oDiv.children);
    // childNodes属性获取到的是指定元素中所有的节点
    // console.log(oDiv.childNodes);
    for(let node of oDiv.childNodes){
        // console.log(node.nodeType);
        // if(node.nodeType === 1){
        if(node.nodeType === Node.ELEMENT_NODE){
            console.log(node);
        }
    }
  • 获取指定节点中的第一个子节点
let oDiv = document.querySelector("div");
    console.log(oDiv.firstChild);
  • 获取指定元素中的第一个子元素
    console.log(oDiv.firstElementChild);
  • 获取指定节点中最后一个子节点
    console.log(oDiv.lastChild);
  • 获取指定元素中最后一个子元素
    console.log(oDiv.lastElementChild);
  • 通过子元素获取父元素/父节点
    let item = document.querySelector(".item");
    console.log(item.parentElement);
    console.log(item.parentNode);
    let parentEle = item.parentElement || item.parentNode;
    console.log(parentEle);

  • 获取相邻上一个节点
    console.log(item.previousSibling);
  • 获取相邻上一个元素
    console.log(item.previousElementSibling);
  • 获取相邻下一个节点
    console.log(item.nextSibling);
  • 获取相邻下一个元素
    console.log(item.nextElementSibling);

元素的增删改查

     // - 创建节点
    let oSpan = document.createElement("span");

    // - 添加节点 
    // - 注意点: parseIntappendChild方法会将指定的元素添加到最后
    let oDiv = document.querySelector("div");
    oDiv.appendChild(oSpan)

    // - 插入节点
    let oH2 = document.querySelector("h2");
    oDiv.insertBefore(oSpan,oH2);

    // - 删除节点
    // - 注意点: 在js中如果想要删除某一个元素, 只能通过对应的父元素来删除
    let oh1 = document.querySelector("h1");
    oh1.parentNode.removeChild(oh1);

    // - 克隆节点
    // - 注意点: cloneNode方法默认不会克隆子元素, 如果想克隆子元素需要传递一个true
    let nDiv = oDiv.cloneNode(true);
    console.log(nDiv);

元素属性的增删改查

    // - 获取元素属性
    let oP = document.querySelector("img");
    // 注意点: 通过对象.属性名称的方式无法获取到自定义属性的取值
    //         通过getAttribute方法可以获取到自定义属性的取值
    console.log(oP.alt);
    console.log(oP.getAttribute("haha"));

    // - 修改元素属性
    oP.alt = "789";
    oP.setAttribute("alt","hahah");
    console.log(oP.alt);

    // - 新增元素属性
    oP.setAttribute("add","145");

    // - 删除元素属性
    oP.alt = "";
    oP.removeAttribute("add");

元素内容操作

    /*
    特点:
    无论通过innerHTML/innerText/textContent设置内容, 新的内容都会覆盖原有的内容
    区别:
    如果通过innerHTML设置数据, 数据中包含标签, 会转换成标签之后再添加
    如果通过innerText/textContent设置数据, 数据中包含标签, 不会转换成标签, 会当做一个字符串直接设置
    */
    
    // - 获取元素内容
    let oDiv = document.querySelector("div");
    oDiv.innerHTML = "123";
    oDiv.innerText = "456";
    oDiv.textContent = "789";

    // - 设置兼容
    setText(oDiv, "www.it666.com");
    function setText(obj,text) {
        if ("textContent" in obj){
            obj.textContent = text;
        }else 
        {
            obj.innerText = text;
        }

    }

元素样式操作

    // 1.设置元素样式
    /*
    let oDiv = document.querySelector("div");
    // 第一种方式
    // 注意点: 由于class在JS中是一个关键字, 所以叫做className
    // oDiv.className = "box";
    // 第二种方式
    // 注意点: 过去CSS中通过-连接的样式, 在JS中都是驼峰命名
    // 注意点: 通过JS添加的样式都是行内样式, 会覆盖掉同名的CSS样式
    oDiv.style.width = "300px";
    oDiv.style.height = "300px";
    oDiv.style.backgroundColor = "blue";
    */

    // 2.获取元素样式
    let oDiv = document.querySelector("div");
    // oDiv.style.width = "300px";
    // 注意点: 通过style属性只能过去到行内样式的属性值, 获取不到CSS设置的属性值
    // console.log(oDiv.style.width);
    // 注意点: 如果想获取到CSS设置的属性值, 必须通过getComputedStyle方法来获取
    // getComputedStyle方法接收一个参数, 这个参数就是要获取的元素对象
    // getComputedStyle方法返回一个对象, 这个对象中就保存了CSS设置的样式和属性值
    let style = window.getComputedStyle(oDiv);
    console.log(style.width);

DOM事件

   /*
   	1.什么是事件?
   用户和浏览器之间的交互行为我们就称之为事件,	比如:点击,移入/移出

   2.如何给元素绑定事件?
   在JavaScript中所有的HTML标签都可以添加事件
   元素.事件名称 = function(){};
   当对应事件被触发时候就会自动执行function中的代码
   */
   let oBtn = document.querySelector("button");
   oBtn.onclick = function () {
       alert("按钮被点击了");
   }
   // 注意点: 如果给元素添加了和系统同名的事件, 我们添加的事件不会覆盖系统添加的事件
   let oA = document.querySelector("a");
   oA.onclick = function () {
       alert("a标签被点击了");
       // 以下代码的含义: 用我们添加的事件覆盖掉系统同名的事件
       return false;
   }

定时器

在JavaScript中有两种定时器, 一种是重复执行的定时器, 一种是只执行一次的定时器

  • 重复执行的定时器
    let startBtn = document.querySelector("#start");
    let id = null;
    startBtn.onclick = function () {
        id = setInterval(function () {
            console.log("随便写点");
        }, 1000);
    }
    let closeBtn = document.querySelector("#close");
    closeBtn.onclick = function () {
        clearInterval(id);
    }
  • 只执行一次的定时器
    let startBtn = document.querySelector("#start");
    let closeBtn = document.querySelector("#close");
    let id = null;
    startBtn.onclick = function () {
        id = window.setTimeout(function () {
            console.log("随便写点");
        }, 5000);
    }
    closeBtn.onclick = function () {
        clearTimeout(id);
    }

移入移出事件

  • 移入事件
    let oDiv = document.querySelector("div");
    oDiv.onmouseover = function () {
        console.log("移入事件");
    }

    oDiv.onmouseenter = function () {
        console.log("移入事件");
    }
  • 移出事件
    oDiv.onmouseout = function () {
        console.log("移出事件");
    }
    oDiv.onmouseleave = function () {
        console.log("移出事件");
    }
  • 移动事件
    oDiv.onmousemove = function () {
        console.log("移动事件");
    }

表单事件

  • 获取input的值
    let oText = document.querySelector("input[type=text]");
    let oBtn = document.querySelector("input[type=submit]");
    oBtn.onclick = function () {
        console.log(oText.value);
        return false;
    }
  • input获取焦点事件
    let oText = document.querySelector("input[type=text]");
    oText.onfocus = function () {
        console.log("获取焦点");
    }
  • input失去焦点事件
    oText.onblur = function () {
        console.log("失去焦点");
    }
  • input内容改变事件
    oText.onchange = function () {
        console.log("失去焦点时获取输入框中内容" + oText.value);
    }

    oText.oninput = function () {
        console.log("实时获取输入框的值" + oText.value);
    }

闭包

  • 什么是闭包

闭包是一种特殊的函数

  • 如何生成一个闭包

当一个内部函数引用了外部函数的数据(变量/函数)时,那么内部函数就是闭包,所以只要满足"是函数嵌套"、"内部函数引用外部函数数据"

  • 闭包特点

只要闭包还在使用外部函数的数据,那么外部的数据就一直不会得到释放,也就是说延长了外部函数的生命周期

  • 闭包注意点

当后续不需要使用闭包时,一定手动将闭包设置为null

    function test() {
        var i = 666;
        // 由于demo函数满足闭包的两个条件, 所以demo函数就是闭包
        return function demo() {
            console.log(i);
        }
    }
    let fn = test();
    fn(); // 666

排他思想

清除其他非选中元素样式,只设置当前选中元素样式

let oItems = document.querySelectorAll("li");
    let previousIndex = 0;
// - ES6之后
    for(let i = 0; i < oItems.length; i++){
        let item = oItems[i];
        item.onclick = function () {
            let preItem = oItems[previousIndex];
            preItem.className = "";
            this.className = "current";
            previousIndex = i;
        }
    }

// -- ES6之前
for(var i = 0; i < oItems.length; i++) {
        var item = oItems[i];
        (function (index) {
            item.onclick = function () {
                // 排它
                var preItem = oItems[previousIndex];
                preItem.className = "";
                this.className = "current";
                previousIndex = index;
            }
        })(i);
    }

时间对象

  • 获取当前时间
    let date = new Date();
    console.log(date); // Thu Aug 20 2020 10:01:02 GMT+0800 (中国标准时间)
  • 获取时间戳
    let date = Date.now();
    console.log(date); // 1597888930073

    let date1 = new Date();
    console.log(date1.valueOf()); // 1597888998763
  • 创建指定时间
    let date = new Date("2019-11-23 08:21:02");
    console.log(date);
    // - 注意点:如果月份为单独传入,会多出一个月
    let date1 = new Date(2019,3,12,11,2,34);
    console.log(date1);

  • 获取指定时间年月日时分秒
    let date = new Date();
    console.log(date.getFullYear());
    // - 注意点:通过getMonth获取的月份会少一个月
    console.log(date.getMonth() +1);
    console.log(date.getDay());
    console.log(date.getHours());
    console.log(date.getMinutes());
    console.log(date.getSeconds());
  • 时间格式化
    let date = new Date();
    function formartDate(date) {
        return `${date.getFullYear()}-${date.getMonth() +1}-${date.getDay()} ${date.getHours()}:${date.getMinutes()}:${date.getSeconds()}`;

    }
    let date1 = formartDate(date);
    console.log(date1);

给元素添加事件的三种方法

  • 通过onclick来添加

后赋值的方法会替换前面的方法

    let box = document.querySelector(".main");
    box.onclick = function () {
        alert("333");
    }

    box.onclick = function () {
        alert("555");

    }
  • 通过addEventListener来添加

给相同元素绑定方法不会被替换

    box.addEventListener("click",function () {
        alert("666");
    })

    box.addEventListener("click",function () {
        alert("777");
    })
  • 通过attachEven添加

事件对象

  • 什么是事件对象

系统自动创建的对象,当注册的事件被触发时,系统会自动创建事件对象。

    box.onclick = function (event) {
        // - event 事件对象
        console.log(event);
    }

事件执行的三个阶段

  • 捕获阶段

从外(父元素)向内(子元素)传递事件

  • 当前目标阶段

执行事件回调函数

  • 冒泡阶段

从内(子元素)向外(父元素)传递事件

事件冒泡的应用

排他

    let oUl = document.querySelector("ul");
    let oli = document.querySelector(".selected");

    oUl.onclick = function (event) {
        oli.className = "";
        let sli = event.target;
        sli.className = "selected";
        oli = sli;
    }

阻止事件冒泡

    // - 阻止事件冒泡
    oDiv.onclick = function (event) {
        if (event.cancelBubble){
            event.cancelBubble = true;
        }else 
        {
            event.stopPropagation();
        }
    }

位置获取

offsetX/offsetY: 事件触发相对于当前元素自身的位置

clientX/clientY: 事件触发相对于浏览器可视区域的位置

注意点: 可视区域是不包括滚动出去的范围的

pageX/pageY: 事件触发相对于整个网页的位置

注意点: 整个网页包括滚动出去的范围的

screenX/screenY: 事件触发相对于屏幕的位置

正则表达式

  • 常用正则
常用正则表达式合集:
验证数字:^[0-9]*$
验证n位的数字:^\d{n}$
验证至少n位数字:^\d{n,}$
验证m-n位的数字:^\d{m,n}$
验证零和非零开头的数字:^(0|[1-9][0-9]*)$
验证有两位小数的正实数:^[0-9]+(.[0-9]{2})?$
验证有1-3位小数的正实数:^[0-9]+(.[0-9]{1,3})?$
验证非零的正整数:^\+?[1-9][0-9]*$
验证非零的负整数:^\-[1-9][0-9]*$
验证非负整数(正整数 + 0)  ^\d+$
验证非正整数(负整数 + 0)  ^((-\d+)|(0+))$
验证长度为3的字符:^.{3}$
验证由26个英文字母组成的字符串:^[A-Za-z]+$
验证由26个大写英文字母组成的字符串:^[A-Z]+$
验证由26个小写英文字母组成的字符串:^[a-z]+$
验证由数字和26个英文字母组成的字符串:^[A-Za-z0-9]+$
验证由数字、26个英文字母或者下划线组成的字符串:^\w+$

验证用户密码:^[a-zA-Z]\w{5,17}$ 正确格式为:以字母开头,长度在6-18之间,只能包含字符、数字和下划线。
验证是否含有 ^%&',;=?$\" 等字符:[^%&',;=?$\x22]+
验证汉字:^[\u4e00-\u9fa5],{0,}$
验证Email地址:^\w+[-+.]\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*$
验证InternetURL:^http://([\w-]+\.)+[\w-]+(/[\w-./?%&=]*)?$ ;^[a-zA-z]+://(w+(-w+)*)(.(w+(-w+)*))*(?S*)?$
验证电话号码:^(\d3,4|\d{3,4}-)?\d{7,8}$:--正确格式为:XXXX-XXXXXXX,XXXX-XXXXXXXX,XXX-XXXXXXX,XXX-XXXXXXXX,XXXXXXX,XXXXXXXX。
验证身份证号(15位或18位数字):^\d{15}|\d{}18$
验证一年的12个月:^(0?[1-9]|1[0-2])$ 正确格式为:“01”-“09”和“1”“12”
验证一个月的31天:^((0?[1-9])|((1|2)[0-9])|30|31)$    正确格式为:01、09和1、31。
整数:^-?\d+$
非负浮点数(正浮点数 + 0):^\d+(\.\d+)?$
正浮点数   ^(([0-9]+\.[0-9]*[1-9][0-9]*)|([0-9]*[1-9][0-9]*\.[0-9]+)|([0-9]*[1-9][0-9]*))$
非正浮点数(负浮点数 + 0) ^((-\d+(\.\d+)?)|(0+(\.0+)?))$
负浮点数  ^(-(([0-9]+\.[0-9]*[1-9][0-9]*)|([0-9]*[1-9][0-9]*\.[0-9]+)|([0-9]*[1-9][0-9]*)))$
浮点数  ^(-?\d+)(\.\d+)?$
posted @ 2020-08-13 15:02  cmg123  阅读(110)  评论(0)    收藏  举报