JavaScript
DOMContentLoaded
document.addEventListener("DOMContentLoaded", function() {
. . .
});
這是一個事件監聽器,它監聽瀏覽器的 "DOMContentLoaded" 事件,即 HTML 檔案體加載、解釋完畢事件,事件觸發時將呼叫 " . . ." 處的代碼,從而避免了錯誤發生.
async和 defer
瀏覽器遇到 async 腳本時不會阻塞頁面渲染,而是直接下載然后運行,這樣腳本的運行次序就無法控制,只是腳本不會阻止剩余頁面的顯示,當頁面的腳本之間彼此獨立,且不依賴于本頁面的其它任何腳本時,async 是最理想的選擇,
添加 defer 屬性的腳本將按照在頁面中出現的順序加載,
- 如果腳本無需等待頁面決議,且無依賴獨立運行,那么應使用
async, - 如果腳本需要等待頁面決議,且依賴于其它腳本,呼叫這些腳本時應使用
defer,將關聯的腳本按所需順序置于 HTML 中,
常用彈出框
alert() 彈出個提示框 (確定)
confirm() 彈出個確認框 (確定,取消)
prompt() 彈出個輸入框 讓你輸入東西
js節點和事件
洗掉當前節點dom
panel 是訊息框,panel.parentNode 就是指 panel 的上一級,就是整個 DOM,然后再來用這個父親來干掉這個兒子,兒子不能自己干掉自己,所以要這么做,
closeBtn.onclick = function() {
panel.parentNode.removeChild(panel);
}
有時候在事件處理函式內部,您可能會看到一個固定指定名稱的引數,例如event,evt或簡單的e,這被稱為事件物件,它被自動傳遞給事件處理函式,以提供額外的功能和資訊,
function bgChange(e) {
const rndCol = 'rgb(' + random(255) + ',' + random(255) + ',' + random(255) + ')';
e.target.style.backgroundColor = rndCol;
console.log(e);
}
事件物件 e 的 target 屬性始終是事件剛剛發生的元素的參考,
可以使用任何您喜歡的名稱作為事件物件 - 您只需要選擇一個名稱,然后可以在事件處理函式中參考它,開發人員最常使用 e / evt / event,因為它們很簡單易記,堅持標準總是很好,
e.preventDefault()
如果事件是可取消的,則 preventDefault() 方法會取消該事件,這意味著屬于該事件的默認操作將不會發生,
form.onsubmit = function(e) {
if (fname.value =https://www.cnblogs.com/ggonekim/p/=='' || lname.value =https://www.cnblogs.com/ggonekim/p/=='') {
e.preventDefault();
para.textContent = 'You need to fill in both names!';
}
}
舉例,在以下情況下有用:
- 單擊“提交”按鈕,阻止其提交表單
- 單擊鏈接,防止鏈接跟隨 URL
事件冒泡和捕捉
- 瀏覽器檢查實際點擊的元素是否在冒泡階段中注冊了一個
onclick事件處理程式,如果是,則運行它 - 然后它移動到下一個直接的祖先元素,并做同樣的事情,然后是下一個,等等,直到它到達
<html>元素,
用 stopPropagation() 修復問題
當在事件物件上呼叫該函式時,它只會讓當前事件處理程式運行,但事件不會在冒泡鏈上進一步擴大,因此將不會有更多事件處理器被運行 (不會向上冒泡),
video.onclick = function(e) {
e.stopPropagation();
video.play();
};
"this"的含義
greeting: function() {
alert('Hi! I\'m ' + this.name.first + '.');
}
關鍵字"this"指向了當前代碼運行時的物件 ( 原文:the current object the code is being written inside )
可以用var that=this來拷貝當前物件指向,
物件原型
面向物件編程(Object Oriented Programming,縮寫為 OOP)
在傳統的 OOP 中,首先定義“類”,此后創建物件實體時,類中定義的所有屬性和方法都被復制到實體中,在 JavaScript 中并不如此復制——而是在物件實體和它的構造器之間建立一個鏈接(它是__proto__屬性,是從建構式的prototype屬性派生的),之后通過上溯原型鏈,在構造器中找到這些屬性和方法,
理解物件的原型(可以通過 Object.getPrototypeOf(obj)或者已被棄用的__proto__與建構式的 prototype 屬性之間的區別是很重要的,前者是每個實體上都有的屬性,后者是建構式的屬性,也就是說,Object.getPrototypeOf(new Foobar()) 和 Foobar.prototype 指向著同一個物件,
必須重申,原型鏈中的方法和屬性沒有被復制到其他物件——它們被訪問需要通過前面所說的“原型鏈”的方式,
盡管原型鏈看起來很像是繼承的層級結構,并且在某些方面,原型鏈的行為與繼承的行為也很類似,但是在其他方面,二者之間仍然存在區別,在繼承方式下,當一個子類完成繼承時,由該子類所創建的物件既具有其子類中單獨定義的屬性,又具有其父類中定義的屬性(以及父類的父類,依此類推),而在原型鏈中,每一個層級都代表了一個不同的物件,不同的物件之間通過 __proto__ 屬性鏈接起來,原型鏈的行為并不太像是繼承,而更像是委派(delegation),委派同樣是物件中的一種編程模式,當我們要求物件執行某項任務時,在委派模式下,物件可以自己執行該項任務,或者要求另一個物件(委派的物件)以其自己的方式執行這項任務,在許多方面,相對于繼承來說,委派可以更為靈活地在許多物件之間建立聯系(例如,委派模式可以在程式運行時改變、甚至完全替換委派物件),
new的程序:
? 創建一個空物件,將它的參考賦給 this,繼承函式的原型,
? 通過 this 將屬性和方法添加至這個物件
? 最后回傳 this 指向的新物件,也就是實體(如果沒有手動回傳其他的物件)
// ES5建構式
let Parent = function (name, age) {
//1.創建一個新物件,賦予this,這一步是隱性的,
// let this = {};
//2.給this指向的物件賦予構造屬性
this.name = name;
this.age = age;
//3.如果沒有手動回傳物件,則默認回傳this指向的這個物件,也是隱性的
// return this;
};
const child = new Parent();
繼承
當一個方法擁有相同的函式名,但是在不同的類中可以具有不同的實作時,我們稱這一特性為多型(polymorphism),當一個方法在子類中替換了父類中的實作時,我們稱之為子類重寫/多載(override)了父類中的實作,
class Professor extends Person {
// 只繼承父類屬性
teaches;
constructor(name, teaches) {
// 呼叫父類方法
super(name);
this.teaches = teaches;
}
introduceSelf() {
console.log(`My name is ${this.name}, and I will be your ${this.teaches} professor.`);
}
grade(paper) {
const grade = Math.floor(Math.random() * (5 - 1) + 1);
console.log(grade);
}
}
因為我們想在創建新的 Professor 時設定 teaches,我們需要宣告一個需要 name 和 teaches 引數的建構式,建構式中需要做的第一件事是使用 super() 呼叫父類的建構式,并傳遞 name 引數,父類的建構式會設定 name 屬性,然后 Professor 的建構式接著設定 teaches 屬性,
class關鍵字宣告類
class Person {
name;
constructor(name) {
this.name = name;
}
introduceSelf() {
console.log(`Hi! I'm ${this.name}`);
}
}
私有方法
與私有資料屬性一樣,你也可以宣告私有方法,而且名稱也是以 # 開頭,只能在類自己的方法中呼叫
class Example {
somePublicMethod() {
this.#somePrivateMethod();
}
#somePrivateMethod() {
console.log('You called me?');
}
}
const myExample = new Example();
myExample.somePublicMethod(); // 'You called me?'
myExample.#somePrivateMethod(); // SyntaxError
物件和文本之間的轉換
parse(): 以文本字串形式接受 JSON 物件作為引數,并回傳相應的物件,stringify(): 接收一個物件作為引數,回傳一個對應的 JSON 字串,
requestAnimationFrame
window.requestAnimationFrame() 告訴瀏覽器——你希望執行一個影片,并且要求瀏覽器在下次重繪之前呼叫指定的回呼函式更新影片,該方法需要傳入一個回呼函式作為引數,該回呼函式會在瀏覽器下一次重繪之前執行,
Promise()
fetch()API
fetch()API是一種現代的、基于 Promise 的、用于替代 XMLHttpRequest 的方法,
const fetchPromise = fetch('https://mdn.github.io/learning-area/javascript/apis/fetching-data/can-store/products.json');
console.log(fetchPromise);
fetchPromise.then( response => {
console.log(`已收到回應:${response.status}`);
});
console.log("已發送請求……");
-
呼叫
fetch()API,并將回傳值賦給fetchPromise變數, -
緊接著,輸出
fetchPromise變數,輸出結果應該像這樣:Promise { <state>: "pending" },這告訴我們有一個Promise物件,它有一個state屬性,值是"pending","pending"狀態意味著操作仍在進行中, -
將一個處理函式傳遞給 Promise 的 then() 方法,當(如果)獲取操作成功時,Promise 將呼叫我們的處理函式,傳入一個包含服務器的回應的
Response物件, -
輸出一條資訊,說明我們已經發送了這個請求,
?
Promise.all()
它接收一個 Promise 陣列,并回傳一個單一的 Promise,
- 當且僅當陣列中所有的 Promise 都被兌現時,才會通知
then()處理函式并提供一個包含所有回應的陣列,陣列中回應的順序與被傳入all()的 Promise 的順序相同, - 會被拒絕——如果陣列中有任何一個 Promise 被拒絕,此時,
catch()處理函式被呼叫,并提供被拒絕的 Promise 所拋出的錯誤,
const fetchPromise1 = fetch('https://mdn.github.io/learning-area/javascript/apis/fetching-data/can-store/products.json');
const fetchPromise2 = fetch('https://mdn.github.io/learning-area/javascript/apis/fetching-data/can-store/not-found');
const fetchPromise3 = fetch('https://mdn.github.io/learning-area/javascript/oojs/json/superheroes.json');
Promise.all([fetchPromise1, fetchPromise2, fetchPromise3])
.then( responses => {
for (const response of responses) {
console.log(`${response.url}:${response.status}`);
}
})
.catch( error => {
console.error(`獲取失敗:${error}`)
});
Promise.any()
在 Promise 陣列中的任何一個被兌現時它就會被兌現,如果所有的 Promise 都被拒絕,它也會被拒絕,
const fetchPromise1 = fetch('https://mdn.github.io/learning-area/javascript/apis/fetching-data/can-store/products.json');
const fetchPromise2 = fetch('https://mdn.github.io/learning-area/javascript/apis/fetching-data/can-store/not-found');
const fetchPromise3 = fetch('https://mdn.github.io/learning-area/javascript/oojs/json/superheroes.json');
Promise.any([fetchPromise1, fetchPromise2, fetchPromise3])
.then( response => {
console.log(`${response.url}:${response.status}`);
})
.catch( error => {
console.error(`獲取失敗:${error}`)
});
async 和 await
async關鍵字為你提供了一種更簡單的方法來處理基于異步 Promise 的代碼,在一個函式的開頭添加 async,就可以使其成為一個異步函式,
async function myFunction() {
// 這是一個異步函式
}
在異步函式中,你可以在呼叫一個回傳 Promise 的函式之前使用 await 關鍵字,這使得代碼在該點上等待,直到 Promise 被完成,這時 Promise 的回應被當作回傳值,或者被拒絕的回應被作為錯誤拋出,
Web Worker
Web Worker 的意義在于可以將一些耗時的資料處理操作從主執行緒中剝離,使主執行緒更加專注于頁面渲染和互動,
當在 HTML 頁面中執行腳本時,頁面的狀態是不可回應的,直到腳本已完成,
web worker 是運行在后臺的 JavaScript,獨立于其他腳本,不會影響頁面的性能,您可以繼續做任何愿意做的事情:點擊、選取內容等等,而此時 web worker 在后臺運行,
- 懶加載
- 文本分析
- 流媒體資料處理
- canvas 圖形繪制
- 影像處理
需要注意:
- 有同源限制
- 無法訪問 DOM 節點
- 運行在另一個背景關系中,無法使用Window物件
- Web Worker 的運行不會影響主執行緒,但與主執行緒互動時仍受到主執行緒單執行緒的瓶頸制約,換言之,如果 Worker 執行緒頻繁與主執行緒進行互動,主執行緒由于需要處理互動,仍有可能使頁面發生阻塞
- 共享執行緒可以被多個瀏覽背景關系(Browsing context)呼叫,但所有這些瀏覽背景關系必須同源(相同的協議,主機和埠號)
// 在 "generate.js" 中創建一個新的 worker
const worker = new Worker('./generate.js');
// 當用戶點擊 "Generate primes" 時,給 worker 發送一條訊息,
// 訊息中的 command 屬性是 "generate", 還包含另外一個屬性 "quota",即要生成的質數,
document.querySelector('#generate').addEventListener('click', () => {
const quota = document.querySelector('#quota').value;
worker.postMessage({
command: 'generate',
quota: quota
});
});
// 當 worker 給主執行緒回發一條訊息時,為用戶更新 output 框,包含生成的質數(從 message 中獲取),
worker.addEventListener('message', message => {
document.querySelector('#output').textContent = `Finished generating ${message.data} primes!`;
});
// 監聽主執行緒中的訊息,
// 如果訊息中的 command 是 "generate",則呼叫 `generatePrimse()`
addEventListener("message", message => {
if (message.data.command === 'generate') {
generatePrimes(message.data.quota);
}
});
// 生成質數 (非常低效)
function generatePrimes(quota) {
function isPrime(n) {
for (let c = 2; c <= Math.sqrt(n); ++c) {
if (n % c === 0) {
return false;
}
}
return true;
}
const primes = [];
const maximum = 1000000;
while (primes.length < quota) {
const candidate = Math.floor(Math.random() * (maximum + 1));
if (isPrime(candidate)) {
primes.push(candidate);
}
}
// 完成后給主執行緒發送一條包含我們生成的質數數量的訊息訊息,
postMessage(primes.length);
}
基本dom操作
document.querySelector
它允許你使用 CSS 選擇器選擇元素,呼叫會匹配它在檔案中遇到的第一個對應元素
document.querySelectorAll
匹配檔案中每個匹配選擇器的元素,并把它們的參考存盤在一個array中
document.getElementById
document.getElementsByTagName
創建和放置節點
document.createElement
document.appendChild
移動和洗掉元素
document.removeChild
洗掉自身節點:
document.parentNode.removeChild
轉載請註明出處,本文鏈接:https://www.uj5u.com/qiye/545670.html
標籤:JavaScript
上一篇:實作 Vue 折疊面板組件
下一篇:JS物件
