sortablejs的使用实践

news2025/2/25 12:01:46

文章目录

  • 说明
  • 基本使用
    • 1. 素颜版
    • 2. 设置可被拖起的项的样式
    • 3. 设置被选中的项的样式
    • 4. 设置拖拽时跟随的阴影的样式
    • 5. 设置正在被拖拽中的样式
    • 6. 设置当前列表容器内是否可以进行拖拽排序
    • 7. 设置拖拽的手柄
    • 8. 多个列表之间的拖拽 [group]
      • 示例1 [name]
      • 示例2 [put]
      • 示例3 [put function]
      • 示例4 [pull]
    • 9. 多个拖拽组嵌套
  • 学习来源

sortablejs 是一个强大的JavaScript拖拽库。

说明

在Angular项目中使用sortablejs拖拽库时,我们需要同时使用 ngx-sortablejs 这个二次封装的Angular拖拽库,它封装了 sortablejs 指令 ,并支持以下参数:

@Directive({
  selector: "[sortablejs]",
})
export class SortablejsDirective {
  // 拖拽列表的数据项
  @Input() sortablejs: SortableData; // array or a FormArray

  // 指定拖拽的容器
  @Input() sortablejsContainer: string;

  // 拖拽相关的配置项
  @Input() sortablejsOptions: Options;

  @Input() sortablejsCloneFunction: (item: any) => any;

  // 在一个拖拽实例被创建并初始化好之后,会立即emit出这个拖拽实例。
  @Output() sortablejsInit = new EventEmitter<Sortable>()
}

基本使用

1. 素颜版

<div
  class="container"
  [sortablejs]="items"
  [sortablejsOptions]="draggableOptions"
>
  <div *ngFor="let item of items" class="item">
    {{ item.name }}
  </div>
</div>
import { SortableOptions } from 'sortablejs';

draggableOptions: SortableOptions = {};

在这里插入图片描述

2. 设置可被拖起的项的样式

<div
  class="container"
  [sortablejs]="items"
  [sortablejsOptions]="draggableOptions"
>
  <ng-container *ngFor="let item of items">
    <div *ngIf="item.id !== '002'" class="item sortable-item">
      {{ item.name }}
    </div>
    <div *ngIf="item.id === '002'" class="item">
      {{ item.name }},这个项不可被拖起
    </div>
  </ng-container>
</div>
draggableOptions: SortableOptions = {
  // 允许拖拽的项的类名,只有这个类名的项才可以拖起 
  draggable: '.sortable-item',  
};
.sortable-item {
  background-color: antiquewhite;
}

在这里插入图片描述

3. 设置被选中的项的样式

draggableOptions: SortableOptions = {
  // 拖拽项被选中时的类名
  chosenClass: 'sortable-chosen',  
};
.sortable-chosen {
  background-color: lightblue;
}

在这里插入图片描述

4. 设置拖拽时跟随的阴影的样式

draggableOptions: SortableOptions = {
  // 项被拖拽的过程中跟随它的那个影子的类名
  ghostClass: 'sortable-ghost',  
};
.sortable-ghost {
  background-color: lightgray;
}

在这里插入图片描述

5. 设置正在被拖拽中的样式

draggableOptions: SortableOptions = {
  dragClass: 'sortable-drag',
};
.sortable-drag {
  background-color: orange;
  border-bottom: none;
}

在这里插入图片描述

6. 设置当前列表容器内是否可以进行拖拽排序

draggableOptions2: SortableOptions = {
  sort: false,  // 值为false,组内不可拖拽排序
  group: {
    name: 'china',
    pull: true, // 组内的项可以被拖出去到其它组
  }
};

7. 设置拖拽的手柄

<div
  class="container"
  [sortablejs]="items"
  [sortablejsOptions]="draggableOptions"
>
  <div *ngFor="let item of items" class="item sortable-item">
    <div class="sortable-handle">手柄</div>
    {{ item.name }}
  </div>
</div>
draggableOptions: SortableOptions = {
  // draggable: '.sortable-item',

  // 可拖拽项的手柄的类名,只有按住手柄才能拖起。(如果将上面那行注释放开,那就不只有手柄能拖拽了)
  handle: '.sortable-handle',
};

在这里插入图片描述

8. 多个列表之间的拖拽 [group]

示例1 [name]

配置项的group属性里的name相同的两个拖拽组之间的项可以互相拖拽。

// 甲组
draggableOptions1: SortableOptions = {
  group: {
    name: 'wmm', 
  }
};

// 乙组
draggableOptions2: SortableOptions = {
  group: {
    name: 'wmm', 
  }
};

在这里插入图片描述
在这里插入图片描述

示例2 [put]

多个拖拽组,name不同时,可以通过 put 指定其它组只有满足条件的项可以拖进当前列表。

// 甲组
draggableOptions1: SortableOptions = {
  group: {
    name: 'wmm',
  }
};

// 乙组
draggableOptions2: SortableOptions = {
  group: {
    name: 'china',
  }
};

// 丙组
draggableOptions3: SortableOptions = {
  group: {
    name: 'happy',

    /**
     * put字段的值可以指定为以下四种:
     * true: 可以将其它指定组的项拖进本组
     * false: 其它任何组的项都不能拖到本组
     * ['wmm', 'china']: 只能将甲组和乙组的项拖到本组。['china']: 只能将乙组的项拖到本组。
     * function: 自定义函数,可进行复杂逻辑判断,根据返回true或false,来判断当前被拖拽的项是否能往本组里放。
     */
    put: ['china'], // 指定甲组和乙组的项可以往丙组里面放
  }
};

在这里插入图片描述

示例3 [put function]

多个拖拽组,可以通过指定 put 的值为function,在function里进行复杂判断来确定被拖拽的项是否可以被拖进本组。

<div
  class="container2"
  [sortablejs]="items2"
  [sortablejsOptions]="draggableOptions2"
>
  乙组
  <div
    *ngFor="let item of items2"
    class="item sortable-item2"
    [ngClass]="{
      'can-move-to-happy': item.name.indexOf('乙 5') === -1
    }"
  >
    {{ item.name }}
    {{ item.name.indexOf("乙 5") !== -1 ? "--该项不可用被拖进丙组" : "" }}
  </div>
</div>
// 乙组
draggableOptions2: SortableOptions = {
  group: {
    name: 'china',
  }
};

// 丙组
draggableOptions3: SortableOptions = {
  group: {
    name: 'happy',

    /**
     * put的值可以是一个自定义function,可进行复杂逻辑判断。
     * 根据返回true或false,来判断当前被拖拽的项是否能往本组里放。
     */
    put: (
      to: Sortable,
      from: Sortable,
      dragEl: HTMLElement,
      event: SortableEvent
    ) => {
      // 判断:只有带有样式类名为'can-move-to-happy'的项,才能被拖进本组。
      return dragEl?.classList.contains('can-move-to-happy');
    },
  }
};

在这里插入图片描述
在这里插入图片描述

示例4 [pull]

draggableOptions2: SortableOptions = {
  group: {
    name: 'china',
    /**
     * 从一个列表中拖动到另一个列表时,是否允许拖动。 默认值:true。
     * true:允许拖动
     * false:不允许拖动
     * 'clone':克隆一个副本拖到其它组
     * function:自定义函数,可进行复杂逻辑判断,根据返回true或false,来判断被拖拽的项是否可从本组移出去。
     */
    pull: (
      to: Sortable,
      from: Sortable,
      dragEl: HTMLElement,
      event: SortableEvent
    ) => {
      return !dragEl?.classList.contains('can-move-to-happy');
    },
  },
};

此示例就不截图了。

9. 多个拖拽组嵌套

<div
  class="grandpa-container"
  [sortablejs]="treeItems"
  [sortablejsOptions]="draggableOptions"
>
  <div
    *ngFor="let grandpa of treeItems"
    class="item"
    [id]="grandpa.id"
    [ngClass]="{
      a: grandpa.name.indexOf('') !== -1,
      b: grandpa.name.indexOf('') !== -1,
      c: grandpa.name.indexOf('') !== -1
    }"
  >
    {{ grandpa?.name }}

    <ng-container *ngIf="grandpa?.children?.length">
      <div
        class="father-container"
        [id]="grandpa.id"
        [sortablejs]="grandpa?.children"
        [sortablejsOptions]="draggableOptions"
      >
        <div
          *ngFor="let father of grandpa?.children"
          class="item"
          [id]="father.id"
          [ngClass]="{
            a: father.name.indexOf('') !== -1,
            b: father.name.indexOf('') !== -1,
            c: father.name.indexOf('') !== -1
          }"
        >
          {{ father?.name }}

          <ng-container *ngIf="father?.children?.length">
            <div
              class="son-container"
              [id]="father.id"
              [sortablejs]="father?.children"
              [sortablejsOptions]="draggableOptions"
            >
              <div
                *ngFor="let son of father?.children"
                class="item"
                [id]="son.id"
                [ngClass]="{
                  a: son.name.indexOf('') !== -1,
                  b: son.name.indexOf('') !== -1,
                  c: son.name.indexOf('') !== -1
                }"
              >
                {{ son?.name }}
              </div>
            </div>
          </ng-container>
        </div>
      </div>
    </ng-container>
  </div>
</div>
public draggableOptions: SortableOptions = {
  group: {
    name: 'wmm',
  }

  // 元素 从其它拖拽分组 拖进 本拖拽分组 时触发
  onAdd: (event: SortableEvent) => {
    console.log('onAdd event:', event);
    console.log('自身id:', event.item.id);
    console.log('当前所属父id:', event.to.id);
    console.log('在当前分组中的index:', event.newIndex);
  },

  // 元素在本拖拽分组中的位置发生改变时触发
  onUpdate: (event: SortableEvent) => {
    console.log('onUpdate event:', event);
  },
};



public treeItems: {
  id: string;
  name: string;
  children?: any[] = [];
} = [];

ngOnInit(): void {
  // 初始化 treeItems
  for (let i = 0; i < 5; i++) {
    let grandpa: any = { id: `0${i}`, name: `甲 0${i}`, children: [] };
    if (i === 1) {
      let fathers: any = [];
      for (let j = 0; j < 5; j++) {
        const fatherItem: any = {
          id: `00${j}`,
          name: `乙 00${j}`,
        };
        if (j === 4) {
          let sons: any = [];
          for (let k = 0; k < 5; k++) {
            const sonItem = {
              id: `000${k}`,
              name: `丙 000${k}`,
            };
            sons.push(sonItem);
          }
          fatherItem.children = sons;
        }
        fathers.push(fatherItem);
      }
      grandpa.children = fathers;
    }
    this.treeItems.push(grandpa);
  }
}

第一次拖拽:
在这里插入图片描述
在这里插入图片描述

第二次拖拽:
在这里插入图片描述
在这里插入图片描述

学习来源

更多配置项及回调方法: http://www.sortablejs.com/options.html
更多示例: http://sortablejs.github.io/Sortable/
Sortable仓库: https://github.com/SortableJS/Sortable
ngx-sortablejs仓库 https://github.com/sortablejs/ngx-sortablejs#readme

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/405564.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【前端】图片懒加载的原理和三种实现方式

一. 图片懒加载的目的 大型网站如常用的淘宝&#xff0c;京东等页面&#xff0c;需要展示大量的商品图片信息&#xff0c;如果打开网页时让所有图片一次性加载完成&#xff0c;需要处理很多次网络请求&#xff0c;等待加载时间比较长&#xff0c;用户体验感很差。 有一种常用…

基于 vite 创建 vue3 全家桶项目(vite + vue3 + tsx + pinia)

vite 最近非常火&#xff0c;它是 vue 作者尤大神发布前端构建工具&#xff0c;底层基于 Rollup&#xff0c;无论是启动速度还是热加载速度都非常快。vite 随 vue3 正式版一起发布&#xff0c;刚开始的时候与 vue 绑定在一起&#xff0c;但之后的 v2 版本便比较独立&#xff0c…

什么是垃圾回收机制(超详细)

垃圾回收机制 1.垃圾回收机制&#xff08;Garbage Collction&#xff09;简称GC&#xff0c;是JavaScript中使用的内存管理系统的基本组部分&#xff0c;是为了防止内存泄漏 2.JavaScript是在创建变量&#xff08;对象、字符串等&#xff09;时自动进行了分配内存&#xff0c;并…

Web实训项目--网页设计(附源码)

1 实训基本信息 1.1 实训项目名称 网页设计 1.2 实训环境 本次实训的形式以实战讲解为主&#xff0c;以项目为主导。学习如何设计网页中的轮播图和动画效果&#xff0c;并掌握a标签文本内容跳转、超链接的应用、播放音乐与视频等操作。 2 实训内容简介 2.1 网页设计 通过…

关于vue中如何清除定时器的方法

一、问题 1、在vue中使用setTimeout定时器的时候&#xff0c;可能会遇到关不掉的情况&#xff0c;会存在明明已经在beforeDestroy和destroyed中设置了定时器清除了&#xff0c;但是有时候没生效&#xff0c;定时器还会继续执行。 2、在这里需要说一下setTimeout的使用场景&am…

路由vue-route的使用

文章目录一、项目初始化二、路由配置规则vue-route标签作用&#xff1a;路由匹配到的组件将渲染到这里router-link标签作用&#xff1a;路由导航&#xff08;路由跳转的链接&#xff09;三、声明式导航和编程式导航声明式导航编程式导航四、路由重定向五、嵌套路由特别注意总结…

04-vscode搭建cmake的编译环境

vscodemingw搭建C/C环境系列 01.vscodemingw搭建编译调试环境 02-vscode编译调试单个源文件程序 03-vscode编译调试多个源文件程序 04-vscode搭建cmake的编译环境 文章目录一、简述二、vscode搭建cmake的编译环境&#xff08;方法1&#xff09;1.配置cmake构建目录(可忽略)…

Redux——详解

一.初识Redux 相当于vue中的vuex 1.redux 是一个独立专门用于做状态管理的 JS 库(不是 react 插件库) 2.它可以用在 react, angular, vue 等项目中, 但基本与 react 配合使用 3.作用: 集中式管理 react 应用中多个组件共享的状态 看看Redux的工作原理图 如果要进行加一操作…

ES6---promise详解及用法

一、什么是Promise Promise是ES6异步编程的一种解决方案(目前最先进的解决方案是async和await的搭配&#xff08;ES8&#xff09;&#xff0c;但是它们是基于promise的)&#xff0c;从语法上讲&#xff0c;Promise是一个对象或者说是构造函数&#xff0c;用来封装异步操作并可…

炫酷登录注册界面【超级简单 jQuery+JS+HTML+CSS实现】

一&#xff1a;源码获取 这两天根据需求写了一个比较好看的有动态效果的登录注册切换页面&#xff0c;这里我将源码资源分享给大家&#xff0c;大家可以直接免费下载使用哦&#xff0c;没有 vip 的小伙伴找我私聊发送"登录注册"即可我给你发文件&#xff0c;此登录注…

四、vue中路由router配置详解

目录 一、vue中的路由作用 二、vue中的路由router 使用步骤 三、路由跳转 1、带参数路由跳转&#xff1a; &#xff08;1&#xff09;this.$router.push() &#xff1a; &#xff08;2&#xff09;this.$router.replace() &#xff1a; 2、不带参数路由跳转 3、this.…

【手把手教安装】VUE安装教程+VScode配置!!!

含泪整理Vue安装教程 因为换了新电脑很多软件要重装&#xff0c;所以想到可以写一份教程&#xff0c;为我以后换电脑方便重装也为了大家&#xff01;&#xff01; 第一次安装Vue踩坑太多&#xff0c;这里整理一份超详细教程&#xff08;win11也可&#xff01;&#xff01;&…

uniapp 控制台警告 DevTools failed to load SourceMap: Could not load content for http://127.0.0.1问题解决

在uniapp中控制台警告&#xff0c;这是用于在开发时定位到报错的源码位置的工具SourceMap出问题了&#xff0c;如果单纯只是想消除这个警告的方法写在下面第一个&#xff0c;真正解决工具问题的方法是第二个&#xff08;需要下载一个插件&#xff09;&#xff0c;现在放在这边做…

如何修复运行缓慢的 WordPress 网站?

&#x1f482; 个人网站:【海拥】【摸鱼游戏】【神级源码资源网站】&#x1f91f; 前端学习课程&#xff1a;&#x1f449;【28个案例趣学前端】【400个JS面试题】&#x1f485; 想寻找共同学习交流、摸鱼划水的小伙伴&#xff0c;请点击【摸鱼学习交流群】 就其 SEO 而言&…

npm、nrm两种方式查看源和切换镜像

一、使用npm查看当前源、切换淘宝镜像、切换官方源 &#xff08;1&#xff09;npm查看当前源&#xff1a; npm get registry&#xff08;2&#xff09;npm设置淘宝镜像源&#xff1a; npm config set registry http://registry.npm.taobao.org&#xff08;3&#xff09;npm设…

2023 前端一场面试及答案整理

金三马上就要开始了&#xff0c;俗话说得好&#xff0c;知己知彼百战百胜&#xff0c;多准备总是没有错的。以面试的形式和大家一起学习、一起回顾我们的职场生涯。今天简单总结一下我个人去面试&#xff0c;包括我在面试别人时的经验。加油加加油&#xff01;&#xff01;&…

2022最新Nodejs下载安装配置步骤(保姆级教程)

1. 进入官网选择下载版本 http://nodejs.cn/download/2.安装过程 步骤1&#xff1a;选择next选项 步骤2&#xff1a;勾选接受协议选项&#xff0c;点击 next&#xff08;下一步&#xff09;按钮 : 步骤3&#xff1a;其默认安装目录是C:\Program Files\nodejs\&#xff0c;当…

【Python】ttkbootstrap的介绍与使用

一、什么是ttkbootstrap&#xff1f; 官方文档 [较慢]&#xff1a;https://ttkbootstrap.readthedocs.io/en/latest/ ttkbootstrap 是一个基于 tkinter 的界面美化库&#xff0c;使用这个工具可以开发出类似前端 bootstrap 风格的 tkinter 桌面程序 二、安装步骤 安装命令…

Vue项目安装less和less-loader

第一步&#xff1a;查看webpack和webpack-cli是否安装 打开cmd&#xff0c;通过命令查看 webpack -vwebpack-cli -v如果没有安装&#xff0c;要先进行安装 可以通过 npm view webpack version / npm view webpack-cli version 查看当前webpack的最新版本 可以通过 npm vie…

什么是axios(写给小白的理解笔记)

0.为什么会诞生axios 最初浏览器页面向服务器请求数据时&#xff0c;返回的是整个页面&#xff0c;整个页面都会刷新&#xff0c;当我们只需要请求部分数据时&#xff0c;返回整个页面会造成网络资源的占用&#xff0c;为了提高数据请求效率&#xff0c;异步网络请求Ajax出现了…