| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118 |
- import React from 'react';
- import ReactDOM from 'react-dom';
- import PropTypes from 'prop-types';
- /**
- * @author suxiaoxin
- * @demo
- * <EasyDragSort data={()=>this.state.list} onChange={this.handleChange} >
- * {list}
- * </EasyDragSot>
- */
- 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 (
- <div>
- {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;
- })}
- </div>
- );
- }
- }
- function arrMove(arr, fromIndex, toIndex) {
- arr = [].concat(arr);
- let item = arr.splice(fromIndex, 1)[0];
- arr.splice(toIndex, 0, item);
- return arr;
- }
|