avaScript是構建在標準Web瀏覽器上工作的Web應用程序前端的唯一本地編程語言。每個流行的Web瀏覽器都遵循眾所周知的ECMAScript標準,并允許Web開發人員運行可移植、兼容的JavaScript代碼。作為另一種流行的編程語言,JavaScript生態系統提供了幾個獨特的編程概念,幫助開發人員編寫自解釋的、性能優先的源代碼。大多數現代Web開發項目在其代碼庫中使用這些JavaScript概念。在某些開發需求中,使用其中一些概念是不可避免的。
因此,有一些必須了解的JavaScript概念,每個Web開發人員在他們的職業生涯中都應該知道。開發人員不需要深入理解這些概念來編寫簡單的實驗性Web應用程序。但是,理解這些JavaScript概念可以讓您充分發揮JavaScript的潛力,通過理解JavaScript內部機制,以高效地編寫生產級Web代碼庫。理解JavaScript的核心概念有助于更快地發現錯誤,并支持您提升職業水平。
在本文中,我將解釋幾個作為經驗豐富的Web開發人員應該了解的核心JavaScript概念。
在JavaScript源代碼中,我們通常不使用全局變量和一個主要函數,而是通過作用域將代碼執行模型分解為多個堆疊段。例如,一個函數可以調用另一個函數,該函數使用私有變量來計算特定的值。閉包是一種位于另一個函數內部的函數,它允許程序員創建內部作用域。在函數調用后,內部函數(閉包)可以訪問主函數作用域。
讓我們通過一個簡單的例子來理解這個概念:
function createUnitAdder(unit) {
return (val)=> `${val} ${unit}`
}
const cm=createUnitAdder('cm');
const kg=createUnitAdder('m');
console.log(cm(120));
console.log(kg(7.5));
在這里,createUnitAdder函數返回一個內部函數,該內部函數使用主作用域中的unit變量。當我們調用內部函數時,它使用了在調用createUnitAdder函數時初始化的主作用域中的unit變量。即使cm和kg函數來自同一個主要函數,它們使用不同的詞法環境。
在C/C++語言中,我們無法在聲明之前調用函數,因此通常在頭文件中預定義它們。JavaScript允許您在聲明之前訪問函數和變量,因為JavaScript通過提升概念將聲明移到作用域的頂部:
sayHello();
function sayHello() {
console.log(`Hello JavaScript!`);
}
現代JavaScript使用Promise和async/await關鍵字支持異步編程。但是,過去的JavaScript實現只能通過回調函數進行異步編程。回調通常是您傳遞給另一個函數的函數,該函數根據特定事件稍后調用它。盡管回調概念不再推薦用于異步編程,但基于事件的瀏覽器API通常會使用它。例如,您應該將回調函數傳遞給計時器和DOM API。
看下面的例子:
function sayHello() {
console.log(`Hello JavaScript!`);
}
setInterval(sayHello, 1000);
在這里,我們使用sayHello函數作為回調函數。在這里,我們也可以使用匿名函數:
setInterval(()=> console.log(`Hello JavaScript!`), 1000);
如果您需要在創建匿名函數后立即運行它,那該怎么辦?立即調用函數表達式(IIFE,Immediately Invoked Function Expression)的概念允許您這樣做,如下面的示例所示:
((param)=> {
let name='JS';
console.log('IIFE', param, name);
})(2023);
如上所示,它通過不允許我們向全局命名空間添加新變量來隔離代碼段。
標準的瀏覽器API為各種目的提供了基于事件的API,用于創建用戶友好的現代Web應用程序前端。這些基于事件的API(特別是DOM API)在短時間內可能會生成大量事件。因此,如果您通過這么多傳入事件觸發了一個昂貴的操作(例如調用RESTful API、解析等),它可能會影響您的整個應用程序的性能。如何減少調用昂貴操作的事件數量?
JavaScript開發人員通常使用防抖動(debounce)和節流(throttling)的概念作為性能增強策略。防抖動會等待頻繁事件,并在超時后沒有新的頻繁事件發生時執行昂貴的操作。例如,以下代碼片段在用戶在半秒鐘內不再主動輸入文本時觸發模擬的RESTful API請求:
async function searchTags() {
return new Promise((resolve)=> setTimeout(()=> {
console.log('API called.');
resolve();
}, 500));
}
function debounce(cb, delay) {
let timer;
return (...args)=> {
clearInterval(timer);
timer=setTimeout(()=> {
cb(...args);
}, delay);
}
}
document
.getElementById('text')
.addEventListener('input', debounce(searchTags, 500));
另一方面,節流的概念根據預定義的時間間隔觸發一個昂貴的函數。換句話說,在特定的時間間隔內只調用一次昂貴的操作。
看下面的節流實現:
function throttle(cb, delay) {
let wait=false;
return (...args)=> {
if(wait)
return;
cb(...args);
wait=true;
setTimeout(()=> {
wait=false;
}, delay);
}
}
document
.getElementById('text')
.addEventListener('input', throttle(searchTags, 500));
上面的代碼片段在半秒的時間內只觸發了一次昂貴的函數調用,即使有很多傳入事件發生。
在過去,每個JavaScript開發人員都使用回調函數進行異步編程,并面臨著回調地獄的問題。ES6引入了Promise的概念,并提供了一種方便的方式來進行異步編程。盡管Promise通過Promise鏈式調用解決了回調地獄的問題,但在異步操作調用過程中仍使用了回調函數。后來,ES8引入了async/await關鍵字,以比Promise更好的異步編程技術,但它們在內部仍然使用了Promise(帶有async標記的函數只是返回一個Promise)。
在開發現代應用程序時使用async/await關鍵字是一個好主意,因為它們提高了代碼的可讀性,優于Promise和回調函數:
async function getTodos() {
let r=await fetch('https://jsonplaceholder.typicode.com/todos');
let todos=await r.json();
return todos;
}
(async function (){
let todos=await getTodos();
console.log(todos);
})();
在這里,我們使用了帶有await關鍵字的Fetch API。在JavaScript中,我們只能在異步函數內部使用await關鍵字,因此我們編寫了一個IIFE。或者,您可以使用Promises API調用RESTful API,因為異步函數通常返回一個Promise:
getTodos().then((todos)=> console.log(todos));
由于async/await關鍵字概念中的這種向后兼容特性,您甚至可以使用現代的await關鍵字調用舊的基于Promise的API:
function getItems() {
return Promise.resolve([1, 2, 4]);
}
(async function (){
let items=await getItems();
console.log(items);
})();
在JavaScript的事件系統中,使用回調是不可避免的,但有時我們可以使用async/await改進某些基于事件的API:
async function sleep(timeout) {
return new Promise((r)=> setTimeout(r, timeout));
}
(async function (){
console.log('Please wait...');
await sleep(1000);
console.log('Done.');
})();
在這里,我們部分地(沒有檢索返回值)將setTimeout函數轉換為Promise。您可以使用Node.js內置的util.promisify函數或es6-promisify包來將任何老式的基于回調的代碼轉換為Promise。
每個標準瀏覽器的JavaScript執行環境都是單線程的,但瀏覽器的功能通常是多線程的。例如,瀏覽器不會一次性排隊和發送所有網絡請求,而是可以并發發送網絡請求。但是,瀏覽器使用事件循環的概念將多線程事件轉換為單線程的JavaScript環境事件。從標準的Web API到高級庫,事件無處不在。因此,掌握事件系統對于所有Web開發人員來說是必不可少的。
研究所有標準瀏覽器提供的有用事件。然后,您可以使用它們來構建用戶友好且高效的Web應用程序。例如,您可以如下所示檢測鼠標滾輪事件:
document.addEventListener('wheel', (e)=> console.log(e.deltaY));
Web API標準積極實現新的瀏覽器事件,關注開發者的生產力和Web應用的可用性。瀏覽器甚至支持觸發自定義事件以進行基于事件的編程。
在Web應用程序中的常規數據處理過程中,數組操作是一種經常使用的技術。過去的JavaScript實現提供了幾種基本的數組方法,但由于缺乏便捷的數組處理方法,我們在許多場景中不得不使用循環結構。現代JavaScript現在提供了許多數組方法,以函數式的方式處理數據,避免了老式的循環結構。鏈式調用這些方法的可能性提高了開發者的生產力和源代碼的簡潔性。
看下面的例子,它顯示了一個未排序整數數組中的最大的三個數字:
let marks=[50, 75, 80, 22, 81, 92];
let topThree=marks
.sort((a, b)=> b - a)
.slice(0, 3);
console.log(topThree);
這是另一個例子,它獲取了兩個單獨數組中值的總和:
let costs1=[20, 15, 5];
let costs2=[10, 200];
let total=costs1.concat(costs2).reduce((acc, n)=> acc + n);
console.log(total);
現代JavaScript擁有許多內置函數,以函數式的方式處理數組,因此在使用循環編寫自己的算法之前,瀏覽MDN上現有的數組方法是一個明智的決策。
函數式的數據處理提高了代碼的可讀性,并激勵您編寫干凈的代碼。
Web開發領域每天都在不斷發展。許多協作者致力于與數百個W3C標準化草案合作,以改進基于JavaScript的Web API。與此同時,貢獻者們致力于ECMAScript標準化草案,以改進標準JavaScript語言。這些新功能可以在Web開發領域引發新的概念。例如,WebAssembly和Workers引發了使用客戶端計算能力來減少服務器工作負載的新概念,通過實現厚客戶端。
家好,在上一篇文章里 CSS小知識,分享14個你可能還未用上但又實用的CSS屬性(上)我們一起學習了上半部分,這篇文章我們我們繼續學習下半部分。
CSS Shake Effect 是一種使用 CSS 制作的晃動效果。這種效果通常用于錯誤提類似的場景。
如下段代碼所示,當用戶輸入無效輸入時,此“搖動”動畫效果會搖動輸入字段。它簡單而優雅。例如,如果用戶在文本字段中輸入數字而不是字母,輸入字段將會抖動。
HTML部分
<input id="name" type="text" placeholder="Enter your name" pattern="[A-Za-z]*"/>
CSS部分
input:invalid{
animation: shake 0.2s ease-in-out 0s 2;
box-shadow: 0 0 0.4em red;
}
@keyframes shake {
0% { margin-left: 0rem; }
25% { margin-left: 0.5rem; }
75% { margin-left: -0.5rem; }
100% { margin-left: 0rem; }
}
您可以使用此屬性截斷溢出的文本。指在文本超出元素寬度時,自動隱藏超出部分的文本。在 CSS 中,可以使用 text-overflow 屬性來實現這種效果。可以使用省略號 (...) 或自定義字符串對其進行截取縮略顯示。
下面是一個簡單的代碼示例:
.overflow-ellipsis {
width: 100px; /* 定義元素的寬度 */
white-space: nowrap; /* 防止文本換行 */
overflow: hidden; /* 隱藏超出部分 */
text-overflow: ellipsis; /* 添加省略號來指示隱藏的文本 */
}
HTML:
<div class="overflow-ellipsis">文本如果超出容器會被截斷并添加省略號</div>
上面的代碼定義了一個名為 "overflow-ellipsis" 的類,并將其應用于一個元素。這個類使用了 white-space: nowrap; 來防止文本換行,使用了 overflow: hidden; 來隱藏超出部分,并使用了 text-overflow: ellipsis; 來添加省略號(...)來指示隱藏的文本。
CSS 的 column-count 屬性可以用來將一個元素的內容分成多列,以實現報紙或雜志的頁面布局效果。
下面是一個簡單的代碼示例:
.multi-column {
column-count: 2; /* 將內容分成兩列 */
column-gap: 20px; /* 設置列之間的間隔 */
}
HTML:
<div class="multi-column">
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed auctor, augue non tincidunt eleifend, magna massa varius lorem, at luctus augue tellus in nibh.</p>
<p>Proin velit orci, pellentesque vel malesuada at, varius vel nibh. Nam eget mauris euismod, feugiat ipsum a, convallis enim. Aenean euismod malesuada orci eget euismod.</p>
<p>Nunc vitae augue eget nulla tempus aliquet. Integer euismod quam nunc, id rhoncus magna convallis at. Nullam euismod, sem a bibendum malesuada, erat ligula molestie magna.</p>
</div>
上面的代碼定義了一個名為 "multi-column" 的類,并將其應用于一個元素。這個類使用了 column-count: 2; 來將內容分成兩列,并使用了 column-gap: 20px; 來設置列之間的間隔。
還有 column-width 屬性可以用來設置每一列的寬度,若同時設置 column-width 和 column-count 屬性,則優先使用 column-width,column-count 會自動調整。
在實際使用中,需要結合其他屬性,如 column-gap, column-rule, column-rule-color, column-rule-style, column-rule-width等等來實現多列布局的效果。
動畫逐漸改變元素的樣式。只有先指定關鍵幀才能使用它。關鍵幀描述動畫元素如何出現在動畫序列中的等相關特性。
示例代碼:
div{
width: 200px;
height: 200px;
background-color: blue;
animation-name: square;
animation-duration: 8s;
}
@keyframes square{
from {background-color: blue;}
to {background-color: black;}
}
text-shadow 屬性可以在文本上添加陰影效果,可以使用它來增強文本的可讀性和吸引力。
box-shadow 屬性可以在元素上添加陰影效果,可以使用它來增強元素的立體感和吸引力。
下面是 text-shadow 和 box-shadow 的一個簡單的代碼示例:
.text-shadow {
text-shadow: 2px 2px 4px #000000; /* x-offset, y-offset, blur-radius, color */
}
.box-shadow {
box-shadow: 2px 2px 4px #000000; /* x-offset, y-offset, blur-radius, color */
}
<p class="text-shadow">This is text with shadow</p>
<div class="box-shadow">This is a box with shadow</div>
上面的代碼定義了一個名為 "text-shadow" 的類和一個名為 "box-shadow" 的類,分別將其應用于一個文本元素和一個盒子元素。這兩個類都使用了 x-offset: 2px; y-offset: 2px; blur-radius: 4px; color: #000000; 來定義陰影的樣式。
陰影的偏移值(x-offset y-offset)可以正值或負值,正值為陰影在元素的下方右方,負值為陰影在元素的上方左方。陰影的模糊半徑和陰影的顏色也可以根據需要調整。
在實際使用中,還可以使用 box-shadow: inset; 屬性來改變陰影為內陰影。
clip-path 屬性可以用來剪切元素的形狀。它可以使用一個圖形或路徑來定義剪切區域。
如下段代碼示例:
.bg{
height: 100%;
width: 100%;
background-color: rgba(199, 62, 133, 0.9);
clip-path: polygon(100% 0, 100% 0, 100% 51%, 0 100%, 0 90%, 0 52%, 0 51%);
position: absolute;
}
https://bennettfeely.com/clippy/ 這個工具網站,是一種通過將元素剪輯為基本形狀(圓形、橢圓形、多邊形或插圖)的可視化在線代碼生成工具,大大節省的你的時間。
background-blend-mode 屬性可以用來控制背景圖像與背景顏色的混合模式。它可以使用一系列的混合模式來定義背景的外觀,如添加顏色、陰影、高光等。
您可以使用 background-blend-mode 屬性制作令人驚嘆的背景。
如下段代碼所示:
div{
width: 600px;
height: 400px;
background-repeat: no-repeat, repeat;
background-position: center;
background-image: url("flower.png"), url("background-image.png");
background-blend-mode: color;
}
完成后的效果:
background-blend-mode 屬性有很多可用的值,如:normal, multiply, screen, overlay, darken, lighten, color-dodge, color-burn, hard-light, soft-light, difference, exclusion, hue, saturation, color, luminosity。
在實際使用中,需要注意瀏覽器的兼容性問題,需要使用前請查詢瀏覽器對 background-blend-mode 的支持情況。更多相關的用法建議查詢 https://www.w3schools.com/cssref/pr_background-blend-mode.php 這個網站。
今天的分享就到這里,14 個關于CSS的屬性就分享到這里,希望對你有所幫助,感謝你的關注。
參考文章:
https://ishratumar.medium.com/14-awesome-css-properties-you-need-to-know-9cee5b364990
作者:Ishrat Umar
注:非直譯,有整理部分
圖的時候遇到的這么一個問題,qq瀏覽器數字文本框 鼠標滾輪滑動,數字會自動加減,這個雖然也有一定的作用,但是并不是所有人都喜歡,所以必要的時候還是要禁用掉,目前在chrome,360為發現該問題,qq瀏覽器存在,禁用的方法也很簡單。
核心代碼就這一句話
<input type=”number” id=”inp1″ onmousewheel=”return false;”>
以下是擴展資料
<style type=”text/css”>
/*盒子大小從邊框開始計算*/
html * {
box-sizing: border-box;
}
/*解決模態框抖動*/
html {
overflow-y: scroll;
-ms-overflow-style: none;
}
/* 隱藏滾動條 */
html::-webkit-scrollbar {
display: none;
}
body {
font-family: “Helvetica Neue”, Helvetica, Arial, sans-serif;
font-size: 14px;
}
/* 去除webkit中input的type=”number”時出現的上下圖標 */
input::-webkit-outer-spin-button,
input::-webkit-inner-spin-button {
-webkit-appearance: none;
}
input[type=”number”] {
-moz-appearance: textfield;
}
</style>
<!DOCTYPE html>
<html lang=”en”>
<head>
<meta charset=”UTF-8″>
<title>禁止input輸入框的鼠標滾輪事件</title>
<script src=”jquery.js”></script>
</head>
<body>
<!– 禁止谷歌瀏覽器、Opera瀏覽器以及360瀏覽器等采用谷歌內核的瀏覽器 –>
<input type=”number” id=”inp1″ onmousewheel=”return false;”>
<!– 禁止Firefox瀏覽器 –>
<input type=”number” id=”inp2″>
<script>
$(“#inp2”)[0].addEventListener(‘DOMMouseScroll’, MouseWheel, false);
function MouseWheel(event) {
event=event || window.event;
event.preventDefault();
}
</script>
</body>
</html>
*請認真填寫需求信息,我們會在24小時內與您取得聯系。