一键生成sprite(雪碧图)以及 动态加载1X &2X&3X 图片

一. 为什么要使用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'), {
    animation150,  // 动画过渡时间(毫秒)
    ghostClass'blue-background'  // 拖动时的样式类
});

.blue-background {
    background#e8f4f8 !important;
}

#simple-list li {
    padding10px;
    margin5px;
    border1px 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',  // 设置相同的组名允许互相拖拽
    animation150,
    onAddfunction(evt{
        console.log('有新任务被添加!');
    }
});

new Sortable(done, {
    group'shared',
    animation150,
    onAddfunction(evt{
        console.log('完成了一个任务!');
    }
});

⚠️ 注意事项:

高级功能展示

Sortable.js还有很多强大的功能:

new Sortable(document.getElementById('advanced-list'), {
    animation150,
    // 禁用特定项目的拖动
    filter'.disabled',
    
    // 拖动开始时的回调
    onStartfunction(evt{
        evt.item.style.backgroundColor = '#f8f9fa';
    },
    
    // 拖动结束时的回调
    onEndfunction(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'), {
    animation150,
    handle'.handle',
    onSortfunction(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',
            bodyJSON.stringify(order)
        });
    } catch (error) {
        console.error('保存失败:', error);
    }
}

.image-item {
    display: flex;
    align-items: center;
    margin10px;
    padding5px;
    border1px solid #ddd;
}

.handle {
    cursor: move;
    padding5px;
    font-size20px;
}

练习小任务

试试实现以下功能:

创建一个待办事项列表,完成后可以拖到"已完成"列表

添加动画效果和样式

保存排序结果到localStorage

小伙伴们,今天的HTML学习之旅就到这里啦!Sortable.js真的是一个特别实用的工具,它能让我们轻松实现各种拖拽排序功能。记得动手试试今天学到的代码,有问题随时在评论区问我哦。祝大家学习愉快,HTML学习节节高!

本站内容来自用户投稿,如果侵犯了您的权利,请与我们联系删除。联系邮箱:835971066@qq.com

本文链接:http://news.xiuzhanwang.com/post/2235.html

发表评论

评论列表

还没有评论,快来说点什么吧~

友情链接: