如何在ExtJS或JavaScript中实现可拖拽交换位置的组件
ExtJS/JavaScript实现可交换位置组件的解决方案
你当前只配置了draggable: true仅开启了组件的拖拽移动能力,没有配置拖拽放置的接收逻辑,所以拖拽后组件会直接重叠,不会触发位置调整。
ExtJS原生实现方案
通过ExtJS自带的拖拽(DD)体系,给组件同时配置拖拽源和放置目标,拖拽结束后交换两个组件在父容器中的索引即可实现位置互换,修改后的参考代码如下:
xtype : "panel", title: 'My Apps', region: 'east', width: 290, itemId: 'parentPanel', // 父容器加唯一标识方便调用 defaults: { xtype: 'panel', cls: 'myCLS', draggable: true, ddGroup: 'panelSwapGroup', // 同一组内的组件才可互相拖拽交换 listeners: { render: function(panel) { // 原有点击事件逻辑保留 panel.body.on('click', function() { alert('onclick'); }); // 新增放置目标逻辑,接收同组拖拽组件 panel.dropTarget = Ext.create('Ext.dd.DropTarget', panel.getEl(), { ddGroup: 'panelSwapGroup', notifyDrop: function(source, event, data) { const dragPanel = data.panel; const dropPanel = panel; const parent = Ext.ComponentQuery.query('#parentPanel')[0]; // 获取两个组件的索引位置 const dragIndex = parent.items.indexOf(dragPanel); const dropIndex = parent.items.indexOf(dropPanel); if (dragIndex !== dropIndex) { // 先临时移除拖拽组件不销毁,再插入到目标位置 parent.remove(dragPanel, false); parent.insert(dropIndex, dragPanel); // 触发父容器重绘更新布局 parent.doLayout(); } return true; } }); }, // 拖拽源绑定组件数据,放置时可识别拖拽对象 afterrender: function(panel) { panel.dd.data.panel = panel; } } }, items:[{ iconCls : 'app-info-appstore', title: 'Home', html : 'Home.' },{ iconCls : "app-info-iconToure", title: 'Profile', html : 'Apps' }]
注意:如果父容器内有多个可交换组件,该逻辑也可通用,无需单独调整
第三方库备选方案
- 普通JavaScript项目可使用SortableJS,零依赖、轻量,仅需绑定父容器即可实现子元素拖拽排序、位置互换,配置成本极低
- 已引入jQuery的项目可使用jQuery UI的sortable组件,适配性好,可自定义的交互配置项丰富
内容的提问来源于stack exchange,提问作者David
相关产品推荐
相关产品推荐

