为啥“draggable = 'true'”不能在 React 渲染组件上工作?

Posted

技术标签:

【中文标题】为啥“draggable = \'true\'”不能在 React 渲染组件上工作?【英文标题】:Why won't "draggable = 'true'" work on React rendered component?为什么“draggable = 'true'”不能在 React 渲染组件上工作? 【发布时间】:2015-06-16 02:06:53 【问题描述】:

这让我很生气,希望有人能提供帮助。

我有这个 React.Component:

var Vehicle = React.createClass(
    ondragend: function(e) 
      e.preventDefault();
      // Logic here
        console.log('onDragOver');
    ,
    ondragstart: function(e)
      e.preventDefault();
      console.log('ondragstart');
    ,
    render: function() 
    that = this
    var loads = this.props.truck.map(function(load , i)
        load.truckid = i
        return (
                <tr key=i draggable="true" dragstart=that.ondragstart dragend=that.ondragend>
                    <td>
                        load.load_number
                    </td>
                    <td>
                        load.stops[0].location_name
                    </td>
                    <td>
                        load.stops[1].location_name
                    </td>
                </tr>
        )
    )
    return (
            <div className="panel panel-primary" draggable="true">
                <VehiclePanelHeading vehicleNbr=this.props.vehicleNbr></VehiclePanelHeading>
                <div className="panel-body" >
                    <table className="table">
                        <tbody>
                            loads
                        </tbody>
                    </table>
                </div>
            </div>
    )

);

如您所见,我正在尝试使 s 可拖动。不幸的是,这不起作用,即使我使用 Chrome 开发工具手动将其添加到浏览器的 html 中。

我已经尝试删除我到 Bootstrap 的链接,以防这与 CSS 规则有关,并且还尝试仅呈现没有动态值的 html 表格。

我看不到这个小提琴中的代码:

jsFiddle

通过在渲染函数中设置 draggable=true 来工作,但我的不会。

提前感谢您的帮助。

编辑 添加了 dropEnd/Start 处理程序,但没有变化。

奇怪的是,如果我将 draggable=true 添加到 div.panel 容器中,它是可拖动的,而包含的 s 仍然不是。

更新

如果我用这个表创建一个快速的 .html 页面:

                       <table className="table">
                        <thead>
                            <tr>
                                <td>Name</td>
                                <td>Tangyness</td>
                            </tr>
                        </thead>
                        <tbody>
                            <tr draggable="true">
                                <td>Apple</td>
                                <td>4</td>
                            </tr>
                            <tr draggable="true">
                                <td>Orange</td>
                                <td>7</td>
                            </tr>
                        </tbody>
                    </table>

然后所需的 draggble = true 适用于表格行。但是,如果我将其粘贴到 React 渲染函数中:

        return (
            <div className="panel panel-primary" >
                <VehiclePanelHeading vehicleNbr=this.props.vehicleNbr></VehiclePanelHeading>
                <div className="panel-body" >
                    <table className="table">
                        <thead>
                            <tr>
                                <td>Name</td>
                                <td>Tangyness</td>
                            </tr>
                        </thead>
                        <tbody>
                            <tr draggable="true">
                                <td>Apple</td>
                                <td>4</td>
                            </tr>
                            <tr draggable="true">
                                <td>Orange</td>
                                <td>7</td>
                            </tr>
                        </tbody>
                    </table>
                </div>
            </div>
    )

然后突然间,“可拖动性”就消失了。

【问题讨论】:

【参考方案1】:

它应该可以工作,但您可能也想实现 onDragOver 事件。否则它看起来好像不起作用,因为您可以拖动组件,但没有任何合法的地方可以放置它。 onDragOver 允许您指定一个元素是否接受拖放以及它接受哪些元素。

正如您在链接的小提琴中看到的那样,onDragOver 事件看起来像这样

onDragOver: function(e) 
    e.preventDefault();
    // Logic here

调用e.preventDefault(); 告诉浏览器这里可以删除。您可以将 onDragOver 事件放在任何父元素上,或放在 tr 本身上。 You can read more about drop targets here. 如果您从 jsFiddle 中删除 onDragOver 事件,您链接的小提琴中的代码也会停止运行。

如果您实现 onDragOver,您将能够在您的表上实现一个 onDrop 事件来处理丢弃的 tr 元素。

这是您实现了事件的代码:

var Vehicle = React.createClass(
    onDragOver: function(e) 
      e.preventDefault();
      // Logic here
      console.log('onDragOver');
    ,
    onDragStart: function(e)
        e.dataTransfer.setData('id', 'setTheId');
        console.log('onDragStart');
    ,
    onDrop: function(e) 
        console.log('onDrop');
        var id = event.dataTransfer.getData('id');
        console.log('Dropped with id:', id);
    ,
    render: function() 
        that = this;
        var loads = this.props.truck.map(function(load , i)
            load.truckid = i
            return (

                    <tr key=i draggable="true" onDragOver=that.onDragOver onDragStart=that.onDragStart>
                        <td>
                            load.load_number
                        </td>
                        <td>
                            load.stops[0].location_name
                        </td>
                        <td>
                            load.stops[1].location_name
                        </td>
                    </tr>

            )
        )
        return (
                <div>
                    <div className="panel-body" >
                        <table className="table" onDrop=this.onDrop>
                            <tbody>
                                loads
                            </tbody>
                        </table>
                    </div>
                </div>
        )
     
);

这是一个 jsFiddle:http://jsfiddle.net/kb3gN/10761/

【讨论】:

感谢您的快速回复!我根据上面的编辑实现了更改,但没有更改。奇怪的是,父 div.panel 确实响应了 draggable=true - 从这里我假设这与 Reacts shadow div 或渲染节点的可用性无关。 太棒了!谢谢。最后一件事:你知道为什么拖动时dragElement不出现吗?即占位符?在实施您的代码更改后,我现在正在关注这篇文章:webcloud.se/sortable-list-component-react-js 在要点中,该元素在拖动时保持可见 - 我的消失了。 我不知道,抱歉。占位符与 div、图像、列表项等一起出现。可能与表格有关。【参考方案2】:

该项目似乎没有拖动的原因是您在onDragStart 函数内有e.preventDefault();,这会阻止它显示默认的拖动动作。只需删除该行,它就会看起来像这样并且它应该可以工作:

var Vehicle = React.createClass(
  ...
  onDragStart: function(e)
    // REMOVED THIS LINE
    //e.preventDefault();

    console.log('ondragstart');
  ,
  ...

【讨论】:

以上是关于为啥“draggable = 'true'”不能在 React 渲染组件上工作?的主要内容,如果未能解决你的问题,请参考以下文章

理解javascript原生拖放

h5-拖拽接口

使用 javascript 访问 `draggable` 属性

HTML5拖拽实例

制作一个包含img draggable的div

Html5 拖拽行为和AngularJs的结合