一. 为什么要使用sprite (雪碧图) 二. CSS雪碧图原理及应用 三. 生成雪碧图的三种实现方式
一.为什么要使用雪碧图
在开发过程中,我们需要用到很多图标,这些图标的大小不是很大,但是每次需要向服务器发送请求,从而加重服务器的负担,尤其是当网站处于高访问量的情况下或网络不稳定的时候,服务器性能会明显下降。这种情况不符合被广泛遵循的雅虎军规“尽量减少HTTP请求数”的要求
例如 当我们引入如图的4个各不到1k的小图片还占用了4个请求,这显然非常浪费服务器资源
二.CSS雪碧图原理及应用
1.css方法是将小图标和背景图像合并到一张图片上,这样每个元素都会以该合成图为背景,而且页面也只加载一张合成图
然后利用CSS的背景定位(background-position)来显示需要显示的图片部分。
其中要用到 background-image,background-position
其中如下图 背景图 左上角默认和容器框重合的,现在也就是默认会显示 第一个图片 ,现在想要显示第二个图片 就需要把background-image 左移动一个(也即是X轴负方向) 所以显示的{x:-60px;y:0px}
合并图片 方法有很多,图片合并软件 ,在线合并 以及 glup webpack工具
方法一
这里提供一个很好用的在线的图片合并网站
可以根据自己的需要添加边距等等,还会生成对应的参考css 如图
使用时候直接引入css 文件 ,定义好对应类名 即可
方法二 目前大多数前端项目都采用 webpack打包 同时可以使用webpack-spritesmith 插件
主要用到:
webpack配置如下
const path = require('path');
const SpritesmithPlugin = require('webpack-spritesmith');
module.export = {
// ...
module: {
rules: [
{
test: /png$/
loader:[
'file-loader?name=i/[hash].[ext]'
]
},
{
test: /\.(css|scss)$/,
use: ExtractTextPlugin.extract({
fallback: 'style-loader',
use: ['css-loader', 'postcss-loader', 'sass-loader']
})
}
]
},
resolve: {
modules: [
'node_modules',
'assets' //css在哪里能找到sprite图 文件夹的名字
]
},
plugins: [
new SpritesmithPlugin({
src: {
cwd: path.resolve(__dirname, 'src/ico'), //准备合并成sprit的图片存放文件夹
glob: '*.png' //哪类图片
},
target: {
image: path.resolve(__dirname, 'src/assets/sprites.png'), // sprite图片保存路径
css: path.resolve(__dirname, 'src/assets/_sprites.scss') // 生成的sass保存在哪里(也可以后缀改成.css 直接生成css文件,在文件中直接使用对应的类名即可)
},
apiOptions: {
cssImageRef: "sprite.png" //css根据该指引找到sprite图
}
})
]
}
注:这是纯webpack的配置的情况 , 现在很多项目才用create-reactp-app 方式创建的 ,上面配置的中rules 部分已经嵌入,可以省略。
下面执行npm start 命令 会在sprite文件夹生成sprite.png sprite.scss
除了 对应的数据外,sass文件中自动生成mixin 如下
//webpack 自动生成的scss文件
$icon1-name: 'icon1';
$icon1-x: 0px;
$icon1-y: 0px;
$icon1-offset-x: 0px;
$icon1-offset-y: 0px;
$icon1-width: 32px;
$icon1-height: 32px;
$icon1-total-width: 158px;
$icon1-total-height: 32px;
$icon1-image: '../sprite/sprite.png';
$icon1: (0px, 0px, 0px, 0px, 32px, 32px, 158px, 32px, '../sprite/sprite.png', 'icon1', );
//数据略...
@mixin sprite($sprite) {
@include sprite-image($sprite);
@include sprite-position($sprite);
@include sprite-width($sprite);
@include sprite-height($sprite);
}
在 自己的sass文件中 如下引用 就可以快乐的使用了 ,
//直接在页面中引入的scss文件
@import '../sprite/sprite.scss';
//生成的尺寸默认是原图大小 如何动态的缩放图片 如下
@mixin spriteScale($sprite,$scale) {
$spriteScaled: ();
$scaleItems: (3, 4, 5, 6, 7, 8);
@for $i from 1 through length($sprite) {
$item: nth($sprite, $i);
@if (null != index($scaleItems, $i)) {
$spriteScaled: append($spriteScaled, $item * $scale);
} @else {
$spriteScaled: append($spriteScaled, $item);
}
}
@include sprite($spriteScaled);
background-size: nth($spriteScaled, 7) nth($spriteScaled, 8);
}
//注释: spriteScale 把雪碧图位置以及size涉及的尺寸 scale同样的倍数
@mixin sprite_dynamic ($arg1,$arg2,$scale){
@include spriteScale($arg1 ,$scale)
@media (-webkit-min-device-pixel-ratio:3),(min-device-pixel-ratio: 3){
@include spriteScale($arg2 ,$scale)
}
}
注释:sprite_dynamic 通过@media查询 ,加载2X图或者3X ,$arg1 $arg2,$scale 分别是 2X 3X图变量名 缩放倍率,具体用法如下
.icon1{
@include sprite_dynamic($wifi_2X,$wifi_3X ,1);
}
注释 :最后在需要的类里面引用 $wifi_2x $window_3X
保存刷新页面 ,图片有显示了,但是此时network一个图片请求都没有了,在看element dom节点,webpack 把背景图片转码为base64
这样以后添加 或者去掉一个图标,只更改少量代码,运行npm runbuild 或者npm start 就ok 的
动态加载 2X &3X图 原理如下动态加载2X&3X
Sortable.js:让拖拽排序变得超简单!
大家好呀!我是你们的前端老师小诺。今天要给大家介绍一个特别好用的JavaScript库——Sortable.js!还在为实现拖拽排序功能发愁吗?有了它,列表排序就像玩积木一样简单!不管是待办清单、图片排序,还是商城后台的商品管理,都能轻松搞定!
Sortable.js是什么?
Sortable.js是一个功能强大的JavaScript库,专门用于实现拖拽排序功能。它不需要任何依赖,支持现代浏览器,而且使用起来超级简单!
首先,让我们引入Sortable.js:
<script src="https://cdn.jsdelivr.net/npm/sortablejs@1.15.0/Sortable.min.js">script>
基础拖拽排序
来实现一个最简单的列表排序效果:
<ul id="simple-list">
<li>项目1li>
<li>项目2li>
<li>项目3li>
<li>项目4li>
ul>
// 初始化Sortable
new Sortable(document.getElementById('simple-list'), {
animation: 150, // 动画过渡时间(毫秒)
ghostClass: 'blue-background' // 拖动时的样式类
});
.blue-background {
background: #e8f4f8 !important;
}
#simple-list li {
padding: 10px;
margin: 5px;
border: 1px solid #ddd;
cursor: move;
}
小贴士:animation设置为0可以关闭动画效果,但建议保留一点动画时间,这样用户体验更好!
多列表之间的拖拽
现在来点更刺激的!实现两个列表之间的拖拽:
<div class="list-container">
<h3>待办事项h3>
<ul id="todo">
<li>写代码li>
<li>看文档li>
<li>写博客li>
ul>
<h3>已完成h3>
<ul id="done">
<li>喝咖啡li>
<li>摸鱼li>
ul>
div>
// 初始化两个列表
const todo = document.getElementById('todo');
const done = document.getElementById('done');
new Sortable(todo, {
group: 'shared', // 设置相同的组名允许互相拖拽
animation: 150,
onAdd: function(evt) {
console.log('有新任务被添加!');
}
});
new Sortable(done, {
group: 'shared',
animation: 150,
onAdd: function(evt) {
console.log('完成了一个任务!');
}
});
⚠️ 注意事项:
高级功能展示
Sortable.js还有很多强大的功能:
new Sortable(document.getElementById('advanced-list'), {
animation: 150,
// 禁用特定项目的拖动
filter: '.disabled',
// 拖动开始时的回调
onStart: function(evt) {
evt.item.style.backgroundColor = '#f8f9fa';
},
// 拖动结束时的回调
onEnd: function(evt) {
evt.item.style.backgroundColor = '';
// 获取新的排序
console.log(evt.newIndex);
},
// 自定义拖动时的占位符
ghostClass: 'sortable-ghost',
// 拖动时的手柄
handle: '.handle'
});
进阶小技巧:
实战应用:图片排序
来做个实用的图片排序功能:
<div id="image-list">
<div class="image-item">
<img src="image1.jpg">
<span class="handle">⋮span>
div>
<div class="image-item">
<img src="image2.jpg">
<span class="handle">⋮span>
div>
div>
new Sortable(document.getElementById('image-list'), {
animation: 150,
handle: '.handle',
onSort: function(evt) {
// 保存新的排序到后端
const newOrder = Array.from(evt.target.children).map(
item => item.dataset.id
);
saveOrder(newOrder);
}
});
async function saveOrder(order) {
try {
await fetch('/api/update-order', {
method: 'POST',
body: JSON.stringify(order)
});
} catch (error) {
console.error('保存失败:', error);
}
}
.image-item {
display: flex;
align-items: center;
margin: 10px;
padding: 5px;
border: 1px solid #ddd;
}
.handle {
cursor: move;
padding: 5px;
font-size: 20px;
}
练习小任务
试试实现以下功能:
创建一个待办事项列表,完成后可以拖到"已完成"列表
添加动画效果和样式
保存排序结果到localStorage
小伙伴们,今天的HTML学习之旅就到这里啦!Sortable.js真的是一个特别实用的工具,它能让我们轻松实现各种拖拽排序功能。记得动手试试今天学到的代码,有问题随时在评论区问我哦。祝大家学习愉快,HTML学习节节高!