拖拽排序组件github地址:https://github.com/vicecho/vdraggable.git
因为使用了react.js技术栈,所以封装优先考虑输入和输出。基于数据驱动去渲染页面、控制拖拽元素的顺序。
由于我不考虑兼容ie8等旧版本浏览器,拖拽的效果采用了html5的拖放(drag 和 drop)。当然,如果要求兼容性丰富,使用鼠标点击的相关事件也很简单。
实现的效果如下:
第一步是先了解h5拖放的相关属性,mdn上有详细的说明,链接为https://developer.mozilla.org/en-us/docs/web/events/dragstart
有一点需要注意的是,react.js会给所有的属性事件名称前加上”on”,后面则为驼峰式写法。例如原生的click事件,在react.js里应使用onclick事件。
我的组件使用的拖放属性如下:
draggable 当设置为true时,当前控件可以拖拽ondragstart 控件开始被拖拽时触发的事件,它提供一个datatransfer.tdata()方法,将必要的数据存储在对象中便于在其它方法中调用ondragover 规定当前控件可以接收拖拽的组件的方法,一般在此方法中阻止冒泡ondragenter 拖动后鼠标进入另一个可接受区域时触发,通过它可以实现移入效果ondragleave a拖到b,离开b的时候触发,可以用于监听消除移入效果的时机ondrop 当控件被“释放”到一个有效的释放目标位置时触发,我在这个方法中处理数据,并通过它调用onchange方法,将value值暴露给父组件其中draggable,ondragstart是被“拖拽”方需要设置的属性,ondragover,ondragenter,ondragleave和ondrop是被“拖入”方需要设置的属性。不过对于我的拖拽排序组件,每一个元素都是拖拽和拖入方
第二步,既然“她”是react.js的组件, 按照习惯,简单的将输入属性定为为value,同时,暴露onch成都野生世界ange事件监听value的变化,并将其暴露给父组件,同时,暴露一个属性sortkey告诉组件使用哪个key作为排序字段。
既然涉及到排序,同时允许指定组件每个元素的内部子组件,我将输入数据格式定义为一个数组对象,其中content可以为reactno外交政策宗旨de:
value: [ { content: 'div1', code: '01', sort: 0, }, { content: 'div2', code: '02', sort: 1 }, { content: 'div3', code: '03', sort: 2 }, { content: 'div5', 北京过年哪里好玩 code: '05', sort: 5 }, { content: 'div4', code: '04', sort: 4 }]
根据value我去生成可排序组件的每个node,关键代码如下:
// 生成拖拽组件 createdragglecomponent(data, sortkey, style, uid) { return data.sort(this.compare(sortkey)).map((item) => { return ( <div classname={styles.content} key={item.code} draggable={true} ondragenter={this.dragenter.bind(this)} ondragleave={this.dragleave.bind(this)} ondragstart={this.domdrugstart.bind(this, item[sortkey], item.code, uid, item)} ondrop={this.drop.bind(this, item[sortkey], 武汉理工大学专业data, sortkey, uid)} ondragover={this.allowdrop.bind(this)} style={{ ...style }}>{item.content}</div> ) }) } render() { const { value, sortkey, style } = this.props; return ( <row> <div style={{ display: 'flex', flexdirection: 'row' }}> {this.createdragglecomponent(value, sortkey, style)} </div> </row> ) }
其中的属性方法具体实现:
// 拖动事件 domdrugstart(sort, code, ee) { ee.datatransfe龚自珍的简介r.tdata("code", code); ee.datatransfer.tdata("sort", sort); } // 拖动后鼠标进入另一个可接受区域 dragenter(ee) { ee.target.style.border = '2px dashed #008dff'; ee.target.style.boxshadow = '0 0 8px rgba(30, 144, 255, 0.8)'; } // a拖到b,离开b的时候触发 dragleave(ee) { ee.target.style.border = '1px solid grey'; ee.target.style.boxshadow = ''; } // 对象排序 compare(key) { return (obj1, obj2) => { if (obj1[key] < obj2[key]) { return -1; } el if (obj1[key] > obj2[key]) { return 1; } return 0 } } // 当一个元素或是选中的文字被拖拽释放到一个有效的释放目标位置时 drop(dropedsort, data, sortkey, ee) { ee.preventdefault(); const code = ee.datatransfer.getdata("code"); const sort = ee.datatransfer.getdata("sort"); if (sort < dropedsort) { data.map(item => { if (item.code === code) { item[sortkey] = dropedsort; } el if (item[sortkey] > sort && item[sortkey] < dropedsort + 1) { item[sortkey]--; } return item; }); } el { data.map(item => { if (item.code === code) { item[sortkey] = dropedsort; } el if (item[sortkey] > dropedsort - 1 && item[sortkey] < sort) { item[sortkey]++; } return item; }); } this.props.onchange(data) } allowdrop(ee) { ee.preventdefault(); }
值得注意的点其实只有一个,我控制顺序的时候,并没有使用.target.before(document.getelementbyid({id}))去实际操控节点,而是在每次触发ondrop时间的时候,处理数据的sort,并通过onchange事件暴露给父组件,将数据输出,通过改变value值触发虚拟dom重新去渲染,以此控制顺序。
根据公司的要求,在此基础上,我还实现了拖拽复制的功能,这个等下次自己不懒的时候再记录下来。
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持www.887551.com。
本文发布于:2023-04-03 08:40:07,感谢您对本站的认可!
本文链接:https://www.wtabcd.cn/fanwen/zuowen/4b24989fb9bf013ba46378aa9ffca9c3.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文word下载地址:基于Html5实现的react拖拽排序组件示例.doc
本文 PDF 下载地址:基于Html5实现的react拖拽排序组件示例.pdf
留言与评论(共有 0 条评论) |