-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathwebp-support.js
More file actions
205 lines (172 loc) · 6.74 KB
/
Copy pathwebp-support.js
File metadata and controls
205 lines (172 loc) · 6.74 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
/**
* WebP 图片格式支持
* 自动检测浏览器支持并选择最佳图片格式
*/
(function () {
'use strict';
// 检测 WebP 支持
function checkWebPSupport() {
return new Promise((resolve) => {
const webP = new Image();
webP.onload = webP.onerror = function () {
resolve(webP.height === 2);
};
webP.src =
'data:image/webp;base64,UklGRjoAAABXRUJQVlA4IC4AAACyAgCdASoCAAIALmk0mk0iIiIiIgBoSygABc6WWgAA/veff/0PP8bA//LwYAAA';
});
}
// 优化图片标签
function optimizeImages() {
// 查找所有 img 标签
const images = document.querySelectorAll(
'img[src$=".jpg"], img[src$=".jpeg"], img[src$=".png"]'
);
images.forEach((img) => {
const src = img.src;
const ext = src.split('.').pop().toLowerCase();
// 创建 WebP 版本的 URL
const webpSrc = src.replace(`.${ext}`, '.webp');
// 创建 picture 元素
const picture = document.createElement('picture');
// 添加 WebP 源
const sourceWebP = document.createElement('source');
sourceWebP.type = 'image/webp';
sourceWebP.srcset = webpSrc;
// 添加原始格式源
const sourceOriginal = document.createElement('source');
sourceOriginal.type = ext === 'png' ? 'image/png' : 'image/jpeg';
sourceOriginal.srcset = src;
// 克隆原始 img 元素
const clonedImg = img.cloneNode(true);
// 组装 picture 元素
picture.appendChild(sourceWebP);
picture.appendChild(sourceOriginal);
picture.appendChild(clonedImg);
// 替换原始 img
img.parentNode.replaceChild(picture, img);
});
}
// 延迟加载优化
function optimizeLazyLoading() {
// 如果浏览器支持原生懒加载,确保正确配置
if ('loading' in HTMLImageElement.prototype) {
const lazyImages = document.querySelectorAll('img[data-src]');
lazyImages.forEach((img) => {
img.src = img.dataset.src;
img.removeAttribute('data-src');
});
}
}
// 图片尺寸优化
function optimizeImageSizes() {
const images = document.querySelectorAll('img[width][height]');
images.forEach((img) => {
// 添加 loading="lazy" 属性
if (!img.loading) {
img.loading = 'lazy';
}
// 确保 width 和 height 是响应式的
img.style.maxWidth = '100%';
img.style.height = 'auto';
});
}
// 为主页背景图片添加 WebP 支持
function optimizeHeroBackgrounds() {
// 这里可以为主页的英雄区域背景添加 WebP 支持
const heroSection = document.querySelector('.hero');
if (heroSection) {
const computedStyle = window.getComputedStyle(heroSection);
const bgImage = computedStyle.backgroundImage;
// 检查是否有背景图片
if (bgImage && bgImage !== 'none') {
// 这里可以根据需要实现背景图片的 WebP 替换
console.log('检测到背景图片,可以进一步优化');
}
}
}
// 添加响应式图片支持
function addResponsiveImages() {
const heroImg = document.querySelector('.hero img, .index-banner');
if (heroImg && heroImg.src) {
// 创建 srcset 属性
const src = heroImg.src;
const ext = src.split('.').pop().toLowerCase();
if (ext === 'jpg' || ext === 'jpeg' || ext === 'png') {
// 添加不同尺寸的图片
const sizes = '(max-width: 768px) 100vw, (max-width: 1200px) 50vw, 33vw';
const webpSrc = src.replace(`.${ext}`, '.webp');
// 创建 picture 元素
const picture = document.createElement('picture');
const sourceWebP = document.createElement('source');
sourceWebP.type = 'image/webp';
sourceWebP.srcset = `${webpSrc} 1x, ${webpSrc} 2x`;
const sourceOriginal = document.createElement('source');
sourceOriginal.type = ext === 'png' ? 'image/png' : 'image/jpeg';
sourceOriginal.srcset = `${src} 1x, ${src} 2x`;
const clonedImg = heroImg.cloneNode(true);
clonedImg.sizes = sizes;
picture.appendChild(sourceWebP);
picture.appendChild(sourceOriginal);
picture.appendChild(clonedImg);
heroImg.parentNode.replaceChild(picture, heroImg);
}
}
}
// 监听图片加载错误
function handleImageErrors() {
document.addEventListener(
'error',
function (e) {
if (e.target.tagName === 'IMG') {
const img = e.target;
const src = img.src;
// 如果 WebP 加载失败,回退到原始格式
if (src.includes('.webp')) {
const originalSrc = src.replace('.webp', '');
console.warn(`WebP 加载失败,回退到: ${originalSrc}`);
img.src = originalSrc;
}
}
},
true
);
}
// 主初始化函数
async function init() {
try {
// 检查 WebP 支持
const webpSupported = await checkWebPSupport();
if (webpSupported) {
console.log('✅ 浏览器支持 WebP 格式');
// 等待 DOM 加载完成后优化图片
if (document.readyState === 'loading') {
document.addEventListener('DOMContentLoaded', () => {
optimizeImages();
addResponsiveImages();
optimizeHeroBackgrounds();
});
} else {
optimizeImages();
addResponsiveImages();
optimizeHeroBackgrounds();
}
} else {
console.log('⚠️ 浏览器不支持 WebP 格式');
}
// 通用优化
optimizeLazyLoading();
optimizeImageSizes();
handleImageErrors();
} catch (error) {
console.error('图片优化初始化失败:', error);
}
}
// 暴露全局方法
window.WebPSupport = {
init: init,
check: checkWebPSupport,
optimize: optimizeImages,
};
// 自动初始化
init();
})();