【Web API】DOM事件

Web APIs与JS基础的关联

JS的三个组成部分中,经常提到的JS基础是指ECMAScript,Web APIs阶段是DOM和BOM

API(Application Programming Interface,应用程序编程接口)我们并不陌生,那么什么是Web API呢?

其实用法思想差不多,Web API用来操作浏览器功能页面元素的接口
 
 

DOM
 
DOM树

文档 document :整个页面

元素 element :页面中所有的标签的都是元素

节点 node :页面中所有的内容都是节点,包括标签、属性、文本、注释等

☀ DOM把以上内容都看作是对象
 

获取页面元素

注意看注释!

// console.dir() 可以打印元素对象,方便查看里面的属性和方法

// 根据id:
var timer = document.getElementById('time');
// 注1:返回是一个元素对象
// 注2:括号里是字符串,必须加引号

// 根据标签名:
var list = document.getElementsByTagName('li');
// 注1:获取了页面(document)的所有li
// 注2:返回的是元素对象的集合(伪数组的形式)
// 注3:获得的对象是动态的
var navList = document.getElementById('me').getElementsByTagName('li');
// 注1:获取了id为'me'的ul的li

// 根据类名:
var boxs = document.getElementsByClassName('box');
// 注1:返回的是集合(即使只找到了一个元素,也是个伪数组)

// HTML5新增的两种方法(推荐):
var box = document.querySelector('.box');
var box = document.querySelector('#time');
var box = document.querySelector('li');
// 注1:只返回指定选择的第一个对象
// 注2:选择器要加'#'或'.'或不加,告诉它这是个什么选择器
var boxs = document.querySelectorAll('.box');
// 注1:顾名思义,返回集合

// 获取head元素
var headElement = document.head;
// 获取body元素
var bodyElement = document.body;
// 获取html元素
var htmlElement = document.documentElement;

事件基础

简单来说,就是触发-响应机制

// 事件三要素: 事件源,事件类型,事件处理程序
// 与点击按钮为例

//(1) 事件源 —— 事件被触发的对象
var btn = document.getElementById('btn');
//(2) 事件类型 —— 如何触发?
//(3) 事件处理程序 —— 通过一个函数赋值完成
btn.onclick = function(){alert('赛高 ! ! !');}

操作元素

1.改变元素的内容

innerTextinnerHTML(推荐后者)

var box = document.querySelector('div');
box.innerText = '一只萝莉';						// 不能识别html标签
box.innerHTML = '<strong>一只萝莉</strong>';		// 可以识别html标签
// 会覆盖之前的内容 !

// 它们是可读可写的
console.log(box.innerText);			// 不识别html标签,和换行和空格一起被自动去掉了
console.log(box.innerHTML);			// 可识别html标签,标签、换行和空格都被保留

 
2.改变元素的属性(src、href、title、alt…)

直接按 对象.属性 思路写

// demo:
var myImg = document.querySelector('img');
myImg.src = 'loli.jpg';

 
3.操作表单元素的属性

需要注意的是,innerHTML用来修改普通盒子的文本内容,而表单的文本内容是写在属性value中的

表单特有的属性除了value,还有type, checked, selected, disabled

// demo:点击一次按钮后该按钮就被禁用
myBtn.onclick = function() {
	this.disabled = true;   // true写成'disabled'也行
	// 注意:this指向的是对象myBtn,也就是该事件的调用者
}
<!-- demo:密码的输入(小眼睛) -->
<!-- 核心思路是密码框和文本框的转换:即input的type属性——password和text -->

<div class="box">
    <input type="password" id="pwd">
    <img src="eyeclose.png" id="eye">
</div>

<script>
	var myInput = document.getElementById('pwd');	 // 获取输入框对象
    var myBtn = document.getElementById('eye'); 	 // 获取img对象当做按钮  
    var flag = 0; 		// 通过一个flag标记进行交替
    myBtn.onclick = function() {
        if (flag == 0) {
            myInput.type = 'text';
            myBtn.src = 'eyecopen.png';
            flag = 1;
        } else {
            myInput.type = 'password';
            myBtn.src = 'eyeclose.png';
            flag = 0;
        }
    }
</script>

 
4.修改元素的样式属性(大小,颜色,位置等)

element.style 行内样式操作

element.className 类名样式操作

// 方式1: 行内样式操作
var box = document.querySelector('div');
box.onclick = function() {
    this.style.width = '250px';
    this.style.backgroundColor = 'Pink';
}
// 注1:属性值加引号——因为本质是修改行内样式,也因此CSS权重较高
// 注2:属性的驼峰命名写法
<!-- demo:关闭小广告 -->
<!-- 核心思路是:同一个按钮控制整个父盒子的display(block or none?) -->
<div class="box">
    <img src="loli1.jpg" alt="">
    <div class="close">×</div>
</div>
<script>
    var closeBtn = document.querySelector('.close');
    var box = document.querySelector('.box');
    closeBtn.onclick = function() {
        box.style.display = 'none';
    }
</script>
// 精灵图
// 核心思路是:精灵图上的图标位置都是[成行或成排的],因此根据其位置规律就可以计算出其[背景位置]
var list = document.querySelectorAll('li');		// 返回的是一个伪数组,伪数组的元素才是对象
for(var i = 0; i < list.length; i++) {
	list[i].style.backgroundPosition = '0 -' + i*44 + 'px';		// 就是 '0 0px' '0 44px' '0 88px'...
}
// 方式二:类名样式操作
// 上面的demo中,都是改变某个元素的仅几个样式,而当需要改变的样式太多时,岂不是要写很多个this.属性? [类名样式操作]给我们提供了另一种思路:

// 把改变后的样式都写在css里,作为一个类;触发事件后就把这个类加上
box.onclick = function() {
	this.className = 'change';		// .change使我们提前写在css的一个类
}

// 缺点也很致命:会覆盖原先的类名
// 解决方案很简单但一定要能想到: this.className = 'old new';	 ———都写上就okk了

 
5.补充:排他思想

这是一种特别常用的思想,比如我们通常需要多个按钮中同时只能一个被按下,那么就需要用到排他思想:

按下这个按钮作为事件,将所有的按钮先复原,再设置此按钮的按下效果
 
6. 获取属性值的两种方法

element.属性 :通常用来也只能获取内置属性(元素自带的属性值)

element.getAttribute('属性') : 主要用来获取自定义属性
 
7. 设置属性值的两种方法

element.属性 = '值' :通常用来也只能设置内置属性(元素自带的属性值)

element.setAttribute('属性', '值') : 主要用来修改自定义属性

注:div.className = 'nav'等价于div.setAttribute('class', 'nav')
 
8. 移除属性

element.removeAttribute('属性')
 
9. H5自定义属性

一个约定:自定义属性以data-作为前缀

获取属性的新写法:element.dataset.属性element.dataset['属性'](dataset实际上是一个集合)

注:像data-part-name这种有多个短连接符的自定义属性,采用驼峰命名法dataset.partNamedataset['partName']

 
 

节点操作

为什么有的情况下使用节点操作?

  DOM获取元素有时较为繁琐逻辑结构性不强,这时就可以利用节点的层级关系(父子兄弟)来获取元素
 
节点概述:

  1. 至少拥有nodeType, nodeName, nodeValue三个基本属性
  2. 关于节点类型nodeType:元素节点为1属性节点为2文本节点为3(包含文字、空格、换行)
  3. 我们在实际开发中,节点操作是指操作元素节点

获取节点:

<div class="bigBox">
    <div class="midBox">
        <div class="littleBox"></div>
        <div class="littleBox"></div>
        <div class="littleBox"></div>
    </div>
</div>

<script>
    var box = document.querySelector('.midBox');
    
    box.parentNode 				// 获取父节点(最近的父亲)

    box.childNodes 				// 获取子节点(实际上返回了一个含有7个对象的伪数组 —— 返回了所有的子节点(包括回车这个文本节点))
    box.children 				// 获取子节点(这是常用的:返回所有的子元素节点;不包括文本节点)
    box.firstChild 				// 第一个子节点(>_<可是是回车(文本节点))
    box.lastChild 				// 最后一个子节点(>_<可是是回车(文本节点))
    box.firstElementChild 		// 第一个孩子元素节点
    box.lastElementChild 		// 最后一个孩子元素节点
    box.children[0]								 // 更好用!
    box.children[box.children.length - 1] 		 //更好用!

    box.nextSibling 				// 下一个兄弟节点
    box.previousSibling 			// 上一个兄弟节点
    box.nextElementSibling 			// 下一个兄弟元素节点
    box.previousElementSibling 		// 上一个兄弟元素节点
</script>

 
节点的增、删

<ul>
    <li>loli1</li>
    <li>loli2</li>
</ul>

<script>
    var son = document.createElement('li'); 		// 创建元素节点
    
    var father = document.querySelector('ul');
    
    father.appendChild(son); 						// 追加元素节点
    father.insertBefore(son, father.children[0]); 	// 插入元素节点(在第二个参数的前面)
    
    father.removeChild(father.children[0]); 		// 删除(第一个)节点 (这个删除的写法其实很奇怪,小心一下)
</script>

 
节点的克隆

<script>
	var father = document.querySelector('ul');
	var loli = father.children[0].cloneNode();			// 默认false,浅拷贝,只复制节点本身 不复制其子节点
	var loli = father.children[0].cloneNode(true);		// true,深拷贝, 复制节点本身和里面所有的子节点
	// 另外,文本节点也是子节点,也就是说,浅拷贝连内容也无法复制
</script>

 
Quselement.innerHTMLdocument.createElement在动态创建元素时,效率的比较?

AnsinnerHTML在创建较多元素效率更高(采取数组形式拼接,不要直接字符串拼接!),结构性不强

   createElement在创建较多元素效率低一些(不是很多),但是结构清晰

 
☀ Loli & JS

♫ Suki

猜你喜欢

转载自blog.csdn.net/m0_46202073/article/details/106578925