import React from 'react'; import ReactDOM from 'react-dom'; import PropTypes from 'prop-types'; /** * @author suxiaoxin * @demo * this.state.list} onChange={this.handleChange} > * {list} * */ let curDragIndex = null; function isDom(obj) { return ( obj && typeof obj === 'object' && obj.nodeType === 1 && typeof obj.nodeName === 'string' && typeof obj.getAttribute === 'function' ); } export default class EasyDragSort extends React.Component { static propTypes = { children: PropTypes.array, onChange: PropTypes.func, onDragEnd: PropTypes.func, data: PropTypes.func, onlyChild: PropTypes.string }; render() { const that = this; const props = this.props; const { onlyChild } = props; let container = props.children; const onChange = (from, to) => { if (from === to) { return; } let curValue; curValue = props.data(); let newValue = arrMove(curValue, from, to); if (typeof props.onChange === 'function') { return props.onChange(newValue, from, to); } }; return (
{container.map((item, index) => { if (React.isValidElement(item)) { return React.cloneElement(item, { draggable: onlyChild ? false : true, ref: 'x' + index, 'data-ref': 'x' + index, onDragStart: function() { curDragIndex = index; }, /** * 控制 dom 是否可拖动 * @param {*} e */ onMouseDown(e) { if (!onlyChild) { return; } let el = e.target, target = e.target; if (!isDom(el)) { return; } do { if (el && isDom(el) && el.getAttribute(onlyChild)) { target = el; } if (el && el.tagName == 'DIV' && el.getAttribute('data-ref')) { break; } } while ((el = el.parentNode)); if (!el) { return; } let ref = that.refs[el.getAttribute('data-ref')]; let dom = ReactDOM.findDOMNode(ref); if (dom) { dom.draggable = target.getAttribute(onlyChild) ? true : false; } }, onDragEnter: function() { onChange(curDragIndex, index); curDragIndex = index; }, onDragEnd: function() { curDragIndex = null; if (typeof props.onDragEnd === 'function') { props.onDragEnd(); } } }); } return item; })}
); } } function arrMove(arr, fromIndex, toIndex) { arr = [].concat(arr); let item = arr.splice(fromIndex, 1)[0]; arr.splice(toIndex, 0, item); return arr; }