01 序文
BOM (Browser Object Model) と DOM (Document Object Model) は、フロントエンド開発において不可欠な概念です。BOM はブラウザ ウィンドウやウィンドウ内のドキュメントへのアクセスなどの機能を提供し、DOM は HTML および XML ドキュメントを操作するためのインターフェイスを提供します。効率的で高品質な Web アプリケーションを開発するには、BOM と DOM をしっかりと理解することが重要です。
この記事では、上記の BOM と DOM に対するいくつかの具体的な操作、つまり一般的な手法の概要を説明します。BOM オブジェクト、BOM イベント、DOM ノード、DOM イベントなど、BOM と DOM の使用方法を詳しく説明します。初心者でも経験豊富な開発者でも、この記事は包括的なリファレンスを提供します。
02 ドム
Web ページが読み込まれると、ブラウザはページのドキュメント オブジェクト モデル (ドキュメント オブジェクト モデル) を作成します。
このオブジェクト モデルを通じて、JavaScript は動的な HTML を作成するためのすべての機能を取得します。
- JavaScript はページ内のすべての HTML 要素を変更できます
- JavaScript はページ内のすべての HTML 属性を変更できます
- JavaScript はページ内のすべての CSS スタイルを変更できます
- JavaScript は既存の HTML 要素と属性を削除できる
- JavaScript は新しい HTML 要素と属性を追加できます
- JavaScript はページ内のすべての既存の HTML イベントに反応できます
- JavaScript はページ内に新しい HTML イベントを作成できます
言い換えれば、HTML DOM は、HTML 要素を取得、変更、追加、削除する方法に関する標準です。
2.1 要素の検索
要素を見つけるために一般的に使用される方法。ここでは、上記の補足とヒントを示します。
方法 | 説明 |
---|---|
document.getElementById(id) | 要素 ID で要素を検索します。 |
document.getElementsByTagName(名前) | タグ名で要素を検索します。 |
document.getElementsByClassName(名前) | クラス名で要素を検索します。 |
document.querySelector (CSS セレクター) | CSS セレクターを介して要素を選択します。 |
document.querySelectorAll (CSS セレクター) | CSS セレクターを介して複数の要素を選択します。 |
2.2 HTMLの読み込み
方法 | 説明 |
---|---|
要素node.innerText | HTML要素の内部テキストを取得します。 |
要素node.innerHTML | HTML要素の内部HTMLを取得します。 |
要素のノード.属性 | HTML要素の属性値を取得します。 |
要素node.getAttribute(属性) | HTML要素の属性値を取得します。 |
要素node.style.style | HTML要素のインラインスタイル値を取得します。 |
その他の追加事項:
操作する | 説明 |
---|---|
document.getElementById(id) | 指定された ID を持つ要素オブジェクトを返します。 |
document.getElementsByTagName(名前) | 指定されたタグ名を持つ要素オブジェクトの配列を返します。 |
要素.innerHTML | 要素の HTML コンテンツを取得または設定します。 |
要素.スタイル.プロパティ | 要素のスタイル属性を取得または設定します。 |
element.setAttribute(名前, 値) | 要素の属性値を設定します。 |
element.getAttribute(名前) | 要素の属性値を返します。 |
element.appendChild(ノード) | 指定されたノードを要素の子ノードのリストの末尾に追加します。 |
element.removeChild(ノード) | 指定された子ノードを要素の子ノードのリストから削除します。 |
element.addEventListener(イベント, 関数) | イベントリスナーを追加します。 |
element.classList.add(クラス) | 要素の class 属性にクラス名を追加します。 |
element.classList.remove(クラス) | 要素の class 属性からクラス名を削除します。 |
element.classList.toggle(クラス) | 要素の class 属性のクラス名を切り替えます。 |
element.classList.contains(クラス) | 指定されたクラス名が要素の class 属性に含まれているかどうかを確認します。 |
これらの DOM 操作を使用すると、HTML ドキュメント内の要素やコンテンツにアクセスして操作できるため、開発者は HTML ページのコンテンツとスタイルを動的に更新および変更できます。
2.2.1 ブラウザはデフォルトのスタイルを読み取ります
注: style 属性の設定と読み取りは両方ともインラインスタイル、スタイル シート内のスタイル、または適用されているスタイルを読み取ることができません。現在適用されているスタイル属性を読み取りたい場合は、それを使用して
元素.currentStyle.样式名
要素の現在表示されているスタイルを取得できます。要素の表示スタイル Style、現在の要素がスタイルを設定していない場合は、そのデフォルト値を取得しますが、currentStyleIEブラウザでのみサポートされています、他のブラウザではサポートされていません。
getComputedStyle()
このメソッドは他のブラウザで要素の現在のスタイルを取得するために使用できます。、このメソッドはウィンドウ メソッドであり、直接使用できますが、次の 2 つのパラメータが必要です。
- 最初のパラメータ: スタイルを取得する要素
- 2 番目のパラメータ: 疑似要素を渡すことができます (通常は null)
このメソッドは、現在の要素に対応するスタイルをカプセル化したオブジェクトを返します。スタイルは对象.样式名
を介して。取得したスタイルが設定されていない場合は、デフォルト値の代わりに実際の値を取得します。
たとえば、幅が設定されていない場合、自動ではなく長さが取得されますが、このメソッドは IE8 以下のブラウザをサポートしていません。
currentStyle と getComputedStyle() によって読み取られるスタイルは読み取り専用で、変更できません。変更したい場合は、style 属性を渡す必要があります。したがって、各ブラウザに適応する要素スタイルを読み取るメソッドを作成できます。
事例紹介:
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title></title>
<style>
/*样式表的样式*/
#box {
width: 200px;
height: 200px;
background-color: green;
}
</style>
</head>
<body>
<div style="width: 100px;height: 100px;" id="box"></div>
<!-- 在这里写JavaScript代码,因为JavaScript是由上到下执行的 -->
<script>
/*通用的获取元素样式的方法*/
function getStyle(obj, name) {
if (window.getComputedStyle) {
//正常浏览器的方式,具有getComputedStyle()方法
return getComputedStyle(obj, null)[name];
} else {
//IE8的方式,没有getComputedStyle()方法
return obj.currentStyle[name];
}
}
var box = document.getElementById("box");
console.log(getStyle(box, "width"));
console.log(getStyle(box, "height"));
console.log(getStyle(box, "background-color"));
</script>
</body>
</html>
2.2.2 ラベルのテキスト内容を取得する
ID 属性を持つ div 要素と class 属性を持つ p 要素を持つ HTML ページがあるとします。DOM を使用して、これらの要素のテキスト コンテンツを取得できます。
以下は、任意のラベルのテキスト コンテンツを取得するケースのデモンストレーションです。
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title></title>
</head>
<body>
<a href="https://www.baidu.com" id="a">打开百度,你就知道!</a>
<!-- 在这里写JavaScript代码,因为JavaScript是由上到下执行的 -->
<script>
var a = document.getElementById("a");
console.log(getInnerText(a));
/*获取任意标签的内容*/
function getInnerText(element) {
// 判断浏览器是否支持textContent,如果支持,则使用textContent获取内容,否则使用innerText获取内容。
if(typeof element.textContent == "undefined") {
return element.innerText;
} else {
return element.textContent;
}
}
</script>
</body>
</html>
上記のコードは、最初にgetElementById
メソッドa 要素を取得し、textContent
属性を使用するかgetInnerText
そのテキスト コンテンツを取得して、それをコンソールに出力します。このようにして、DOM を使用して任意のラベルのテキスト コンテンツを取得できます。
2.3 HTMLの変更
方法 | 説明 |
---|---|
要素node.innerText = 新しいテキストコンテンツ | 要素の内部テキストを変更します。 |
要素node.innerHTML = 新しいHTMLコンテンツ | 要素の内部 HTML を変更します。 |
要素のノード.属性 = 新しい値 | HTML要素の属性値を変更します。 |
要素node.setAttribute(属性, 値) | HTML要素の属性値を変更します。 |
要素node.style.style = 新しいスタイル | HTML 要素のインライン スタイル値を変更します。 |
注: スタイルの変更には .style のみを使用できます。その後の他の方法は、スタイルを読み取るか、HTML を変更することです。
2.3.1insertAdjacentHTML
およびinsertAdjacentText
メソッド実装の変更
注: ノードのコンテンツを変更するために一般的に使用される innerHTML および innerText に加えて、指定された場所にコンテンツを挿入できる
insertAdjacentHTML
およびメソッドもあります。このメソッドはメソッドと似ていますが、同じパラメータを使用してプレーン テキストが挿入される点が異なります。insertAdjacentText
insertAdjacentText
insertAdjacentHTML
予防:
- これら 2 つのメソッドはドキュメントのロード後に実行する必要があります。実行しないとエラーが発生します。
- insertAdjacentText は通常のテキストのみを挿入でき、insertAdjacentHTML は HTML コードを挿入します。
- insertAdjacentHTML メソッドを使用してスクリプト ファイルを挿入する場合は、script 要素で defer 属性を定義する必要があります。
- insertAdjacentHTML メソッドを使用して HTML コードを挿入した後、ページ上の要素のコレクションが変更されます。
- insertAdjacentHTML方法不适用于单个的空的元素标签(如img,input等)。
参数说明:
参数一:where:
- beforeBegin:插入到开始标签的前面
- beforeEnd:插入到结束标签的前面
- afterBegin:插入到开始标签的后面
- afterEnd:插入到结束标签的后面
参数二:
- html:一段html代码
- text:一段文本值
代码示例:
<!DOCTYPE html>
<html>
<head>
<title>DOM示例</title>
</head>
<body>
<p class="myPara">这是一个示例p元素。</p>
<div id="myDiv">这是一个示例div元素。</div>
<script>
// 使用insertAdjacentHTML添加狐妖小红娘的优酷视频超链接
document.body.insertAdjacentHTML('beforeend', '<p><a href="https://v.youku.com/v_show/id_XMTMzNzgyMzY5Ng==.html?spm=a2h1n.8251845.0.0" target="_blank">狐妖小红娘的优酷视频</a></p>');
// 使用insertAdjacentText添加狐妖小红娘的简介
var myPara = document.getElementsByClassName('myPara')[0];
myPara.insertAdjacentText('afterEnd', '以下是狐妖小红娘的简介:');
// 使用insertAdjacentElement添加狐妖小红娘的简介
var myDiv = document.getElementById('myDiv');
var introPara = document.createElement('p');
var introText = document.createTextNode('《狐妖小红娘》是一部描写狐妖与人类之间的爱情故事的动漫作品。');
introPara.appendChild(introText);
myDiv.insertAdjacentElement('beforeBegin', introPara);
</script>
</body>
</html>
2.3.2 编写一段兼容性代码,用来设置任意标签的文本内容
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title></title>
</head>
<body>
<a href="https://www.baidu.com" id="a">打开百度,你就知道!</a>
<!-- 在这里写JavaScript代码,因为JavaScript是由上到下执行的 -->
<script>
var a = document.getElementById("a");
setInnerText(a, "你要打开百度吗?");
console.log(getInnerText(a));
/*获取任意标签的内容*/
function getInnerText(element) {
// 判断浏览器是否支持textContent,如果支持,则使用textContent获取内容,否则使用innerText获取内容。
if (typeof element.textContent == "undefined") {
return element.innerText;
} else {
return element.textContent;
}
}
/*设置任意标签的内容*/
function setInnerText(element, text) {
// 判断浏览器是否支持textContent,如果支持,则使用textContent设置内容,否则使用innerText设置内容。
if (typeof element.textContent == "undefined") {
return element.innerText = text;
} else {
return element.textContent = text;
}
}
</script>
</body>
</html>
2.4 修改元素样式
方法 | 描述 |
---|---|
document.createElement(element) | 创建 HTML 元素节点。 |
document.createAttribute(attribute) | 创建 HTML 属性节点。 |
document.createTextNode(text) | 创建 HTML 文本节点。 |
元素节点.removeChild(element) | 删除 HTML 元素。 |
元素节点.appendChild(element) | 添加 HTML 元素。 |
元素节点.replaceChild(element) | 替换 HTML 元素。 |
元素节点.insertBefore(element) | 在指定的子节点前面插入新的子节点。 |
2.4.1兼容性修改样式
动态判断、添加、删除、切换样式,支持IE5-IE11,谷歌浏览器、火狐浏览器等
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title></title>
<style>
.b1 {
width: 100px;
height: 100px;
background-color: red;
}
.b2 {
width: 300px;
height: 300px;
background-color: yellow;
}
</style>
</head>
<body>
<button id="btn0">判断b2样式</button>
<button id="btn1">添加b2样式</button>
<button id="btn2">删除b2样式</button>
<button id="btn3">切换b2样式</button>
<br>
<br>
<div id="box" class="b1"></div>
<!-- 在这里写JavaScript代码,因为JavaScript是由上到下执行的 -->
<script>
var btn0 = document.getElementById("btn0");
var btn1 = document.getElementById("btn1");
var btn2 = document.getElementById("btn2");
var btn3 = document.getElementById("btn3");
var box = document.getElementById("box");
btn0.onclick = function () {
alert(hasClass(box, "b2"));
};
btn1.onclick = function () {
addClass(box, "b2");
};
btn2.onclick = function () {
removeClass(box, "b2");
};
btn3.onclick = function () {
toggleClass(box, "b2");
};
/*
* 判断一个元素中是否含有指定的class属性值
* 如果有该class,则返回true,没有则返回false
*/
function hasClass(obj, cn) {
var reg = new RegExp("\\b" + cn + "\\b");
return reg.test(obj.className);
}
/*
* 向一个元素中添加指定的class属性值
* 参数:
* obj 要添加class属性的元素
* cn 要添加的class值
*/
function addClass(obj, cn) {
// 检查obj中是否含有cn
if (!hasClass(obj, cn)) {
obj.className += " " + cn;
}
}
/*
* 删除一个元素中的指定的class属性
*/
function removeClass(obj, cn) {
var reg = new RegExp("\\b" + cn + "\\b");
obj.className = obj.className.replace(reg, "");
}
/*
* toggleClass可以用来切换一个类
* 如果元素中具有该类,则删除
* 如果元素中没有该类,则添加
*/
function toggleClass(obj, cn) {
// 判断obj中是否含有cn
if (hasClass(obj, cn)) {
// 存在,则删除
removeClass(obj, cn);
} else {
// 没有,则添加
addClass(obj, cn);
}
}
</script>
</body>
</html>
2.5 查找父子节点
下面是利用 DOM 树查找各种节点的常用函数和方法以及它们的返回值和用途的表格展示:
查找函数/方法 | 返回值 | 用途 |
---|---|---|
元素节点 getElementById | 单个元素 | 通过 ID 获取元素 |
getElementsByClassName | 元素集合 | 通过类名获取元素 |
getElementsByTagName | 元素集合 | 通过标签名获取元素 |
querySelector | 单个元素 | 通过选择器获取元素 |
querySelectorAll | 元素集合 | 通过选择器获取元素 |
文本节点 createTextNode | 文本节点 | 创建文本节点 |
nodeValue | 字符串 | 获取/设置节点的文本内容 |
属性节点 getAttribute | 字符串 | 获取元素的属性值 |
setAttribute | 无返回值 | 设置元素的属性值 |
removeAttribute | 无返回值 | 移除元素的属性 |
父节点 parentNode | 元素节点 | 获取元素的父元素 |
parentElement | 元素节点 | 获取元素的父元素 |
子节点 childNodes | 子节点集合 | 获取元素的所有子节点 |
children | 元素节点集合 | 获取元素的所有子元素 |
firstChild | 子节点 | 获取元素的第一个子节点 |
firstElementChild | 元素节点 | 获取元素的第一个子元素 |
lastChild | 子节点 | 获取元素的最后一个子节点 |
lastElementChild | 元素节点 | 获取元素的最后一个子元素 |
nextSibling | 兄弟节点 | 获取元素的下一个兄弟节点 |
nextElementSibling | 元素节点 | 获取元素的下一个兄弟元素 |
previousSibling | 兄弟节点 | 获取元素的上一个兄弟节点 |
previousElementSibling | 元素节点 | 获取元素的上一个兄弟元素 |
创建节点 createElement | 元素节点 | 创建新的元素节点 |
createAttribute | 属性节点 | 创建新的属性节点 |
createComment | 注释节点 | 创建新的注释节点 |
createDocumentFragment | 文档片段节点 | 创建新的文档片段节点 |
插入节点 appendChild | 子节点 | 将新的子节点添加到元素的子节点列表的末尾 |
insertBefore | 子节点 | 将新的子节点插入到指定位置之前 |
删除节点 removeChild | 子节点 | 从元素的子节点列表中删除一个子节点 |
replaceChild | 子节点 | 替换元素的子节点 |
remove | 无返回值 | 从其父元素中删除当前节点 |
使用这些函数和方法,我们可以在 DOM 树中找到并操作各种类型的节点。
2.5.1 兼容性方法
/*获取任意一个父级元素的第一个子元素*/
function getfirstElementChild(element) {
if(element.firstElementChild) {
return element.firstElementChild;
} else {
var node = element.firstChild;
while(node && node.nodeType != 1) {
node = node.nextSibling;
}
return node;
}
}
/*获取任意一个父级元素的最后一个子元素*/
function getLastElementChild(element) {
if(element.lastElementChild) {
return element.lastElementChild;
} else {
var node = element.lastChild;
while(node && node.nodeType != 1) {
node = node.previousSibling;
}
return node;
}
}
/*获取任意一个子元素的前一个兄弟元素*/
function getPreviousElementSibling(element) {
if(element.previousElementSibling) {
return element.previousElementSibling;
} else {
var node = element.previousSibling;
while(node && node.nodeType != 1) {
node = node.previousSibling;
}
return node;
}
}
/*获取任意一个子元素的后一个兄弟元素*/
function getNextElementSibling(element) {
if(element.nextElementSibling) {
return element.nextElementSibling;
} else {
var node = element.nextSibling;
while(node && node.nodeType != 1) {
node = node.nextSibling;
}
return node;
}
}
案例演示:
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title></title>
</head>
<body>
<div id="container">
<p>前面的P标签</p>
<b>加粗文本</b>
<a href="https://www.baidu.com" id="a">百度一下</a>
<i>斜体文本</i>
<p>最后的P标签</p>
</div>
<!-- 在这里写JavaScript代码,因为JavaScript是由上到下执行的 -->
<script>
/*第一个子元素*/
var firstNode = getfirstElementChild(document.getElementById("container"));
console.log(firstNode.innerHTML);
/*最后一个子元素*/
var lastNode = getLastElementChild(document.getElementById("container"));
console.log(lastNode.innerHTML);
/*指定元素的前一个子元素*/
var node1 = getPreviousElementSibling(document.getElementById("a"));
console.log(node1.innerHTML);
/*指定元素的后一个子元素*/
var node2 = getNextElementSibling(document.getElementById("a"));
console.log(node2.innerHTML);
/*获取任意一个父级元素的第一个子元素*/
function getfirstElementChild(element) {
if (element.firstElementChild) {
return element.firstElementChild;
} else {
var node = element.firstChild;
while (node && node.nodeType != 1) {
node = node.nextSibling;
}
return node;
}
}
/*获取任意一个父级元素的最后一个子元素*/
function getLastElementChild(element) {
if (element.lastElementChild) {
return element.lastElementChild;
} else {
var node = element.lastChild;
while (node && node.nodeType != 1) {
node = node.previousSibling;
}
return node;
}
}
/*获取任意一个子元素的前一个兄弟元素*/
function getPreviousElementSibling(element) {
if (element.previousElementSibling) {
return element.previousElementSibling;
} else {
var node = element.previousSibling;
while (node && node.nodeType != 1) {
node = node.previousSibling;
}
return node;
}
}
/*获取任意一个子元素的后一个兄弟元素*/
function getNextElementSibling(element) {
if (element.nextElementSibling) {
return element.nextElementSibling;
} else {
var node = element.nextSibling;
while (node && node.nodeType != 1) {
node = node.nextSibling;
}
return node;
}
}
</script>
</body>
</html>
03 dom文档事件流
3.1 事件简述
DOM 事件模型是指当网页中发生某些特定的事件时,浏览器会自动创建一个事件对象,并将该事件对象传递给相关的 JavaScript 代码,以便处理该事件。事件模型分为三个阶段:捕获阶段、目标阶段和冒泡阶段。
- 常见的 DOM 事件包括:
- 鼠标事件:click、dblclick、mousedown、mouseup、mousemove、mouseover、mouseout、mouseenter、mouseleave 等;
- 键盘事件:keydown、keyup、keypress 等;
- 表单事件:submit、reset、focus、blur、change 等;
- 窗口事件:load、unload、resize、scroll 等;
- 手机事件:touchstart、touchmove、touchend 等。
- DOM 事件处理的方式有两种:传统的事件处理方式和现代的事件处理方式。
传统的事件处理方式是在 HTML 元素中通过属性绑定事件处理函数,如:
<button onclick="alert('Hello World!')">点击我</button>
这种方式的缺点是不易于维护和扩展,因为代码和 HTML 元素紧密耦合在一起。
现代的事件处理方式是通过 JavaScript 代码动态地绑定事件处理函数,如:
const button = document.querySelector('button');
button.addEventListener('click', function() {
alert('Hello World!');
});
这种方式可以让代码和 HTML 元素分离,更易于维护和扩展。
- 事件处理函数的基本语法如下:
element.addEventListener(event, function, useCapture);
其中,element 是要绑定事件处理函数的 HTML 元素;event 是要绑定的事件名称,如 click、mousemove 等;function 是事件处理函数,可以是已经定义的函数或匿名函数;useCapture 是一个可选的布尔值,表示事件处理是否在捕获阶段执行,默认为 false,即在冒泡阶段执行。
事件处理函数中的 this 关键字指向触发事件的 HTML 元素,event 对象包含有关事件的详细信息,如事件类型、事件目标、事件发生的时间等。可以通过 event 对象的属性和方法获取这些信息,如 event.type、event.target、event.timeStamp 等。
- 除了使用
addEventListener
方法绑定事件处理函数之外,还可以使用removeEventListener
方法取消事件处理函数的绑定,如:
button.removeEventListener('click', handleClick);
其中,handleClick 是要取消绑定的事件处理函数。需要注意的是,在使用 removeEventListener 方法取消绑定时,要确保传入的事件处理函数和之前绑定的事件处理函数是同一个函数,否则无法取消绑定。
3.2 窗口事件
由窗口触发该事件 (同样适用于 标签):
属性 | 描述 |
---|---|
onblur | 当窗口失去焦点时运行脚本。 |
onfocus | 当窗口获得焦点时运行脚本。 |
onload | 当文档加载之后运行脚本。 |
onresize | 当调整窗口大小时运行脚本。 |
onstorage | 当 Web Storage 区域更新时(存储空间中的数据发生变化时)运行脚本。 |
3.2.1 标签失去焦点
案例演示:
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>示例页面</title>
</head>
<body>
<h1>欢迎访问示例页面</h1>
<p>请输入您的姓名:</p>
<input type="text" id="myInput">
<script>
const myInput = document.getElementById('myInput');
myInput.addEventListener('blur', function() {
alert('您已离开该目标');
});
</script>
</body>
</html>
3.3 表单事件
表单事件在HTML表单中触发 (适用于所有 HTML 元素,但该HTML元素需在form表单内):
属性 | 描述 |
---|---|
onblur | 当元素失去焦点时运行脚本。 |
onfocus | 当元素获得焦点时运行脚本。 |
onchange | 当元素改变时运行脚本。 |
oninput | 当元素获得用户输入时运行脚本。 |
oninvalid | 当元素无效时运行脚本。 |
onselect | 当选取元素时运行脚本。 |
onsubmit | 当提交表单时运行脚本。 |
如果单击“submit”,则不填写文本字段,将发生警报消息。案例演示:
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title></title>
</head>
<body>
<form>
<input type="text" id="text" required>
<input type="submit" value="submit">
</form>
<!-- 在这里写JavaScript代码,因为JavaScript是由上到下执行的 -->
<script>
var textInput = document.getElementById("text");
/* 如果单击“submit”,则不填写文本字段,将发生警报消息 */
textInput.oninvalid = function () {
console.log("请您完善表单内容!");
};
</script>
</body>
</html>
3.4 键盘事件
属性 | 描述 |
---|---|
onkeydown | 当按下按键时运行脚本。 |
onkeyup | 当松开按键时运行脚本。 |
onkeypress | 当按下并松开按键时运行脚本。 |
补充:
事件名称 | 触发条件 | 相关事件属性 |
---|---|---|
keydown | 按下任意键时触发 | event.key、event.code、event.keyCode、event.shiftKey、event.ctrlKey、event.altKey |
keyup | 松开任意键时触发 | event.key、event.code、event.keyCode、event.shiftKey、event.ctrlKey、event.altKey |
keypress | 按下并松开某个键时触发 | event.key、event.code、event.charCode |
其中,event.key 表示按下或松开的键的名称(例如,a、Shift、Enter),event.code 表示按下或松开的键的标准键码(例如,KeyA、ShiftLeft、Enter),event.keyCode 表示按下或松开的键的 ASCII 码(仅适用于部分键),event.shiftKey、event.ctrlKey、event.altKey 分别表示 Shift、Ctrl 和 Alt 键是否被按下。
注意:event.keyCode 已经被废弃,推荐使用 event.key 或 event.code。
以上是常用的键盘事件代码和相关事件属性。在实际应用中,可以根据需求选择相应的事件类型和事件属性来处理键盘事件。
3.4.1 键盘实现元素块的移动
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title></title>
</head>
<body>
<div id="box" style="width: 100px;height: 100px;background: red;position: absolute;"></div>
<!-- 在这里写JavaScript代码,因为JavaScript是由上到下执行的 -->
<script>
var box = document.getElementById("box");
//为document绑定一个按键按下的事件
document.onkeydown = function (event) {
event = event || window.event;
// 定义移动速度
var speed = 10;
// 选择移动方向
switch (event.keyCode) {
case 37:
box.style.left = box.offsetLeft - speed + "px";
break;
case 39:
box.style.left = box.offsetLeft + speed + "px";
break;
case 38:
box.style.top = box.offsetTop - speed + "px";
break;
case 40:
box.style.top = box.offsetTop + speed + "px";
break;
}
};
</script>
</body>
</html>
3.5 鼠标事件
属性 | 描述 |
---|---|
onclick | 当单击鼠标时运行脚本。 |
ondblclick | 当双击鼠标时运行脚本。 |
onmousedown | 当按下鼠标按钮时运行脚本。 |
onmouseup | 当松开鼠标按钮时运行脚本。 |
onmousemove | 当鼠标指针移动时运行脚本。 |
onmouseover | 当鼠标指针移至元素之上时运行脚本,不可以阻止冒泡。 |
onmouseout | 当鼠标指针移出元素时运行脚本,不可以阻止冒泡。 |
onmouseenter | 当鼠标指针移至元素之上时运行脚本,可以阻止冒泡。 |
onmouseleave | 当鼠标指针移出元素时运行脚本,可以阻止冒泡。 |
onmousewheel | 当转动鼠标滚轮时运行脚本。 |
onscroll | 当滚动元素的滚动条时运行脚本。 |
3.5.1 鼠标实现拖曳元素快
案例演示2:编写一个通用的拖拽元素函数,创建两个div,进行拖拽演示,要求兼容IE8、火狐、谷歌等主流浏览器
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title></title>
</head>
<body>
<div id="box1" style="width: 100px;height: 100px;background: red;position: absolute;"></div>
<div id="box2" style="width: 100px;height: 100px;background: green;position: absolute;"></div>
<!-- 在这里写JavaScript代码,因为JavaScript是由上到下执行的 -->
<script>
var box1 = document.getElementById("box1");
var box2 = document.getElementById("box2");
drag(box1);
drag(box2);
/*
* 提取一个专门用来设置拖拽的函数
* 参数:开启拖拽的元素
*/
function drag(obj) {
//当鼠标在被拖拽元素上按下时,开始拖拽
obj.onmousedown = function (event) {
// 解决事件的兼容性问题
event = event || window.event;
// 设置obj捕获所有鼠标按下的事件
/**
* setCapture():
* 只有IE支持,但是在火狐中调用时不会报错,
* 而如果使用chrome调用,它也会报错
*/
obj.setCapture && obj.setCapture();
// obj的偏移量 鼠标.clentX - 元素.offsetLeft
// obj的偏移量 鼠标.clentY - 元素.offsetTop
var ol = event.clientX - obj.offsetLeft;
var ot = event.clientY - obj.offsetTop;
// 为document绑定一个鼠标移动事件
document.onmousemove = function (event) {
// 解决事件的兼容性问题
event = event || window.event;
// 当鼠标移动时被拖拽元素跟随鼠标移动
// 获取鼠标的坐标
var left = event.clientX - ol;
var top = event.clientY - ot;
// 修改obj的位置
obj.style.left = left + "px";
obj.style.top = top + "px";
};
// 为document绑定一个鼠标松开事件
document.onmouseup = function () {
// 取消document的onmousemove事件
document.onmousemove = null;
// 取消document的onmouseup事件
document.onmouseup = null;
// 当鼠标松开时,取消对事件的捕获
obj.releaseCapture && obj.releaseCapture();
};
/*
* 当我们拖拽一个网页中的内容时,浏览器会默认去搜索引擎中搜索内容,
* 此时会导致拖拽功能的异常,这个是浏览器提供的默认行为,
* 如果不希望发生这个行为,则可以通过return false来取消默认行为,
* 但是这招对IE8不起作用
*/
return false;
};
}
</script>
</body>
</html>
3.5.2 拖曳元素进行身份验证
实现拖拽验证身份信息的思路是,将需要拖拽的元素设置为可拖拽(draggable),然后在拖拽开始、拖拽过程和拖拽结束三个阶段分别监听相关事件,处理事件响应。具体步骤如下:
在 HTML 中定义需要拖拽的元素和放置元素;其中,id 为 draggable 的 div 元素是需要被拖拽的元素,设置 draggable 属性为 true 表示该元素可拖拽;id 为 droppable 的 div 元素是需要放置的元素。
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>拖拽验证身份信息</title>
<style>
#draggable {
width: 100px;
height: 100px;
background-color: #6aa84f;
color: #fff;
text-align: center;
line-height: 100px;
cursor: move;
}
#droppable {
width: 200px;
height: 200px;
border: 2px dashed #ccc;
margin-top: 20px;
}
#droppable.droppable-hover {
background-color: #ddd;
}
#message {
display: none;
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
background-color: #6aa84f;
color: #fff;
text-align: center;
padding: 20px;
font-size: 18px;
border-radius: 10px;
box-shadow: 2px 2px 2px #ccc;
}
</style>
</head>
<body>
<div id="draggable" draggable="true">拖拽我</div>
<div id="droppable">放置在此处</div>
<div id="message">身份验证成功!</div>
<script>
const draggable = document.getElementById('draggable');
const droppable = document.getElementById('droppable');
const message = document.getElementById('message');
let isDragging = false;
draggable.addEventListener('dragstart', function(event) {
isDragging = true;
event.dataTransfer.setData('text/plain', 'identity');
});
droppable.addEventListener('dragenter', function(event) {
if (isDragging) {
droppable.classList.add('droppable-hover');
}
});
droppable.addEventListener('dragover', function(event) {
event.preventDefault();
});
droppable.addEventListener('dragleave', function(event) {
droppable.classList.remove('droppable-hover');
});
droppable.addEventListener('drop', function(event) {
event.preventDefault();
droppable.classList.remove('droppable-hover');
const draggedItem = event.dataTransfer.getData('text/plain');
if (draggedItem === 'identity') {
message.style.display = 'block';
}
});
</script>
</body>
</html>
其中,dragstart、drag、dragend 分别表示拖拽开始、拖拽过程和拖拽结束;dragenter、dragover、dragleave 和 drop 分别表示拖拽元素进入放置区域、在放置区域中移动、离开放置区域和放置拖拽元素到目标元素中。
需要注意的是,在 dragover 事件中需要调用 event.preventDefault(),防止浏览器默认行为,使得拖拽操作可以被放置到目标元素中。
3.6 媒体事件
通过视频(videos),图像(images)或音频(audio) 触发该事件。
属性 | 描述 |
---|---|
onabort | 当发生中止事件时运行脚本。 |
oncanplay | 当媒介能够开始播放但可能因缓冲而需要停止时运行脚本。 |
oncanplaythrough | 当媒介能够无需因缓冲而停止即可播放至结尾时运行脚本。 |
ondurationchange | 当媒介长度改变时运行脚本。 |
onemptied | 当媒介资源元素突然为空时(网络错误、加载错误等)运行脚本。 |
onended | 当媒介已抵达结尾时运行脚本。 |
onerror | 当在元素加载期间发生错误时运行脚本。 |
onloadeddata | 当加载媒介数据时运行脚本。 |
onloadedmetadata | 当媒介元素的持续时间以及其它媒介数据已加载时运行脚本。 |
onloadstart | 当浏览器开始加载媒介数据时运行脚本。 |
onpause | 当媒介数据暂停时运行脚本。 |
onplay | 当媒介数据将要开始播放时运行脚本。 |
onplaying | 当媒介数据已开始播放时运行脚本。 |
onprogress | 当浏览器正在取媒介数据时运行脚本。 |
onratechange | 当媒介数据的播放速率改变时运行脚本。 |
onreadystatechange | 当就绪状态(ready-state)改变时运行脚本。 |
onseeked | 当媒介元素的定位属性不再为真且定位已结束时运行脚本。 |
onseeking | 当媒介元素的定位属性为真且定位已开始时运行脚本。 |
onstalled | 当取回媒介数据过程中(延迟)存在错误时运行脚本。 |
onsuspend | 当浏览器已在取媒介数据但在取回整个媒介文件之前停止时运行脚本。 |
ontimeupdate | 当媒介改变其播放位置时运行脚本。 |
onvolumechange | 当媒介改变音量亦或当音量被设置为静音时运行脚本。 |
onwaiting | 当媒介已停止播放但打算继续播放时运行脚本。 |
3.7 其它事件以及概念补充
属性 | 描述 |
---|---|
onshow | 当<menu> 元素在上下文显示时触发。 |
ontoggle | 当用户打开或关闭 <details> 元素时触发。 |
事件是 Web 应用程序中最重要的交互机制之一。当用户与网页进行交互时(比如点击按钮、拖拽元素、滚动页面等),浏览器会触发相应的事件,并将事件传递给网页的 JavaScript 代码处理。事件的处理方式包括事件绑定、事件委派、事件解绑等。下面是一些与事件处理相关的常用概念的解释:
- 事件捕获(Event Capturing):事件从文档根节点开始往下传递到目标元素之前,会先经过文档根节点、HTML 元素、body 元素、父元素等节点,这个过程称为事件捕获。事件捕获的处理函数会在目标元素的事件处理函数之前被触发。
- 事件目标(Event Target):事件目标是指用户与之交互的元素。例如,当用户点击一个按钮时,该按钮就是事件目标。
- 事件冒泡(Event Bubbling):事件从目标元素开始往上冒泡到文档根节点之前,会经过目标元素的父元素、body 元素、HTML 元素、文档根节点等节点,这个过程称为事件冒泡。
事件冒泡的处理函数会在目标元素的事件处理函数之后被触发。
- 事件委派(Event Delegation):事件委派是一种利用事件冒泡机制,在父元素上绑定事件处理函数,而不是在子元素上绑定事件处理函数。当子元素触发事件时,事件会冒泡到父元素,由父元素上的事件处理函数处理。这种方式可以减少事件处理函数的数量,提高页面性能。
- 事件绑定(Event Binding):事件绑定是指将事件处理函数绑定到一个元素上,当该元素触发相应的事件时,该事件处理函数会被执行。事件绑定通常使用
addEventListener()
方法实现。 - 事件传播(Event Propagation):事件传播是指事件从目标元素开始往上冒泡到文档根节点或者往下传递到子元素。事件传播包括事件捕获、事件目标、事件冒泡三个阶段。
- 微软公司认为事件应该是由内向外传播,也就是当事件触发时,应该先触发当前元素上的事件,然后再向当前元素的祖先元素上传播,也就说事件应该在冒泡阶段执行。
- 网景公司认为事件应该是由外向内传播的,也就是当前事件触发时,应该先触发当前元素的最外层的祖先元素的事件,然后在向内传播给后代元素。
- 事件解绑(Event Unbinding):事件解绑是指将事件处理函数从一个元素上移除,该元素不再响应相应的事件。事件解绑通常使用
removeEventListener()
方法实现。
以上是与事件处理相关的一些常用概念的解释。在实际应用中,根据需要选择不同的事件处理方式可以使页面交互更加灵活和高效。
3.7.1 阻止超链接跳转
代码演示:
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title></title>
<style>
#div1 {
width: 200px;
height: 200px;
background: pink;
}
#div2 {
width: 100px;
height: 100px;
background: coral;
}
</style>
</head>
<body>
<a href="https://www.baidu.com" id="a">打开百度,你就知道!</a>
<!-- 在这里写JavaScript代码,因为JavaScript是由上到下执行的 -->
<script>
var a = document.getElementById("a");
// 为a绑定单击事件
a.onclick = function () {
stopDefault();
};
// 阻止浏览器的默认行为
function stopDefault(event) {
if (event && event.preventDefault) {
// 阻止默认浏览器动作(W3C)
event.preventDefault();
} else {
// IE中阻止函数器默认动作的方式
window.event.returnValue = false;
}
return false;
}
</script>
</body>
</html>
04 BOM树
4.1 BOM模型
浏览器对象模型(BOM)可以使我们通过JS来操作浏览器,在BOM中为我们提供了一组对象,用来完成对浏览器的操作,常见的BOM对象如下:
- Window:代表的是整个浏览器的窗口,同时window也是网页中的全局对象
- Navigator:代表的当前浏览器的信息,通过该对象可以来识别不同的浏览器
- Location:代表当前浏览器的地址栏信息,通过Location可以获取地址栏信息,或者操作浏览器跳转页面
- History:代表浏览器的历史记录,可以通过该对象来操作浏览器的历史记录,由于隐私原因,该对象不能获取到具体的历史记录,只能操作浏览器向前或向后翻页,而且该操作只在当次访问时有效
- Screen:代表用户的屏幕的信息,通过该对象可以获取到用户的显示器的相关的信息
4.2 常用的一些脚本操作
操作 | 描述 |
---|---|
window.open() | 打开新窗口或标签页。 |
window.close() | 关闭当前窗口或标签页。 |
window.location.href | 获取或设置当前窗口的 URL。 |
window.history.back() | 返回上一页。 |
window.history.forward() | 前往下一页。 |
window.navigator.userAgent | 获取用户代理信息。 |
window.navigator.cookieEnabled | 判断浏览器是否启用 cookie。 |
window.screen.width | 获取屏幕宽度。 |
window.screen.height | 获取屏幕高度。 |
window.document.cookie | 获取或设置当前窗口的 cookie。 |
注意:上述表格中仅列出了常用的一些操作,具体的应用还需要根据具体需求进行选择。剩下的平时也不太用的上,这里不做赘述。