react-dnd中useDrag的drag和dragPreview

3,554 阅读2分钟
  1. drag是添加到想要被拖拽的DOM元素上
  2. dragPreview会影响DOM元素拖拽时,在视觉效果上,页面上面实际跟着鼠标移动的DOM元素数量
  3. 多drag只有最后一个drag会生效
  4. 单drag和单dragPreview——drag和dragPreview绑定的DOM元素存在父子关系,那么视觉效果上页面上面跟着鼠标移动的元素将会是父元素和它下面的所有子元素
import React from 'react';
import { useDrag } from 'react-dnd';
const TestDrag = () => {
  const [{ opacity }, drag, dragPreview] = useDrag({
    item: { type: 'drag' },
    collect(monitor) {
      return { opacity: monitor.isDragging() ? 0.4 : 1 }
    }
  })
  return (
    <div style={{ paddingLeft: 200, paddingTop: 300 }}>
      <div className="dragBox" style={{ width: 300, height: 200, background: 'lightBlue' }} ref={dragPreview}>
        <span>这是行内元素span</span>
        <p>这是块级元素p</p>
        <div className="drag" ref={drag} style={{ width: 200, height : 100, backgroundColor: 'lightgreen', opacity}} >这是drag</div>
      </div>
    </div>
  )
}
export default TestDrag;

第一种情况.png 5. 单drag和单dragPreview——drag和dragPreview绑定的元素不存在父子关系,那么视觉效果上页面上面跟着鼠标移动的元素将会是dragPreview绑定的DOM元素

import React from 'react';
import { useDrag } from 'react-dnd';
const TestDrag = () => {
  const [{ opacity }, drag, dragPreview] = useDrag({
    item: { type: 'drag' },
    collect(monitor) {
      return { opacity: monitor.isDragging() ? 0.4 : 1 }
    }
  })
  return (
    <div style={{ paddingLeft: 200, paddingTop: 300 }}>
      <div className="drag" ref={drag} style={{ width: 200, height : 100, backgroundColor: 'lightgreen', opacity}} >这是drag</div>
      <div className="dragBox" style={{ width: 300, height: 200, background: 'lightBlue' }} ref={dragPreview}>
        <span>这是行内元素span</span>
        <p>这是块级元素p</p>
      </div>
    </div>
  )
}
export default TestDrag;

第二种情况.png 6. 单drag和多dragPreview——如果多个dragPreview都绑定在drag元素的父元素上,那么视觉效果上页面上面跟着鼠标移动的元素将会是最外层父元素和其下所有子元素

import React from 'react';
import { useDrag } from 'react-dnd';

const TestDrag = () => {
  const [{ opacity }, drag, dragPreview] = useDrag({
    item: { type: 'drag' },
    collect(monitor) {
      return { opacity: monitor.isDragging() ? 0.4 : 1 }
    }
  })
  return (
    <div style={{ paddingLeft: 200, paddingTop: 300 }}>
      <div style={{ width: 400, height: 300, background: 'cyan' }}>
        <div style={{ width: 350, height: 250, background: 'brown' }} ref={dragPreview}>
          <div className="dragBox" style={{ width: 300, height: 200, background: 'lightBlue' }} ref={dragPreview}>
            <span>这是行内元素span</span>
            <p>这是块级元素p</p>
            <div className="drag" ref={drag} style={{ width: 200, height : 100, backgroundColor: 'lightgreen', opacity}} >这是drag</div>
          </div>
        </div>
      </div>
    </div>
  )
}
export default TestDrag;

第三种情况.png 7. 单drag和多dragPreview——如果多个dragPreview中和drag元素不存在父子关系的那些DOM都是排在drag的前面,那效果和(6)一样

import React from 'react';
import { useDrag } from 'react-dnd';
const TestDrag = () => {
  const [{ opacity }, drag, dragPreview] = useDrag({
    item: { type: 'drag' },
    collect(monitor) {
      return { opacity: monitor.isDragging() ? 0.4 : 1 }
    }
  })
  return (
    <div style={{ paddingLeft: 200, paddingTop: 300 }}>
      <div style={{ width: 400, height: 300, background: 'orange' }} ref={dragPreview}>单飞的dragPreview</div>
      <div style={{ width: 400, height: 300, background: 'cyan' }}>
        <div style={{ width: 350, height: 250, background: 'brown' }} ref={dragPreview}>
          <div className="dragBox" style={{ width: 300, height: 200, background: 'lightBlue' }} ref={dragPreview}>
            <span>这是行内元素span</span>
            <p>这是块级元素p</p>
            <div className="drag" ref={drag} style={{ width: 200, height : 100, backgroundColor: 'lightgreen', opacity}} >这是drag</div>
          </div>
        </div>
      </div>
    </div>
  )
}
export default TestDrag;

第四种情况.png 8. 单drag和多dragPreview——如果最后的一个dragPreview与drag元素不存在父子关系,而且还排在最后面,那么效果和(5)一样

import React from 'react';
import { useDrag } from 'react-dnd';
const TestDrag = () => {
  const [{ opacity }, drag, dragPreview] = useDrag({
    item: { type: 'drag' },
    collect(monitor) {
      return { opacity: monitor.isDragging() ? 0.4 : 1 }
    }
  })
  return (
    <div style={{ paddingLeft: 200, paddingTop: 300 }}>
      <div style={{ width: 400, height: 300, background: 'cyan' }}>
        <div style={{ width: 350, height: 250, background: 'brown' }} ref={dragPreview}>
          <div className="dragBox" style={{ width: 300, height: 200, background: 'lightBlue' }} ref={dragPreview}>
            <span>这是行内元素span</span>
            <p>这是块级元素p</p>
            <div className="drag" ref={drag} style={{ width: 200, height : 100, backgroundColor: 'lightgreen', opacity}} >这是drag</div>
          </div>
        </div>
      </div>
      <div style={{ width: 400, height: 300, background: 'orange' }} ref={dragPreview}>单飞的dragPreview</div>
    </div>
  )
}
export default TestDrag;

第五种情况.png