幾乎所有的瀏覽器都內(nèi)嵌了javaScript引擎,使得javaScript語言能夠在瀏覽器環(huán)境下運行。 那么,如果要使用javaScript語言來操作瀏覽器中的各種對象,就需要使用BOM模型與DOM模型。
- 瀏覽器對象模型BOM(Browser Object Model): 提供了獨立于內(nèi)容的、可以與瀏覽器窗口進行互動的對象結(jié)構(gòu)。
-
文檔對象模型DOM(Document Object Model): 定義訪問和處理HTML文檔的標準方法。DOM 將HTML文檔呈現(xiàn)為帶有元素、屬性和文本的樹結(jié)構(gòu)(節(jié)點樹)。
DOM模型.png
4.1 獲取DOM對象常用方法
- getElementById() 通過元素的ID屬性獲取DOM對象,獲取的是一個DOM對象。
- getElementsByTagName() 通過元素的標簽名獲取DOM對象,獲取的是一組DOM對象。
- getElementsByClassName() 通過元素的class屬性獲取DOM對象,獲取的是一組DOM對象。
- getElementsByName() 通過元素的name屬性獲取DOM對象,獲取的是一組DOM對象。
<p id="one">這是一個p標簽</p>
<p class="first">這是一個p標簽</p>
<p class="first">這是一個p標簽</p>
<p name="username">這是一個p標簽</p>
<p name="username">這是一個p標簽</p>
<script>
let oneObj = document.getElementById('one');
oneObj.style.color = 'red'; //只有第一個p標簽字體變紅色
let pArr = document.getElementsByTagName('p');
console.log(pArr.length); //獲取所有p標簽對象,是數(shù)組,長度為5
let firstArr = document.getElementsByClassName('first');
console.log(firstArr.length); //獲取所有class為first的對象,是數(shù)組,長度為2
let userArr = document.getElementsByName('user');
console.log(userArr.length); //獲取所有name屬性為user的對象,是數(shù)組,長度為2
</script>
4.2 獲取DOM對象其他方法
- document.documentElement 獲取html對象
- document.body 獲取body對象
- document.querySelector() 通過選擇器獲取一個DOM對象
- document.querySelectorAll() 通過選擇器獲取一組DOM對象
<div>
<p>這是一個p標簽</p>
<p>這是一個p標簽</p>
</div>
<script>
let htmlObj = document.documentElement;
htmlObj.style.backgroundColor = 'red'; //設置html背景色
let bodyObj = document.body;
bodyObj.style.fontSize = '36px'; //設置body中所有元素的字體大小
let pObj = document.querySelector('div p');
pObj.style.color = 'blue'; //第一個p標簽有效
let pArr = document.querySelectorAll('div p');
console.log(pArr.length); //數(shù)組長度為2
</script>
4.3 獲取DOM對象的時機
- javaScript代碼要寫在body的最后。必須要保證html代碼全部加載完畢之后,才執(zhí)行javaScript代碼,才能獲取DOM對象。
- 如果一定要將javaScript代碼放在html之前那么要做如下寫法:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title>獲取DOM對象的時機</title>
<script>
//等待頁面加載完畢,再去執(zhí)行function里面的代碼
window.onload = function(){
let pobj = document.getElementById('one')
pobj.innerHTML = '<span>hello</span>'
}
</script>
</head>
<body>
<p id='one'></p>
</script> -->
</body>
</html>
4.4 操作DOM對象的屬性
(1)通過DOM對象直接操作屬性:
<p>hello world</p>
<input type="text">
<script>
document.getElementsByTagName('p')[0].title = 'aaaa';
let userName = document.getElementsByTagName('input')[0];
userName.value = 'zhangsan';
userName.disabled = true;
</script>
(2)通過DOM對象中封裝的方法操作屬性 :
setAttribute() 設置元素的屬性值
getAttribute() 獲取元素的屬性值
removeAttribute() 移除元素的屬性值
<p>hello world</p>
<input type="text">
<script>
document.getElementsByTagName('p')[0].setAttribute('title','aaaa');
let userName = document.getElementsByTagName('input')[0];
userName.setAttribute('value','zhangsan');
userName.setAttribute('disabled',true);
userName.removeAttribute('disabled');
console.log(userName.getAttribute('value'))
</script>
4.5 DOM對象中的常用屬性
(1)innerHTML屬性:用于設置或獲取HTML 元素中的內(nèi)容。
<p id="one">
<span>這是一個段落</span>
</p>
<script>
let obj = document.getElementById('one');
console.log(obj.innerHTML); //<span>這是一個段落</span>
obj.innerHTML = '<span>hello world!</span>';
</script>
(2)innerText屬性:用于設置或獲取HTML 元素中的純文本。
<p id="one">
<span>這是一個段落</span>
</p>
<script>
let obj = document.getElementById('one');
console.log(obj.innerText); //這是一個段落
obj.innerText = 'hello world!';
</script>
(3)className屬性:用于設置或獲取DOM對象的類樣式
<div id="one" class="first"></div>
<script>
let obj = document.getElementById('one');
console.log(obj.className); //first
obj.className = 'two';
</script>
(4)style屬性:用于設置或獲取DOM對象的style樣式
<div id="one">我是一個div</div>
<script>
let obj = document.getElementById('one');
obj.style.width = '300px';
obj.style.height = '200px';
obj.style.backgroundColor = 'blue';
obj.style.fontSize = '24px';
obj.style.color = '#fff';
obj.style.border = 'solid 10px red';
obj.style.display = 'block'; //設置DOM對象的顯示和隱藏
</script>
4.6 遍歷DOM數(shù)組
<p>我是p標簽</p>
<p>我是p標簽</p>
<p>我是p標簽</p>
<script>
let arr = document.getElementsByTagName('p');
for(let i=0;i<arr.length;i++){
arr[i].style.color = 'red';
arr[i].style.fontSize = '36px';
}
</script>
4.7 DOM編程
-
事件
| 事件 | 說明 |
|---|---|
| onload | 頁面加載完成后觸發(fā)該事件(window對象事件) |
| onscroll | 當滾動條滾動時觸發(fā)該事件(window對象事件) |
| onresize | 當頁面尺寸發(fā)生變化時觸發(fā)該事件(window對象事件) |
| onclick | 鼠標單擊時觸發(fā)該事件 |
| onmouseover | 鼠標移入到指定對象上時觸發(fā)該事件(鼠標懸停) |
| onmouseout | 鼠標從指定對象上移出時觸發(fā)該事件(鼠標移出) |
| onmousemove | 鼠標在指定對象上移動時觸發(fā)該事件(鼠標移動,會觸發(fā)多次) |
| onfocus | 對象獲得光標(焦點)時觸發(fā)該事件 |
| onblur | 對象失去光標(焦點)時觸發(fā)該事件 |
| onselect | 當文本框或文本域中的文字被選中時觸發(fā)該事件 |
| onchange | 當文本框或文本域中的文字被改變時觸發(fā)該事件 |
| onkeydown | 當按下鍵盤上的按鈕時觸發(fā)該事件(document對象事件) |
| onkeyup | 當釋放鍵盤上的按鈕時觸發(fā)該事件(document對象事件 |
| onkeypress | onkeydown+onkeyup(document對象事件 |
| oncontextmenu | 鼠標右鍵菜單事件 |
-
JavaScript中綁定事件方式
- 侵入式事件方式:將javaScript事件直接寫在html標簽中
<div onclick="add()">點我</div>
<script>
//事件處理函數(shù)
function add(){
console.log('點擊了div對象');
}
</script>
注意:此種方式的缺點是:javaScript事件與HTML代碼混雜在一起。
- 綁定式事件方式:通過DOM對象,使用javaScript代碼綁定一個事件
<div>點我</div>
<script>
let divObj = document.getElementsByTagName('div')[0];
//function()匿名函數(shù)就是事件處理函數(shù)
divObj.onclick = function(){
console.log('點擊了div對象');
}
</script>
注意:此種方式的優(yōu)點是:
1. 行間和事件分離。
2. 可以給元素動態(tài)添加事件。
- 監(jiān)聽函數(shù)式事件方式:
<div>點我</div>
<script>
let divObj = document.getElementsByTagName('div')[0];
divObj.addEventListener('click',function(){
console.log('點擊了div對象');
},false);
</script>
注意:addEventListener函數(shù)的三個參數(shù):
1. 事件名(沒有前綴on)。
2. 事件處理函數(shù)。
3. 布爾類型(一般為false)。true:進行事件捕獲; false:不進行事件捕獲;
-
對象事件-event
| 屬性 | 說明 |
|---|---|
| clientX | 獲取相對于可視區(qū)域內(nèi)鼠標的X坐標 |
| clientY | 獲取相對于可視區(qū)域內(nèi)鼠標的Y坐標 |
| offsetX | 獲取相對于觸發(fā)事件對象上鼠標的X坐標 |
| offsetY | 獲取相對于觸發(fā)事件對象上鼠標的Y坐標 |
| cancelBubble | 阻止事件冒泡 |
| preventDefault | 阻止默認行為 |
| keyCode | 獲取用戶按鍵值 |
| target | 當前事件對象 |
- 鼠標坐標的使用
<head>
<meta charset="utf-8">
<title></title>
<style>
div{
width: 200px;
height: 200px;
background-color: blue;
margin: 100px;
}
</style>
</head>
<body>
<div><div>
<script>
document.getElementsByTagName('div')[0].onmousemove = function(event){
console.log('相對視口坐標:'+event.clientX+','+event.clientY);
console.log('相對觸發(fā)事件對象坐標:'+event.offsetX+','+event.offsetY);
}
</script>
</body>
- keyCode的使用
//獲取鍵盤按鍵的keyCode
document.onkeydown = function(event){
console.log(event.keyCode);
}
常用按鍵的keyCode值:回車13, 空格32,上38,下40,左37,右39
-
事件冒泡與事件捕獲
在頁面上的一塊可視區(qū)域中,其中可能會包括父元素可視區(qū)域與子元素可視區(qū)域。
此時,如果用戶觸發(fā)了子元素的某個事件,而父元素也具有相同的事件,那么事實上,我們并不能確定:用戶到底是想觸發(fā)子元素事件,還是想觸發(fā)父元素事件。
解決這個問題的思路是設計兩種事件流:當用戶觸發(fā)了子元素事件時,先觸發(fā)子元素事件,再觸發(fā)父元素事件。這就是事件冒泡。(默認);當用戶觸發(fā)了子元素事件時,先觸發(fā)父元素事件,再觸發(fā)子元素事件。這就是事件捕獲。
下面演示事件冒泡:
<head>
<style>
div{
width: 200px;
height: 200px;
background-color: red;
}
div p{
width: 100px;
height: 100px;
background-color: blue;
}
</style>
</head>
<body>
<div>
<p></p>
</div>
<script>
let divObj = document.getElementsByTagName('div')[0];
let pObj = divObj.getElementsByTagName('p')[0];
divObj.onclick = function(){
alert('父元素的點擊事件被觸發(fā)');
}
pObj.onclick = function(){
alert('子元素的點擊事件被觸發(fā)');
}
</script>
</body>
<!--阻止事件冒泡-->
event.cancelBubble = true;
pObj.onclick = function(event){
alert('子元素的點擊事件被觸發(fā)');
event.cancelBubble = true;
}
- 瀏覽器默認行為
<!DOCTYPE html>
<html>
<head>
<title>瀏覽器默認行為</title>
</head>
<body>
<ul id="one">
<li>復制</li>
<li>粘貼</li>
<li>剪切</li>
<li>刪除</li>
</ul>
<script>
let ulObj = document.getElementById('one')
ulObj.style.border = 'solid 1px #666666' //實線邊框
ulObj.style.width = '120px' //寬度
ulObj.style.display = 'none' //隱藏
ulObj.style.position = 'absolute';
document.oncontextmenu = function(event){
ulObj.style.display = 'block'; //顯示
event.preventDefault(); //取消瀏覽器默認事件
ulObj.style.left = event.clientX+'px'; //指定定位跟鼠標點定位一致
ulObj.style.top = event.clientY+'px';
}
ulObj.onclick = function(){
this.style.display = 'none';//隱藏
}
</script>
</body>
</html>
