页面拖拽排序案例

h5中给元素新增了draggable全局属性,定义了元素的可拖拽属性。在项目中,拖拽排序也是比较常见的需求。

截屏2021-12-16 下午4.17.26.png

上图view层的代码如下

const SelectArea = observer((props: { store: Store; }): React.ReactElement => {
 const { categoryIconList, deleteWashIcon, emptyIconNum, onDrag } = props.store;
 useLayoutEffect(() => {
   onDrag();
 }, []);
 return (
   <div
     className={styles.selectArea}
     id="selectArea"
   >
     <Alert
       banner
       className={styles.alert}
       icon={(<InfoCircleOutlined/>)}
       message="最多选择8个图标,支持长按拖动排序"
       type="info"
     />
     <Row style={{ alignItems: 'center' }}>
       {
         categoryIconList.map((item) => (
           <EachIcon
             deleteWashIcon={() => {
               deleteWashIcon(item);
             }}
             key={item}
             showDelete
             url={item}
           />
         ))
       }
       {
         emptyIconNum.map((item) => (
           <AddIcon key={item}/>
         ))
       }
       <Col span={3}>
         <Button type="primary">
           保存
         </Button>
       </Col>
     </Row>
   </div>
 );
});

在拖动上图的图标时可以交换图标的位置,具体的逻辑和代码实现如下,在组件挂载时将onDrag方法执行。

  // 拖动排序事件绑定
  public onDrag = () => {
    const selectArea = document.getElementById('selectArea');

    selectArea.addEventListener('dragstart', (e) => {
      // @ts-ignore
      const dragUrl = e.target.getAttribute('src');
      this.dragIndex = this.categoryIconList.findIndex((item) => item === dragUrl);
    });

    // 将dragover的默认事件取消后才能触发drop事件
    selectArea.addEventListener('dragover', (e) => {
      e.preventDefault();
    });

    selectArea.addEventListener('drop', (e) => {
      // @ts-ignore
      if (e.target.nodeName !== 'IMG') {
        return;
      }

      // @ts-ignore
      const dragTargetUrl = e.target.getAttribute('src');

      const targetInex = this.categoryIconList.findIndex((item) => item === dragTargetUrl);
      if (this.dragIndex === targetInex) {
        ret
      }
      this.categoryIconList = this.swap(this.categoryIconList, this.dragIndex, targetInex);

      this.dragIndex = -1;
    });
  };

该段代码的逻辑如下,采用事件委托的方式给这些图标的父级元素selectArea绑定dragstart和drop方法,通过e.target来获取img的src值,从而获取数组的index值实现换序。设置了draggable属性的元素即可触发drag的一系列方法(图片和链接是默认自带draggable属性)。要注意的是为了触发元素的ondrop方法,要将元素的dragover默认事件取消掉。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。