者有話要說:此文適合前端初學者哦~如有大神路過,請多多指教。
最近在看《JavaScript DOM編程藝術》這本書,順手給大家安利下。不得不說作者真真是極其細致的一個人,寫得不僅通俗易懂,而且妙趣橫生,非常適合初學者。本文也是來自書中第四-六章的案例。好啦,廢話不多說,直接先上成果。
<script src="https://lf3-cdn-tos.bytescm.com/obj/cdn-static-resource/tt_player/tt.player.js?v=20160723"></script>
我這里寫了一個二十四節氣,圖片均源自網絡,僅用于分享教學,如涉及侵權,請聯系我刪除。大家可自行發揮創意,比如寫一個情侶照片庫啦,旅游照片合輯啦等等都是非常不錯的idea呢。
1.整體結構和框架
從視頻中可以看到我們的需求是點擊相應的文本,在當前窗口內切換圖片和相應的說明文字。那么需要在網頁內設置一個圖片占位符,并阻止超鏈接的默認彈窗行為。將整個文檔分為兩部分,列表部分和展示部分。
分別設置list和show的CSS屬性。
2.列表部分
接下來優化list,這部分的思路就是一個4x6的彈性盒。首先補充list中的a標簽,添加圖片路徑和title屬性。二十四個節氣就有24個a標簽,此處有省略。
我這里將每個小格子命名為block,同樣設置為彈性盒,這樣可以方便地把文本鏈接用margin:auto實現上下左右居中。最后可根據自己的喜好更改鏈接被鼠標懸停、被訪問后的狀態。
至此list部分就寫好啦。
列表部分整體的完成效果
3.占位符初始狀態
占位符初始狀態指的是鏈接未被點擊之前顯示的一張默認圖片,我這里就用第一張圖片(第一個節氣)來顯示。最最關鍵的部分要來了,如何使圖片在當前占位符位置切換呢?這里肯定是要編寫一個JS函數的,把它命名為replace.js。
占位符初始狀態
4.編寫一個簡單的showPic()
為圖片占位符命名為placeholder,替換文本命名為description,分別設置CSS屬性。
占位符整體的效果
當鏈接被點擊時進行替換行為。我們可以在每個a鏈接中綁上onclick屬性,將行為函數命名showPic(),參數即為當前a標簽(this)。
在showPic()里需要完成的事件是:獲取a標簽中的href屬性,用它來替換placeholder中的src屬性;獲取a標簽中的title屬性,用它來替換description中的文本(nodeValue值)。注意此處文本是p標簽的第一個子節點,所以要加上.firstChild。
showPic()函數寫完了,接下來就是要阻止a鏈接被點擊時的默認彈出新窗口行為(因為我們想要圖片切換就發生在占位符位置)。有以下兩種實現方式:
一是在onclick中直接添加return false;
二是讓showPic()函數的返回值直接為false,然后在onclick中返回showPic()函數的返回值。
至此這個圖片庫就全部寫好啦,快去試試吧~
之前的文章中,我們討論了圖片的尺寸自適應、裁切與縮放、壓縮、動態webp等技術。這些技術都是對單張圖片的處理,而在實際項目中,我們往往需要處理大量的圖片。本文將討論如何高效批量優化圖片,并介紹一些圖片加載技巧。
圖片預加載(Preloading Images)是一種提前加載即將使用的圖片資源的技術。通過在頁面加載時就將未來可能用到的圖片資源進行預加載,可以在用戶真正需要這些圖片時,減少等待時間,提升用戶體驗。
HTML中的預加載
在HTML中,可以通過<link>標簽的rel屬性來實現圖片預加載。例如,我們可以在頁面的`<head>`標簽中添加如下代碼:
<link rel="preload" href="image.jpg" as="image" fetchpriority="high">
該 <link> 標簽用于預加載一個圖片資源。讓我們逐個解釋其中的屬性及其作用:
當前<link>標簽的用途是預加載資源。preload告訴瀏覽器提前加載指定的資源(在這里是圖片),以便在后續使用時能夠更快地提供資源。這有助于提高頁面的加載性能,尤其是在資源密集型的網站上。
指定要預加載的資源的URL。href屬性是一個URL,指向需要預加載的資源。在這個例子中,image.jpg是要預加載的圖片的路徑。
指定預加載資源的類型。as屬性告訴瀏覽器預加載資源的類型,以便正確地處理和優化加載過程。在這個例子中,as="image"明確了資源是一個圖片。這對于瀏覽器優化資源加載順序和優先級非常重要。
指定預加載資源的獲取優先級。fetchpriority屬性是一個新的屬性,用于指示瀏覽器在預加載資源時的優先級。在這個例子中,fetchpriority="high"告訴瀏覽器這是一個高優先級的資源,應該盡快加載。這在需要確保關鍵資源(如首屏圖片)快速加載時非常有用。
CSS中的預加載
在CSS中,可以通過background-image屬性來實現圖片預加載。例如,我們可以在CSS文件中添加如下代碼:
.preload {
background-image: url('image.jpg');
}
這段CSS代碼定義了一個`.preload`類,其中包含了一個 background-image 屬性,指定了要預加載的圖片資源的URL。在頁面加載時,瀏覽器會提前加載這個圖片資源,以便在后續使用時能夠更快地提供資源。
JavaScript中的預加載
在JavaScript中,可以通過Image對象來實現圖片預加載。例如,我們可以在JavaScript代碼中添加如下代碼:
var img=new Image();
img.src='image.jpg';
這段JavaScript代碼創建了一個新的Image對象,并設置了src屬性為要預加載的圖片資源的URL。當這段代碼執行時,瀏覽器會開始加載這個圖片資源,以便在后續使用時能夠更快地提供資源。
二、圖片懶加載
圖片懶加載(Lazy Loading Images)是一種延遲加載圖片資源的技術。通過在頁面加載時只加載可見區域內的圖片資源,可以減少頁面的加載時間,提升用戶體驗。
img loading屬性
在HTML中,可以通過loading屬性來實現圖片懶加載。例如,我們可以在<img>標簽中添加如下代碼:
<img src="image.jpg" loading="lazy" alt="Image">
loading屬性是一個新的屬性,用于指定圖片的加載方式。它有三個可能的值:
Intersection Observer API
在JavaScript中,可以通過Intersection Observer API來實現圖片懶加載。Intersection Observer API是一種用于監視元素與視口交叉狀態的API,可以用于實現懶加載、無限滾動等功能。
例如,我們可以在JavaScript代碼中添加如下代碼:
// 創建一個IntersectionObserver實例
const intersectionObserver=new IntersectionObserver((entries)=> {
entries.forEach(entry=> {
if (entry.isIntersecting) {
// 當元素與視窗交叉時執行的操作
const img=entry.target; // entry.target是交叉的元素
// 假設data-src屬性包含了圖片的路徑
img.src=img.dataset.src;
intersectionObserver.unobserve(img); // 停止觀察該元素
}
});
});
// 為所有需要滾動加載的元素(例如圖片)設置觀察
document.querySelectorAll('img[data-src]').forEach((img)=> {
intersectionObserver.observe(img);
});
這段JavaScript代碼創建了一個IntersectionObserver實例,并為所有帶有data-src屬性的圖片元素設置了觀察。當圖片元素與視口交叉時,會加載圖片資源,并停止觀察該元素。
Scroll事件
在JavaScript中,也可以通過監聽scroll事件來實現圖片懶加載。例如,我們可以在JavaScript代碼中添加如下代碼:
// 獲取所有帶有data-src屬性的圖片元素
const lazyImages=document.querySelectorAll('img[data-src]');
// 懶加載函數
function lazyLoad() {
lazyImages.forEach((img)=> {
if (img.offsetTop < window.innerHeight + window.pageYOffset + 200) {
img.src=img.dataset.src;
img.removeAttribute('data-src');
}
});
// 更新 lazyImages,排除已加載的圖片
lazyImages=document.querySelectorAll('img[data-src]');
// 如果所有的圖片都已經加載,則移除事件監聽器
if (lazyImages.length===0) {
document.removeEventListener('scroll', lazyLoad);
}
}
// 監聽scroll事件
document.addEventListener('scroll', lazyLoad);
// 初始檢查一次,以便在頁面加載時懶加載位于視窗中的圖片
lazyLoad();
這段JavaScript代碼監聽了scroll事件,并在圖片元素進入視口時加載圖片資源。當圖片進入視口時,會加載圖片資源,并移除data-src屬性。
結合多種方法來實現圖片懶加載
在實際項目中,我們可以結合多種方法來實現圖片懶加載,以便在不同瀏覽器和環境下提供最佳的用戶體驗。例如,我們可以先檢查瀏覽器是否支持loading屬性,如果支持,則使用`loading`屬性實現圖片懶加載;如果不支持,則檢查瀏覽器是否支持Intersection Observer API,如果支持,則使用Intersection Observer API實現圖片懶加載;如果不支持,則使用scroll事件實現圖片懶加載。
下面是一個示例代碼,演示了如何結合多種方法來實現圖片懶加載:
html
<body>
<img src="placeholder.jpg" data-src="image1.jpg" alt="Description 1">
<img src="placeholder.jpg" data-src="image2.jpg" alt="Description 2">
<img src="placeholder.jpg" data-src="image3.jpg" alt="Description 3">
<!-- 更多 img -->
<script src="lazyload.js"></script>
</body>
javascript
const lazyImages=document.querySelectorAll('img[data-src]');
// 判斷瀏覽器是否支持 loading 屬性
if('loading' in HTMLImageElement.prototype) {
lazyImages.forEach(img=> {
img.src=img.dataset.src;
});
} else if('IntersectionObserver' in window) {
// 使用Intersection Observer API實現懶加載
const intersectionObserver=new IntersectionObserver((entries)=> {
entries.forEach(entry=> {
if (entry.isIntersecting) {
const img=entry.target;
img.src=img.dataset.src;
intersectionObserver.unobserve(img);
}
});
});
lazyImages.forEach((img)=> {
intersectionObserver.observe(img);
});
} else {
// 使用scroll事件實現懶加載
let lazyImages=document.querySelectorAll('img[data-src]');
function lazyLoad() {
lazyImages.forEach((img)=> {
if (img.offsetTop < window.innerHeight + window.pageYOffset + 200) {
img.src=img.dataset.src;
img.removeAttribute('data-src');
}
});
lazyImages=document.querySelectorAll('img[data-src]');
if (lazyImages.length===0) {
document.removeEventListener('scroll', lazyLoad);
}
}
document.addEventListener('scroll', lazyLoad);
lazyLoad();
}
三、漸進式圖片加載
圖片漸進式加載(Progressive Image Loading)是一種逐步加載圖片資源的技術。通過在圖片加載過程中逐步顯示模糊的低分辨率圖片,可以提升用戶體驗,減少等待時間。這種技術不僅適用于優化頁面性能,還可以為用戶提供視覺上的反饋,使頁面顯得更加流暢。
漸進式 JPEG
漸進式 JPEG (Progressive JPEG) 是一種通過逐步顯示圖片的技術,漸進式 JPEG 與標準的 JPEG 圖片區別在于,漸進式 JPEG 圖片在加載時會逐步顯示圖片的分辨率,而不是一次性顯示完整的圖片。這種逐步加載的方式可以提升用戶體驗,減少等待時間。漸進式 JPEG 圖片最初會顯示的是一張模糊的低分辨率圖片,隨著數據的不斷加載,圖片的分辨率會逐步提高,直至達到全分辨率。這種方法特別適合需要加載大圖的場景。
許多圖像編輯工具和壓縮工具都支持將圖片保存為漸進式 JPEG。在實際項目中,例如,在 Photoshop 中保存圖片時,可以勾選“漸進式”選項。也可以使用命令行工具如ImageMagick(https://imagemagick.org/index.php)來生成漸進式 JPEG:
1convert input.jpg -interlace Plane output.jpg
需要注意的是漸進式 JPEG 圖片的文件大小通常會比標準的 JPEG 圖片稍大,因為漸進式 JPEG 圖片包含了更多的數據,用于逐步顯示圖片的分辨率,但是這種額外的數據可以提升用戶體驗。因此,在選擇使用漸進式 JPEG 圖片時,需要權衡圖片質量和文件大小之間的關系。
占位圖技術
占位圖技術(Placeholder Image)通常使用一個非常小的、模糊的低分辨率圖像作為占位符,在高分辨率圖像加載完成之前先顯示出來。這種方法通過減少初始加載時間和網絡請求,可以顯著提升頁面的首屏加載速度。
占位圖實現原理很簡單,只需要在頁面中插入一個占位圖像,然后在高分辨率圖像加載完成后替換為真實圖像即可。
代碼示例:
html:
<img src="https://fs.autohome.com.cn/energyspace_views/image_demo/compress_before.png?format=webp&dis_rule=20x0_q50_" data-src="https://fs.autohome.com.cn/energyspace_views/image_demo/compress_before.png?format=webp&dis_rule=400x0_q90_" alt="Description">
javascript:
document.addEventListener('DOMContentLoaded', function() {
const lazyImages=document.querySelectorAll('img[data-src]');
lazyImages.forEach(img=> {
const placeholder=new Image();
placeholder.src=img.src;
placeholder.onload=()=> {
img.src=img.dataset.src;
};
});
});
img src 屬性中的圖片是一個模糊的小圖,data-src 屬性中的圖片是高分辨率圖像。在頁面加載時,先顯示模糊的小圖,待高分辨率圖像加載完成后再替換。
使用占位圖技術可以有效減少頁面的加載時間,提升用戶體驗。同時,占位圖技術也可以結合圖片懶加載技術一起使用,進一步提升頁面性能。
四、Base64 編碼
在 Web 開發中,將圖片轉換為 Base64 編碼是一種優化頁面加載速度的方法,但需要權衡其優缺點。一般來說,適用于 Base64 編碼的圖片大小取決于幾個因素,包括頁面的總體加載時間、HTTP 請求的數量以及文件大小。
Base64 編碼的優點
Base64 編碼的缺點
適合轉為 Base64 的圖片大小一般為 1KB 到 10KB 的圖片:通常,文件大小在 1KB 到 10KB 之間的圖片是轉為 Base64 編碼的最佳選擇。這樣的圖片往往是小圖標、按鈕、背景圖案等。對于這些小圖片,Base64 編碼可以顯著減少 HTTP 請求的數量,從而提升頁面加載速度。
在實際Web項目開發中,使用 Webpack或 Vite 將小圖片自動轉換為 Base64 編碼是一個常見的優化方法。這種自動化的處理可以簡化開發流程,并確保在構建過程中優化資源。
webpack 配置示例:
module.exports={
module: {
rules: [
{
test: /\.(png|jpe?g|gif)$/i,
use: [
{
loader: 'url-loader',
options: {
limit: 10240, // 10KB
},
},
],
},
],
},
};
Vite 配置示例:
import { defineConfig } from 'vite';
export default defineConfig({
build: {
assetsInlineLimit: 10240, // 10KB
},
});
在以上配置中,limit 或 assetsInlineLimit 選項指定了圖片轉為 Base64 編碼的閾值,超過這個閾值的圖片將被單獨打包為文件,而小于這個閾值的圖片將被轉為 Base64 編碼。
五、結語
通過結合多種圖片加載與優化技術,可以提升頁面性能,提供更好的用戶體驗。預加載、懶加載、漸進式加載等技術在不同場景下有著不同的優勢,通過合理地選擇和組合這些技術,可以有效地優化圖片加載過程。
在實際項目中,建議根據項目的具體需求,選擇合適的技術和工具進行圖片優化和加載。希望本文所介紹的技術和示例代碼能夠幫助您更好地實現圖片批量處理與加載優化,提升網頁的加載速度和用戶體驗。
WEB 圖片優化的相關文章到此結束,希望對你有所幫助。如果有任何問題或建議,歡迎在評論區留言,謝謝!
作者:之家-梁家瑋
來源-微信公眾號:之家前端共享流
出處:https://mp.weixin.qq.com/s/bhxtIED32lJP7PY9g28GNA
般我們常見placeholder偽類選擇器用來修改默認樣式及文案,忽然發現placeholder-shown偽類選擇器,比較官方的解釋是
CSS偽類表示任何顯示占位符文本的form元素。
簡單來說就是當輸入框的placeholder內容顯示的時候,輸入框干嘛干嘛。
兼容性如下,在移動端沒什么問題
:placeholder-shown CSS 偽類 在 <input> 或 <textarea> 元素顯示 placeholder text 時生效,簡單的說就是 placeholder 有值才生效,如下所示:
// html
<input placeholder="placeholder text" />
<textarea placeholder="placeholder text"></textarea>
// css
input:placeholder-shown, textarea:placeholder-shown{
border:1px solid pink;
}
如果 placeholder 為空 placeholder-show 就沒效果了:
// html
<input placeholder="" />
<textarea placeholder=" text"></textarea>
我們可以使用:placeholder-shown設置input元素的樣式。
input:placeholder-shown {
border: 1px solid pink;
background: yellow;
color: green;
}
注意一些奇怪的問題-我們設置 color: green,但沒有作用用。這是因為:placeholder-shown僅會針對input本身。對于實際的占位符文本,必須使用偽元素::placeholder。
input::placeholder {
color: green;
}
?? 我注意到有一些其他的屬性,如果應用::placeholder-shown,也會影響placeholder的樣式。
input:placeholder-shown, textarea:placeholder-shown{
font-style: italic;
text-transform: uppercase;
letter-spacing: 5px;
}
我也不知道這是啥情況,也許是因為這些屬性被placeholder繼承了,如果你知道原因,歡迎留言告訴我一下,謝謝。
:placeholder-shown是專門用于確定元素是否顯示占位符的對象,我們主要使用它來檢查input 內容是否為空(假設所有的input都有一個占位符)。這里你可能會想,使用 empty 也是可以的吧?我們來看看。
// html
<input value="not empty">
<input><!-- empty -->
// css
input:empty {
border: 1px solid pink;
}
input {
border: 1px solid black;
}
這里看似empty起作用了,因為我們看到的是粉紅色邊框,但這實際上不起作用
之所以顯示粉紅色,是因為偽類增加了 css 的權重。類似于類選擇器(即.form-input)比類型選擇器(即input)具有更高的權重。高權限選擇器將始終覆蓋低權重設置的樣式。
所以我們可以這樣說:不要使用:empty檢查輸入元素是否為空。
我們檢查輸入是否為空的唯一方法是使用:placeholder-shown。但是如果我們的輸入元素沒有占位符會發生什么呢? 這里有個取巧的方法:傳入一個空字符串" "。
// html
<input placeholder=" "><!-- pass empty string -->
//css
input:placeholder-shown {
border-color: pink;
}
我們可以使用:not偽類對某些事物進行逆運算。在這里,我們可以在輸入不是空的情況下進行定位。
//html
<input placeholder="placeholder" value="not empty" />
// css
input:not(:placeholder-shown) {
border: 1px solid green;
}
用placeholder-shown我們可以實現下面動效
具體代碼如下:
Html
<div class="input">
<input class="input-fill" placeholder="郵箱">
<label class="input-label">郵箱</label>
</div>
Css
.input{
position: relative;
}
.input-fill{
border: 1px solid #ececec;
outline: none;
padding: 13px 16px 13px;
font-size: 16px;
line-height: 1.5;
width: fit-content;
border-radius: 5px;
}
.input-fill:placeholder-shown::placeholder {
color: transparent;
}
.input-label {
position: absolute;
font-size: 16px;
line-height: 1.5;
left: 16px; top: 14px;
color: #a2a9b6;
padding: 0 2px;
transform-origin: 0 0;
pointer-events: none;
transition: all .25s;
}
.input-fill:focus{
border: 1px solid #2486ff;
}
.input-fill:not(:placeholder-shown) ~ .input-label,
.input-fill:focus ~ .input-label {
transform: scale(0.75) translate(0, -32px);
background-color: #fff;
color: #2486ff;
}
作者:Samantha Ming 譯者:前端小智 來源:medium 原文:https://www.samanthaming.com/tidbits/88-css-placeholder-shown/
*請認真填寫需求信息,我們會在24小時內與您取得聯系。