【问题标题】:implementing html5 drag and drop photos with knockout js , durandal 2.0用淘汰赛js实现html5拖放照片,durandal 2.0
【发布时间】:2014-07-25 21:55:52
【问题描述】:

我有一个淘汰赛 js 视图模型中的照片列表,我希望能够在它们之间交换(实际上更正确的术语是在另一个之上复制一个)。 这是我的简化视图模型:

define(['durandal/app', 'knockout', 'jquery'], function(app, ko, jquery) {
    var miscPhotos = ko.observableArray();
    var draggedPhoto = ko.observable();

    function handleDragStart(data, e) {
        // e.preventDefault();
        draggedPhoto(data);
        console.log('dragStart');
        return true;
    }

    function handleDragOver(e) {
        e.preventDefault();
        console.log('dragOver');

    }

    function handleDrop(e) {
        e.preventDefault();
        e.stopPropagation();
        console.log('drop');

    }

    return {
        miscPhotos: miscPhotos,
        handleDrop: handleDrop,
        handleDragOver: handleDragOver,
        handleDragStart: handleDragStart
    }

});

还有简化的用户界面:

<div id="holder" data-bind="foreach: miscPhotos">
    <div class="pull-left well well-small"  draggable="true" 
        data-bind="event:{
                dragstart: function(data, e){ $root.handleDragStart($data, e);},
                dragover:function(data, e){ $root.handleDragOver( e);},
                drop:function(data, e){ $root.handleDrop(e, $data);}}
     ">
    <div class="thumb">
        <img class="thumb" 
            title="" style="display: block" 
            data-bind="attr: {src: 'data:image;base64,' + PhotoData()}"
        />
    </div>  
</div>

当我尝试将一张照片复制到另一张照片上时,只会触发 dragstart 事件,不会触发 dragover 和 drop。

【问题讨论】:

  • 您是否尝试过在handleDragOver 和handleDrop 中添加'return true'?

标签: html knockout.js durandal-2.0


【解决方案1】:

解决方案:

您需要将 return true 添加到您的 dragstart 定义中:

dragstart:   function(data, e){ $root.handleDragStart($data, e); return true;},

更多信息:

dragover 没有被触发,因为 Knockout 阻止了 dragstart 的默认操作,如果没有默认操作,就不会从 dragstart 过渡到 dragover。

我认为您尝试通过在此处添加“return true”来启用默认操作:

function handleDragStart(data, e) {
   // e.preventDefault();
    draggedPhoto(data);
    console.log('dragStart');
    return true;   
}

但是,由于您绑定事件的方式,您需要做的(这是最快的解决方法)是将“return true”移动到绑定中的内联函数中:

dragstart:   function(data, e){ $root.handleDragStart($data, e); return true;},

我认为这将为您解决问题。但是,如果你愿意,你可以稍微简化你的代码。您没有从事件绑定中的内联函数传递任何额外的参数,因此您实际上不需要内联函数。您可以按原样提供视图模型函数:

   dragstart: $root.handleDragStart,
   dragover:  $root.handleDragOver,
   drop:      $root.handleDrop

为了使其正常工作,您需要更改处理程序函数签名以使用(数据,事件)的 Knockout 约定:

 handleDragStart(data, e)
 ...
 handleDragOver(data, e)
 ...
 handleDrop(data, e)

我做了一个小提琴来测试这个......我不得不稍微重写你的视图模型,我跳过了依赖语句只是因为没有它做小提琴会更容易一些。但是代码与您的代码基本相同,因此希望您能够正常阅读。我还在视图模型中添加了一些测试数据 URL,因此有一个工作演示。

http://jsfiddle.net/NLvm7/

当我在那里时,我还继续展示了如何在 handleDrop 函数中将数据从被拖到的照片中写入到您放置它的照片中,从而实现将一张照片复制到另一张照片的目标:

    // The next 3 lines shows how you can copy the dragged photo onto the dropped target...
    var context = ko.contextFor(e.target);
    var index = context.$index();
    this.miscPhotos()[index].PhotoData(this.draggedPhoto().PhotoData());

【讨论】:

    猜你喜欢
    • 2013-04-09
    • 2014-08-21
    • 2013-08-30
    • 2017-11-03
    • 2014-04-11
    • 1970-01-01
    • 2018-03-30
    • 2013-02-21
    • 2014-08-01
    相关资源
    最近更新 更多