Web 開發的浩瀚海洋中,CSS 猶如點睛之筆,為網頁增光添彩。而引入 CSS 樣式的方式,也決定了網頁渲染的效率和代碼的可維護性。 link 和 @import 作為兩種常見的 CSS 引入方式,今天就來一場正面對決,看看誰才是你的最佳選擇!
<!DOCTYPE html>
<html>
<head>
<title>link vs @import</title>
<link rel="stylesheet" href="style.css">
</head>
<body>
<h1>Hello world</h1>
</body>
</html>
/* style.css */
@import url("other-style.css");
在瀏覽器解析 HTML 文件時,會依次解析 link 標簽和 style 標簽,并下載相應的 CSS 文件。@import 規則會在 CSS 文件解析時被執行,瀏覽器會再次發送請求下載 other-style.css 文件。
綜上所述,link 標簽憑借其加載速度快、兼容性好、可控性強等優勢,在 CSS 引入方式的較量中更勝一籌,是大多數場景下的最佳選擇。
當然,@import 也并非一無是處,在某些特殊情況下,它也能發揮作用。例如,當我們需要根據不同的條件加載不同的樣式表時,可以使用 @import 結合 JavaScript 實現動態加載。
#頭條創作挑戰賽#
在HTML中,通過 <input type="file> 標簽可以讓用戶從其設備中選擇一個或多個文件,并將文件提交到服務器或通過JS操作文件。在MDN文檔中了解更多。
<label for="avatar">Choose a profile picture:</label>
<input type="file"
id="avatar" name="avatar"
accept="image/png, image/jpeg">
使用accept屬性可以指定文件選擇的格式,例如只選擇word文件,則accept=".doc,.docx,application/msword"。
<input
type="file"
id="docpicker"
accept=".doc,.docx,application/msword" />
然而,這種指定并不是絕對的,用戶可以在系統文件選擇框中切換成"*",從而選擇其他文件格式。
默認情況下,文件選擇是單選的。通過multiple屬性可以指定多選。
<input
type="file"
id="docpicker"
multiple="true"
accept=".doc,.docx,application/msword" />
獲取 <input type="file> 的DOM實例,通過HTMLInputElement.files來獲取選擇的文件。
<div>
<label for="file">選擇要上傳的文件</label>
<input type="file" id="file" name="file" multiple />
</div>
<script>
var inputEl = document.getElementById('file');
inputEl.addEventListener('change', () => {
console.log(inputEl.files);
});
</script>
HTMLInputElement.files中的file元素包含:name、lastModified、size、type等信息。
通常情況下,為了美觀,我們不會僅使用原生的<input type="file>標簽來實現文件選擇功能。我們可以使用CSS對樣式進行修改,或者通過其他方式實現點擊其他元素來觸發隱藏的<input>來選擇文件。這種方式會比較繁瑣,而引入組件庫會增加復雜度。我們可以創建一個文件選擇函數,它可以直接完成文件選擇操作,而不必關心樣式。 通過JS創建HTMLInputElement,并將其type屬性設置為file,然后觸發點擊事件來選擇文件。在創建<input>實例后,不要將其掛載到DOM上,以避免出現在頁面中。最后,添加change監聽器到<input>實例中,在回調函數中獲取選中的文件。由于文件選擇是一個異步事件,因此使用Promise來處理選擇的文件。
export const selectFile = (accepts = ['*'], multiple = false) => {
// 創建<input>標簽
const inputElem = document.createElement('input');
// 設置屬性`type`為`file`
inputElem.setAttribute('type', 'file');
// 設置屬性`visibility`為`hidden`
inputElem.setAttribute('visibility', 'hidden');
if (Array.isArray(accepts) && accepts.length > 0) {
// 設置文件格式
inputElem.setAttribute('accept', accepts.join(','));
}
if (multiple) {
// 設置多選文件
inputElem.setAttribute('multiple', 'true');
}
// 主動觸發點擊事件
inputElem.click();
return new Promise((resolve, reject) => {
// 在實例上添加監聽
inputElem.addEventListener('change', () => {
if (!inputElem.files || inputElem.files?.length == 0) {
reject();
} else {
const files = Array.from(inputElem.files);
// 主要防止用戶主動選擇了非指定的文件格式
if (illegalFiles(files)) {
reject();
}
resolve(files);
}
});
});
function illegalFiles(files) {
return !accepts.includes('*') && files.some((file) => !accepts.includes(`.${getFileExtension(file)}`));
}
};
以下是selectFile函數的使用示例:
// 單選文件
selectFile(['.jpg', '.png'])
.then((files) => {
console.log(files);
// 處理文件
})
.catch(() => {
console.log('選擇文件出錯');
});
// 多選文件
selectFile(['.jpg', '.png'], true)
.then((files) => {
console.log(files);
// 處理文件
})
.catch(() => {
console.log('選擇文件出錯');
});
上述示例中,第一個selectFile函數調用將只允許選擇 .jpg和 .png格式的單個文件,而第二個調用將允許選擇 .jpg和 .png格式的多個文件。在選擇文件之后,可以使用then回調處理返回的文件數組。如果選擇文件時出現錯誤,則將會調用catch回調函數。
封裝的文件選擇函數在用戶沒有選擇文件時,點擊【確定】按鈕時調用者會決策失敗。但是如果用戶主動點擊系統的文件選擇框里的【取消選擇】按鈕,此時并不會觸發inputElement的change事件,導致調用方無法識別。 雖然DOM沒有提供監聽【取消選擇】的API,但是可以通過監聽window對象的focus事件,再加上inputElement.files來判斷用戶是否點擊了【取消選擇】按鈕。具體實現方式為,在調用selectFile函數前先監聽window對象的focus事件,當事件觸發時判斷inputElement.files是否為空,如果為空則表示用戶點擊了【取消選擇】按鈕。需要注意的是,這種方法只能監聽瀏覽器失焦事件,對于一些特殊情況可能無法生效。
export class BaseError extends Error {
cause?: Error;
constructor(message: string, options?: ErrorOptions) {
super(message, options);
this.name = this.constructor.name;
}
}
export class FileSelectCancelError extends BaseError {
constructor() {
super('Cancel select');
}
}
export class IllegalFileError extends BaseError {
accepts: string[];
constructor(accepts: string[]) {
super(`Please select files in ${accepts} format`);
this.accepts = accepts;
}
}
export const selectFile = (accepts = ['*'], multiple = false) => {
// 創建<input>標簽
const inputElem = document.createElement('input');
// 設置屬性`type`為`file`
inputElem.setAttribute('type', 'file');
// 設置屬性`visibility`為`hidden`
inputElem.setAttribute('visibility', 'hidden');
if (Array.isArray(accepts) && accepts.length > 0) {
// 設置文件格式
inputElem.setAttribute('accept', accepts.join(','));
}
if (multiple) {
// 設置多選文件
inputElem.setAttribute('multiple', 'true');
}
// 主動觸發點擊事件
inputElem.click();
return new Promise((resolve, reject) => {
window.addEventListener(
'focus',
() => {
// 這里必須異步處理`inputElement`
setTimeout(() => {
if (!inputElement.files || inputElement.files?.length === 0) {
reject(new FileSelectCancelError());
}
}, 1000);
},
{ once: true }
);
inputElement.addEventListener('change', () => {
if (!inputElement.files || inputElement.files?.length === 0) {
reject(new FileSelectCancelError());
} else {
const files = Array.from(inputElement.files);
if (illegalFiles(files)) {
reject(new IllegalFileError(accepts));
}
resolve(files);
}
});
});
function illegalFiles(files: File[]): boolean {
return !accepts.includes('*') && files.some((file) => !accepts.includes(`.${getFileExtension(file)}`));
}
};
以下是selectFile函數的使用示例:
const onFileSelect = async () => {
try {
const files = await selectFile(['jpg', 'png'], true);
// 處理選擇的文件
console.log(files);
} catch (error) {
if (error instanceof FileSelectCancelError) {
console.log('取消選擇文件');
} else if (error instanceof IllegalFileError) {
console.log(`只能選擇 ${error.accepts} 格式的文件`);
} else {
console.error(error);
}
}
};
// 觸發文件選擇
onFileSelect();
在上面的示例中,selectFile函數會返回一個 Promise 對象,用于異步獲取用戶選擇的文件。如果用戶選擇了文件,則 Promise 對象會被解析,返回選擇的文件數組;如果用戶取消選擇,則 Promise 對象會被拒絕,返回一個 FileSelectCancelError 對象;如果用戶選擇了不合法的文件格式,則 Promise 對象也會被拒絕,返回一個 IllegalFileError 對象。在使用 selectFile 函數時,可以使用 try-catch 語句來捕捉 Promise 對象的解析和拒絕結果,并進行相應的處理。
歡迎大家留言評論!
如果您看過《HTML是什么?——零基礎自學網頁制作》這篇教程,請按照其中說明創建一個txt文件。具體過程如下:
step1:在您方便的磁盤中建立一個文件夾,命名為"零基礎自學網頁制作"。例如我在D盤中建立了"零基礎自學網頁制作"文件夾。
step2:在文件夾中創建"HTML框架.txt"文件。鼠標移動到空白處點擊右鍵選擇"文本文檔"。
命名為"html框架",如下圖所示。
如果您的電腦沒有顯示".txt"后綴的話,請做如下操作:點擊"工具",找到"文件夾選項"
菜單如下:點擊"查看選項"。
下拉滑條,找到"隱藏已知文件類型的擴展名"選項,將前面的對勾去掉。
如果您使用的是win10的話請參考《邊學邊做網頁篇------初識HTML》,這也是我做的教程,不過以后都使用這個賬號來發了。
step3:把"HTML框架"復制粘貼到"html框架.txt"文件中。HTML框架代碼如下:
<!DOCTYPE HTML> <html> <head> </head><body> </body> </html>
代碼講解請參照《HTML是什么?——零基礎自學網頁制作》這篇教程中的講解。
粘貼后效果如下:使用CTRL+s組合鍵保存文件。
step4:復制"html框架.txt"文件,更名為"第一個網頁.txt"。原始的"html框架.txt"文件為以后備用。
如圖所示:
step5:把"第一個網頁.txt"的后綴名".txt"改為".html"。
首先將光標放在"第一個網頁.txt"文件上,點擊右鍵,選擇"重命名"。如圖:
選擇".txt"
更改為".html",敲擊回車鍵。這時會彈出一個對話框,如圖:
大膽的點擊"是"即可。
修改后文件是這樣的,如圖:因為我的默認瀏覽器是360,所以,".html"文件圖標顯示為360瀏覽器的圖標,顯示其他瀏覽器的圖標也沒有問題。
step6:將鼠標移動到"第一個網頁.html"文件上,單擊右鍵,選擇打開方式,如圖:
選擇任何一個瀏覽器打開即可,我使用的是火狐瀏覽器(Firefox),打開后如圖所示:空白一片。
點擊鍵盤F12鍵,看一下控制臺,如圖:查看器中已經顯示我們的代碼框架了。成功!
如果網頁是一道菜,那么,html框架我們可以理解為裝菜的白盤子,所以我們打開框架時,瀏覽器顯示一片白。下面我們為盤子中加些簡單的"菜"。
首先我們為頁面添加"標題"
在添加標題前,我們來看一下html框架代碼中的內容,在<html></html>標簽中有<head></head>和<body></body>兩個兄弟標簽。
我們在頁面中看到的所有的內容都是添加到<body></body>標簽中間!
<head></head>標簽中的內容并不會顯示在頁面中。
那么如何添加"標題"呢?
標題在HTML中用<h></h>標簽表示。在<h></h>中間加入文字內容即可。如下所示:
<h>第一個頁面</h>
右鍵,使用"記事本"打開"第一個網頁.html"文件。如圖所示:如果您的"打開方式"中沒有"記事本"請點擊"選擇默認程序"
在"其他程序"中找到"記事本"。點擊"確定"。從此,"記事本"就一直存在于"打開方式"中了。
我們把這句代碼粘貼到<body></body>之間。如下所示:保存后使用瀏覽器打開。
<!DOCTYPE HTML><html><head> </head> <body> <h>第一個頁面</h> </body> </html>
然后,使用瀏覽器打開,如圖所示:標題出現在頁面中了。
下面,我們來添加段落內容。
段落在HTML中使用<p></p>標簽添加。代碼如下
<p>千里之行始于足下</p>
請各位自行將代碼添加到"第一個網頁.html"文件中吧!示例代碼如下:
<!DOCTYPE HTML> <html> <head> </head> <body> <h>第一個網頁</h><p>千里之行始于足下</p> </body> </html>
結果如圖所示:
通過這個練習,我們可以發現一個規律,在<body></body>中,子元素代碼的上下順序代表了它在頁面中顯示的排版順序。
這也簡單回答了代碼結構與排版的關系,html的標簽語句只是標記了它所承載的信息的屬性和版面位置。
基于這個特性,html被稱為超文本標記語言。
下一期我們具體討論頁面中文字編輯的技巧。
喜歡的小伙伴請加關注,有任何問題請給我留言,歡迎大家給與指正!感激不盡!
HTML序章(學習目的、對象、基本概念)——零基礎自學網頁制作
HTML是什么?——零基礎自學網頁制作
HTML頁面中head標簽有啥用?——零基礎自學網頁制作
初識meta標簽與SEO——零基礎自學網頁制作
HTML中的元素使用方法1——零基礎自學網頁制作
HTML中的元素使用方法2——零基礎自學網頁制作
HTML元素中的屬性1——零基礎自學網頁制作
HTML元素中的屬性2(路徑詳解)——零基礎自學網頁制作
使用HTML添加表格1(基本元素)——零基礎自學網頁制作
使用HTML添加表格2(表格頭部與腳部)——零基礎自學網頁制作
使用HTML添加表格3(間距與顏色)——零基礎自學網頁制作
使用HTML添加表格4(行顏色與表格嵌套)——零基礎自學網頁制作
16進制顏色表示與RGB色彩模型——零基礎自學網頁制作
HTML中的塊級元素與內聯元素——零基礎自學網頁制作
初識HTML中的<div>塊元素——零基礎自學網頁制作
在HTML頁面中嵌入其他頁面的方法——零基礎自學網頁制作
封閉在家學網頁制作!為頁面嵌入PDF文件——零基礎自學網頁制作
HTML表單元素初識1——零基礎自學網頁制作
HTML表單元素初識2——零基礎自學網頁制作
HTML表單3(下拉列表、多行文字輸入)——零基礎自學網頁制作
HTML表單4(form的action、method屬性)——零基礎自學網頁制作
HTML列表制作講解——零基礎自學網頁制作
為HTML頁面添加視頻、音頻的方法——零基礎自學網頁制作
音視頻格式轉換神器與html視頻元素加字幕——零基礎自學網頁制作
HTML中使用<a>標簽實現文本內鏈接——零基礎自學網頁制作
*請認真填寫需求信息,我們會在24小時內與您取得聯系。