JS-WebAPIs-DOM基础

JS-WebAPIs第1天-DOM

参考:

pink老师JS基础 JavaScript基础语法-dom/bom-es6-jQuery-数据可视化echarts-包含笔记源码作业黑马程序员pink老师前端入门视频教程(持续更新)

MDN-Web API接口参考 文档对象模型

Web APIs 和JS基础的关联性

在这里插入图片描述

一. 什么是DOM(Document Object Model)

详细参考{MDN-Web API接口参考 文档对象模型}, 这里先只学几个常用方法并给出示例.

The Document Object Model (DOM) connects web pages to scripts or programming languages by representing the structure of a document. The DOM represents a document with a logical tree. Each branch of the tree ends in a node, and each node contains objects.

在这里插入图片描述

DOM是W3C组织推荐的处理可扩展标记语言(HTML/XML)的标准编程接口. DOM模型用一个逻辑树来表示一个文档,树的每个分支的终点都是一个节点(node),每个节点都包含着对象(objects)。DOM的方法(methods)让你可以用特定方式操作这个树,用这些方法你可以改变文档的结构、样式或者内容。节点可以关联上事件处理器,一旦某一事件被触发了,那些事件处理器就会被执行.

要做一个动态页面, 就是触发响应, 称之为事件. 事件是有三部分组成 事件源 事件类型 事件处理程序 我们也称为事件三要素.首先获取DOM元素也就是事件源, 接着设计触发的事件类型(点击\按下…), 最后通过函数设计响应(事件处理程序).

Document 接口描述了任何类型的文档的通用属性与方法。根据不同的文档类型(例如HTMLXMLSVG,…),还能使用更多 API:使用 "text/html" 作为内容类型(content type)的 HTML 文档,还实现了 HTMLDocument 接口,而 XML 和 SVG 文档则(额外)实现了 XMLDocument 接口。

二. 事件-获取页面元素当事件源

根据ID获取(适用于独一的元素)document.getElementById()
根据标签名获取document.getElementsByTagName()
通过HTML5新增方法获取document.getElementsByClassName(‘类名’); document.querySelector(’.类名/#ID名’)
特殊元素获取(html/body…)document.body; document.documentElement;
2.1 document.getElementById()根据ID获取

MDN详细信息: https://developer.mozilla.org/zh-CN/docs/Web/API/Document/getElementById

ID是独一无二的, 因此可以直接通过ID获取元素

// 1. 因为我们文档页面从上往下加载,所以先得有标签 所以我们script写到标签的下面,即body的后面
// 2. get 获得 element 元素 by 通过 驼峰命名法 
// 3. 参数 id是大小写敏感的字符串
// 4. 返回的是一个元素对象

var timer = document.getElementById('time');
console.log(timer);
console.log(typeof timer);
// 5. console.dir 打印我们返回的元素对象 更好的查看里面的属性和方法
console.dir(timer);
2.2 document/element.getElementsByTagName()根据标签名获取

document. getElementsByTagName()可以获取HTML中所有这个标签的元素, 如果需要某个特点父元素下的此类子元素, 可以用element(这里是父元素). getElementsByTagName(标签名‘)

// 1.返回的是 获取过来元素对象的集合 以伪数组的形式存储的
//以伪数组形式存储, 因此可以用伪数组方式遍历
var lis = document.getElementsByTagName('li');
console.log(lis);
console.log(lis[0]);

// 2. 我们想要依次打印里面的元素对象我们可以采取遍历的方式
for (var i = 0; i < lis.length; i++) {
  console.log(lis[i]);
}

// 3. 如果页面中只有一个li 返回的还是伪数组的形式 
// 4. 如果页面中没有这个元素 返回的是空的伪数组的形式
// 5. element.getElementsByTagName('标签名'); 父元素必须是指定的单个元素
// var ol = document.getElementsByTagName('ol'); // [ol]
// console.log(ol[0].getElementsByTagName('li'));
var ol = document.getElementById('ol');
console.log(ol.getElementsByTagName('li'));
2.3 H5新增方式-CSS选择器(不兼容IE678…)
  1. document.getElementsByClassName(‘类名’) 根据类名获得某些元素集合,包括所有同名元素,返回一个伪数组

  2. document.querySelector() 返回指定选择器的第一个元素对象 切记 里面的选择器需要加符号 .box #nav(.表示class名, #表示id名)

  3. document.querySelectorAll() 返回所有

<body>
    <div class="box">盒子1</div>
    <div class="box">盒子2</div>
    <div id="nav">
        <ul>
            <li>首页</li>
            <li>产品</li>
        </ul>
    </div>
    <script>
       // 1. getElementsByClassName 根据类名获得某些元素集合
        var boxs = document.getElementsByClassName('box');
        console.log(boxs);	//返回伪数组包含’盒子1’’盒子2’两个元素
        // 2. querySelector 返回指定选择器的第一个元素对象  切记 里面的选择器需要加符号 .box  #nav
        var firstBox = document.querySelector('.box');
        console.log(firstBox);	//盒子1
        var nav = document.querySelector('#nav');
        console.log(nav);		//返回< div id="nav">此行
        var li = document.querySelector('li');
        console.log(li);		//首页
        // 3. querySelectorAll()返回指定选择器的所有元素对象集合
        var allBox = document.querySelectorAll('.box');
        console.log(allBox);
        var lis = document.querySelectorAll('li');
        console.log(lis);
    </script>
</body>

2.4 特殊元素
// 1.获取body 元素
var bodyEle = document.body;
console.log(bodyEle);
console.dir(bodyEle);
// 2.获取html 元素
// var htmlEle = document.html;     //  此时为undefined
var htmlEle = document.documentElement;
console.log(htmlEle);

三. 事件-触发响应

执行事件的步骤: 1,获取事件源 2,注册事件(绑定事件) 3,添加事件处理程序(函数赋值形式)

常见的鼠标事件:

鼠标事件触发条件
onclick鼠标点击左键触发(CSS里没有)
onmouseover鼠标经过触发(CSS里hover可实现)
onmouseout鼠标离开触发
onfocus获得鼠标焦点(适用于表单输入)
onblur失去鼠标焦点
onmousemove鼠标移动触发
onmouseup鼠标弹起触发
onmousedown鼠标按下触发

四. 操作元素

在这里插入图片描述

4.1 改变元素内容

格式:

element.innerText;
element.innerHTML;

使用举例:

//获取事件源
var div = document.querySelector('div');
div.innerText = '<strong>今天是:</strong> 2019';
//返回: <strong>今天是:</strong> 2019

div.innerHTML = '<strong>今天是:</strong> 2019';
//返回: 今天是:(加粗字体) 2019

// 这两个属性是可读写的  可以获取元素里面的内容
var p = document.querySelector('p');
console.log(p.innerText);
console.log(p.innerHTML);

innerText 和 innerHTML的区别 :

// 1. innerText 不识别html标签 非标准  会去除空格和换行
// 2. innerHTML 识别html标签 W3C标准 保留空格和换行的
//总结: innerText非标准, 推荐使用标准innerHTML
4.2 常用元素的属性操作
element.src //改变路径
href		//返回当前样式表文件(css文件)的路径地址
id, alt, title...

使用案例:

<head>
    <link rel="StyleSheet" href="//C:/Windows/Desktop/example.css" type="text/css" />
    <script>
        function sref() {
            alert(document.styleSheets[0].href);
        }
    </script>
</head>

<body>
    <button onclick="sref()">显示路径</button>
</body>

</html>
<!-- 弹出 "file:C:/Windows/Desktop/example.css -->

见练习2-根据不同时间显示不同提示语和图片

4.3 表单元素的属性操作

利用DOM可以操作如下表单元素的属性:

属性举个栗子
typeinput密码框变文本框,显示密码
value搜索框的默认文字
checked
selected
disabled

表单里的文字不能通过innerHTML修改,而是有专门的属性

见练习3-点击显示密码

4.4 样式属性操作
1. element.style	//行内样式操作,等效于把样式在CSS行内更改,优先级高
2. element.className	//类名样式操作, 同时更改多个样式时使用,避免在JS里写过多CSS样式代码

练习4-关闭二维码(网页上的小块广告, 点击关闭)

练习5-循环精灵图

练习6-搜索框输入时隐藏默认字符

五. 节点操作

在这里插入图片描述

文档叫做文档节点, 元素叫元素节点, 标签成为标签节点, 属性也是节点, 甚至注释也是节点. 一般主要操作元素节点.

一般地,节点至少拥有nodeType(节点类型), nodeName(节点名称)和nodeValue(节点值)这三个基本属性.

  • 元素节点 nodeType 为1
  • 属性节点 nodeType 为2
  • 文本节点 nodeType 为3 (包括文字,空格,换行)
5.1 父节点

利用亲父子关系: node.parentNode, 如果找不到父节点返回空.

5.2 子节点
parentNode.childNodes

获得此父节点的所有孩子, 其中文字算文本节点, 也会被存进该伪数组.

如果只想获得里面的元素节点,需要再遍历去除其他类型节点, 更麻烦. 所有一般不使用childNodes

parentNode.children

实际开发常用,获取所有子元素节点.

parentNode.firstChild && parentNode.lastChild

获得第一个/最后一个节点, 包括文本

parentNode.firstElementChild && parentNode.lastElementChild

返回第一个/最后一个子元素节点,找不到则返回null

注意: 只兼容IE9+

实际开发写法, 解决兼容问题:

parentNode.children[0] 返回第一个子元素

parentNode.children[parentNode.children.length-1] 返回最后一个子元素

5.3 兄弟节点
element.nextSibling && previousSibling

下个兄弟节点和上个兄弟节点, 包含文本,换行等

node.nextElementSibling && previousElementSibling

IE9+才支持 返回下一个兄弟元素节点,找不到返回null

封装一个兼容性函数
function getNextElementSibling(element) {
    var el = element;
    while(el = el.nextSibling) {
        if (el.nodeType === 1){
            return el;
        }
    }
    return null;
}
5.4 创造节点-增加节点
1. appendChild
2. insertBefore

使用案例: 用户发表评论时显示出来,实际是创造了一个节点

创造节点有两步: 1. 创建新元素 2. 把新元素添加进去

//创造节点方法:
var newNode = document.createElement('tagTypeName');
//添加节点方法:
1. 添加到指定父节点的子节点列表末尾, 类似css里的after伪元素
parentNode.appendChild(newNode);
2. 添加到置顶父节点的子节点列表的指定元素前面
parentNode.insertBefore(newNode, parentNode.children[0]);

举个栗子:

	<ul><ul>
<script>
    // 1. 创建节点元素节点
    var li = document.createElement('li');
    // 2. 添加节点 node.appendChild(child)  node 父级  child 是子级 后面追加元素  类似于数组中的push
    //先获取已有元素,为要添加的位置
    var ul = document.querySelector('ul');
    
    //
    ul.appendChild(li);
    // 3. 添加节点 node.insertBefore(child, 指定元素);
    var lili = document.createElement('li');
    ul.insertBefore(lili, ul.children[0]);
    // 4. 我们想要页面添加一个新的元素 : 1. 创建元素 2. 添加元素
</script>
5.5 删除节点
node.removeChild(child)

从DOM中删除父节点node的一个子节点, 返回删除的节点.

举个栗子:

<body>
    <ul>
        <li>熊大</li>
        <li>熊二</li>
        <li>光头强</li>
    </ul>
    <button>删除</button>
    <script>
        // 1. 获取父元素
        var ul = document.querySelector('ul');
        // 2. 删除子元素  ul.removeChild(ul.children[0]);

        //3. 点击删除
        var btn = document.querySelector('button');
        btn.onclick = function() {
            if (ul.children.length === 0) {
                alert('恭喜你,删光啦');
                this.disabled = true;
            } else {
                ul.removeChild(ul.children[0]);
            }
        }
    </script>
</body>
5.6 复制节点

练习见: [动态生成数组]

node.cloneNode()

返回调用该方法的节点的一个副本, 也称克隆节点/拷贝节点;

注意: 1.如果括号参数为空或者false, 代表浅拷贝, 即只克隆标签类型,不复制里面的内容; 2. 括号内true, 则全部复制

克隆完如果需要使用,别忘了添加此克隆节点

var ul = document.querySelector('ul');
// 1. node.cloneNode(); 括号为空或者里面是false 浅拷贝 只复制标签不复制里面的内容
// 2. node.cloneNode(true); 括号为true 深拷贝 复制标签复制里面的内容
var lili = ul.children[0].cloneNode(true);//把ul的第一个孩子深复制
ul.appendChild(lili);

六, 创建节点的三种方式

6.1 document.write()

页面加载完再重新写入, 页面除了写入的新节点其他会被清空

<body>
    <button>点击</button>
    <p>abc</p>
    <div class="inner"></div>
    <div class="create"></div>
    <script>
        // 三种创建元素方式区别 
        // 1. document.write() 创建元素  如果页面文档流加载完毕,再调用这句话会导致页面重绘
         var btn = document.querySelector('button');
         btn.onclick = function() {
             document.write('<div>123</div>');
         }
    </script>
</body>

上面所示JS等效于如下:

 window.onload = function() {
 document.write('<div>123</div>');
}

很不常用, 了解即可

6.2 element.innerHTML

相当于给父节点里面放一个子节点, innerHTML后面不必是text类型, 可以带标签.

innerHTML添加也有两种方式.

第一种, 直接拼接字符串. 缺点: 每次拼接都会新建一个加长的字符串, 多次拼接会大量占用内存

var inner = document.querySelector('.inner');
// 拼接字符串方式用innerHTML创建
inner.innerHTML = '<a href="#">百度</a>'
// 拼接100个
for (var i = 0; i <= 100; i++) {
    inner.innerHTML += '<a href="#">百度</a>'
}

第二种(优), 用数组形式实现拼接多个字符串, 先把字符串放进数组, 再一次性 arr.join(’’) 把数组转字符串拼进去

var arr = [];
for (var i = 0; i <= 100; i++) {
    arr.push('<a href="#">百度</a>');
}
inner.innerHTML = arr.join('');
6.3 document.creatElement()
// 3. document.createElement() 创建元素
var create = document.querySelector('.create');
for (var i = 0; i <= 100; i++) {
    var a = document.createElement('a');
    create.appendChild(a);
}
6.4 三者区别

在这里插入图片描述

比如面试问题如下:

问: innerHTML和creatElement谁效率高?

答: 如果不拼接字符串, 而是采用数组形式, 那么innerHTML效率会更高

问: 为什么innerHTML效率更高. creatElement每次都创建一个节点,再append进父节点, 下次创建节点时虽然上次的节点所占内存空间被释放,依然会新建一个节点, 所以效率慢一些, 但结构清晰

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值