JavaScript的DOM,BOM簡單介紹
阿新 • • 發佈:2020-12-14
技術標籤:JavaScriptjs
JavaScript能幹什麼
html:決定網頁的結構(腦袋,身體,手腳)
css:決定網頁的佈局及樣式(高矮,胖瘦,黑白)
JavaScript:定義網頁的行為(走路,跑步,眨眼)
所以它究竟能幹什麼?
- 可以新增或刪除HTML元素,改變其內容,屬性和樣式
- 對頁面所有的事件作出反應,實現頁面與使用者之間實時、動態互動,如使用者註冊,登入驗證
- 增強頁面動態效果,如下拉選單,圖片輪播,資訊滾動
- 可以操作資料庫,寫動畫,寫遊戲,做一些網頁特效
- …
DOM(文件物件模型)
當網頁被載入時,瀏覽器會建立頁面的文件物件模型(Document Object Model)。HTML DOM模型被構造成物件的樹,頁面的每一個組成部分都是一種節點,包含不同的資料:
通過DOM樹,開發者可以隨心所欲地控制網頁內容和結構,並輕鬆地刪除、新增、替換、修改節點。
節點介紹
- 節點的種類主要分為三種:元素節點,文字節點,屬性節點
- 節點關係:兄弟關係,父子關係
獲取元素節點
<div class="intro" id="box"></div>
- 通過元素的id:var x = document.getElementById(“box”);
- 通過標籤名:var y = document.getElementsByTagName(“div”);
- 通過類名:var z = document.getElementsByClassName(“intro”);
改變元素內容,屬性,樣式
- 直接向HTML輸出流寫內容:document.write(“想寫入的內容”);
- 修改HTML內容(要先獲取元素):document.getElementById(“box”).innerHTML = “新文字”;
- 修改HTML元素屬性:document.getElementById(“box”).attribute = 新屬性值;
- 修改元素樣式:document.getElementById(id).style.property = 新樣式;
注:
- 所謂的輸出流,就是HTML渲染頁面,實現輸出的過程。HTML的載入過程是由上至下的,當遇到js指令碼時,頁面載入會被阻塞,瀏覽器會先去下載js指令碼,當js指令碼執行完之後,再繼續渲染頁面。
- 絕對不要在文件(DOM)載入完成之後使用 document.write(),這會覆蓋該文件。(文件載入後不是指在文件後使用script標籤進行文件內容寫入,而是通過按鈕響應等方式在全部頁面載入完畢之後進行文字寫入)
<span>行內元素</span>
<p id="second">我是唯一的</p>
<div class="box">那我加一</div>
<div class="box">那我加一</div>
<div class="box">那我加一</div>
<a onclick="myFunction()">hello</a><br>
<img id="image" src="gz.jpg" alt="" width="200">
<script>
//獲取元素
var x = document.getElementById('second');
console.log(x);
var y = document.getElementsByTagName("span");
console.log(y);
console.log(y.length);
//y是HTMLCollection物件,類似包含HTML元素的一個數組,但它並不是陣列,你可以通過索引來獲取元素,但無法使用陣列的方法,如pop(),push()等
var z = document.getElementsByClassName("box");
console.log(z);
// z[1].innerHTML = "新文字";
//修改輸出流
document.write("路過");
function myFunction(){
document.write("我會發生覆蓋");
}
//修改屬性
// document.getElementById('image').src = 'th.jpg';
// 修改樣式
// x.style.color = "red";
</script>
DOM事件
- 滑鼠點選,移動事件
- 網頁載入完成觸發事件
- 當輸入欄位被改變及表單提交產生的事件等
<p>冬天了,應該多喝熱水</p>
<button id="myBtn">點這裡</button><br>
<input type="text" id="fname" onchange="upperCase()">
<script>
window.onload = function load(){
alert("載入完成");
}//onload事件在文件載入完成後能立即觸發,所以即使是放頭部也能執行
console.log(document.getElementsByTagName('p')[0].innerHTML);//如果放頭部就會報錯
document.getElementById('myBtn').onclick = function(){
document.getElementsByTagName('p')[0].style.backgroundColor = "yellow";
}
function upperCase(){
var fname = document.getElementById('fname');
fname.value = fname.value.toUpperCase();
}
addEventListener()方法
- addEventListener()方法用於向指定元素新增事件控制代碼
- 語法:element.addEventListener(event, function, useCapture);
- 第一個引數:事件型別,如’click’或’blur’(注意,不能使用"on"字首)
- 第二個引數:事件觸發後呼叫的函式
- 第三個引數:用於描述事件是冒泡還是捕獲(該引數可省略,預設值為 false, 即冒泡傳遞,當值為 true 時, 事件使用捕獲傳遞)
注:
- 該方法可以給一個元素新增多個事件,也可新增多個相同型別的事件,如給一個按鈕新增兩個"click"事件
- 該方法新增的事件控制代碼不會覆蓋已存在的事件控制代碼
- 可通過removeEventListener()方法來移除事件的監聽
事件傳遞定義了元素事件觸發的順序。 如果你將
元素插入到
元素中,使用者點選元素, 哪個元素的 “click” 事件先被觸發呢
- 冒泡:內部元素的事件會先被觸發,然後再觸發外部元素,即:
元素的點選事件先觸發,然後會觸發
元素的點選事件。 - 捕獲:外部元素的事件會先被觸發,然後才會觸發內部元素的事件,即:
元素的點選事件先觸發 ,然後再觸發
元素的點選事件。
<style>
#parent{
background-color: yellow;
width: 500px;
height: 200px;
display: flex;
justify-content: center;
align-items: center;
}
#son{
cursor: pointer;
}
</style>
<div id="parent">
<p id="son">冬天了,應該多喝熱水</p>
</div>
<script>
var x = document.getElementById('parent');
var y = document.getElementById('son');
var p1 = 2;
x.addEventListener('click',function(){
console.log('我是一個div');
},true);
y.addEventListener('click',function(){
console.log('我是一個p標籤');
},true);
</script>
建立,移除,替換元素(節點)
<div id="box">
<p id="p1">這是一個段落</p>
<p id="p2">這是另一個段落</p>
</div>
<script>
//建立新元素
var para = document.createElement("p");
var node = document.createTextNode("這是一個新文字");
para.appendChild(node);
var divBox = document.getElementById("box");
//在最後加入新元素
//divBox.appendChild(para);
//在指定元素前加入新元素
var child = document.getElementById('p1');
// divBox.insertBefore(para,child);
var secchild = document.getElementById('p2');
// divBox.insertBefore(para,secchild);
// 移除已存在的元素
// divBox.removeChild(child);
//child.parentNode.removeChild(child);
//替換元素
//divBox.replaceChild(para,child);
</script>
BOM介紹
瀏覽器物件模型(Browser Object Model (BOM))使 JavaScript 有能力與瀏覽器"對話"。
- 所有瀏覽器都支援 window 物件。它表示瀏覽器視窗。
- 全域性變數是 window 物件的屬性。全域性函式是 window 物件的方法。同時HTML DOM 的 document 也是 window 物件的屬性之一
window.location 物件
- 用於獲得當前頁面的地址 (URL),並把瀏覽器重定向到新的頁面。(可不加window字首)
- location.hostname 返回 web 主機的域名
- location.pathname 返回當前頁面的路徑和檔名
- location.port 返回 web 主機的埠 (80 或 443)
- location.protocol 返回所使用的 web 協議(http: 或 https:)
- location.replace(url) : 通過載入 URL 指定的文件來替換當前文件 ,這個方法是替換當前視窗頁面,前後兩個頁面共用一個視窗,所以是沒有後退返回上一頁的
window.history物件
- 在編寫時可不使用 window 這個字首
- history.back() - 與在瀏覽器點選後退按鈕相同
- history.forward() - 與在瀏覽器中點擊向前按鈕相同
JavaScript彈窗
- JavaScript中三種訊息框:警告框(alert),確認框(confirm),提示框(prompt)
JavaScript計時事件
- setInterval() - 間隔指定的毫秒數不停地執行指定的程式碼。(迴圈執行)
- setTimeout() - 在指定的毫秒數後執行指定程式碼。(延遲執行)
- clearInterval() - 用於停止 setInterval() 方法執行的函式程式碼。
- clearTimeout() - 用於停止setTimeout()方法執行的函式程式碼。
<p>頁面上顯示時鐘:</p>
<p id="demo"></p>
<button onclick="stop()">停止</button>
<script>
var cir = setInterval(getTime,1000);
function getTime(){
var t = new Date();
var time = t.toLocaleTimeString();
document.getElementById("demo").innerHTML = time;
}
function stop(){
clearInterval(cir);
}
</script>
最後敲個小栗子
todolist.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<style>
.bigBox input{
outline: none;
}
.bigBox button{
cursor: pointer;
outline: none;
}
.bigBox{
width: 450px;
min-height: 300px;
height: min-content;
background-color: #F2F3F5;
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%,-50%);
text-align: center;
padding: .5rem;
box-sizing: border-box;
}
h2{
letter-spacing: 0.1em;
}
.bigBox>input{
width: 60%;
border: 1px solid gray;
padding: .3rem .5rem;
}
#add{
border: none;
color: white;
background-color:#1B8FFB;
padding: .3rem;
border-radius: 5px;
}
#delayadd{
padding:.3rem;
border: 1px solid gray;
border-radius: 5px;
}
#allBox > div{
width: calc(100% - 2rem);
background-color: white;
padding: .5rem;
margin: .5rem;
}
#allBox > div::after{
content: "";
display: block;
clear: both;
}
#allBox label{
position: relative;
float: left;
width: 20px;
height: 20px;
border: 1px solid gray;
}
#allBox label input{
border: none;
-webkit-appearance:none ;
}
#allBox label span{
width: 7px;
height: 14px;
border-bottom: 1px solid black;
border-right: 1px solid black;
transform: rotate(45deg);
position: absolute;
top: 2px;
left: 5px;
opacity: 0;
}
#allBox input:checked ~ span{
opacity: 1;
}
#allBox div>span{
font-size: 1rem;
float: left;
margin-left:.5rem ;
}
#allBox button{
float: right;
color: red;
border-radius: 50%;
border: 1px solid gray;
outline: none;
}
</style>
</head>
<body>
<div class="bigBox">
<h2>Todolist</h2>
<input type="text" id="inputElt" placeholder="請輸入待辦事項">
<button id="add">+ 新增</button>
<button id="delayadd">+ 延遲新增</button>
<div id="allBox">
<div class="todo">
<label for="1">
<input type="checkbox" id="1" onclick="checkItem(1)">
<span></span>
</label>
<span>吃飯</span>
<button class="btn" onclick="delItem(1)">✖</button>
</div>
</div>
</div>
<script src="demo.js"></script>
</body>
</html>
demo.js
var total = 1;//總條數
var text = [{text:"吃飯",id:1,del:false}];
var box = document.getElementById('allBox');
var todoItem = document.getElementsByClassName("todo");
var inputElt = document.getElementById("inputElt");
var addBtn = document.getElementById("add");
var delayBtn = document.getElementById("delayadd");
var i;
//新增
addBtn.addEventListener('click',()=>{
var text = inputElt.value;
console.log(text);
if(text != ""){
// if(text.replace(/^\s+|\s+$/g,"") != ""){
//匹配頭尾的任何空白字元,包括空格、製表符、換頁符等等
this.addContent(text);
inputElt.value = "";
}
})
//延遲新增
delayBtn.addEventListener('click',()=>{
var text = inputElt.value;
if(text.replace(/^\s+|\s+$/g,"") != ""){
setTimeout(()=>{
this.addContent(text);
},500);
inputElt.value = "";
}
})
function addContent(text){
this.total++;
console.log(this.total);
this.text.splice(0,0,{text:text,id:total,del:false});
//splice()方法用於新增或刪除陣列元素
this.add(text,total);
}
//新增待辦事項
function add(x,id){
var div = document.createElement('div');
var label = document.createElement('label');
var input = document.createElement('input');
var span = document.createElement('span');
var span1 = document.createElement('span');
var button = document.createElement('button');
input.type = "checkbox";
input.setAttribute("id",id);
input.addEventListener('click',()=>{
checkItem(id);
})
label.appendChild(input);
label.appendChild(span);
// span1.textContent = x;
span1.innerHTML = x;
button.className = "btn";
button.innerHTML = "✖";
//刪除
button.addEventListener('click',()=>{
delItem(id);
})
div.appendChild(label);
div.appendChild(span1);
div.appendChild(button);
div.className = "todo";
box.prepend(div);
}
//刪除
function delItem(id){
var length = this.text.length;
console.log(this.text);
for(i = length-1;i>=0;i--){
if(this.text[i].id == id)
this.text[i].del = true;
}
for(i = length-1;i>=0;i--){
if(this.text[i].del){
box.removeChild(todoItem[i]);
this.text.splice(i,1);
}
}
}
//勾選刪除項
function checkItem(id){
for(i = 0;i<this.text.length;i++){
if(this.text[i].id == id)
this.text[i].del = !this.text[i].del;
}
}