implementing html5 drag and drop photos with knockout js , durandal 2.0

最后都变了- 提交于 2019-12-13 14:49:07

问题


I have a list of photos in a knockout js viewmodel and I want to be able to swap among them(actually the more correct term is copy one on top of another). Here is my simplified viewmodel:

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
    }

});

And there goes the simplified UI also:

<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>

When I try to copy one photo on top of the other, only the dragstart event fires, dragover and drop won't fire.


回答1:


Solution:

You need to add return true to your dragstart definition:

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

More info:

dragover isn't being fired, because Knockout is preventing the default action of dragstart, and without the default action there won't be a transition from dragstart into dragover.

I think you tried to enable the default action, by adding 'return true' here:

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

However, because of the way you have bound your events, what you need to do (and this is the quickest possible fix) is move the 'return true' into your inline function in the binding:

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

I think that will fix it for you. But, if you like, you can simplify your code a bit. You're not passing any extra parameters from your inline functions in the event binding, so you don't actually need the inline function. You can just supply your view-model functions as they are:

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

In order for this to work, you need to change your handler function signature to work with the Knockout convention of (data, event):

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

I made a fiddle to test this... I had to rewrite your view-model a bit, I skipped the depend statement just because it is a bit easier to do a fiddle without it. But the code is basically the same as yours, so hopefully you'll be able to read it OK. I also added some test data URLs to the view-model so there's a working demo.

http://jsfiddle.net/NLvm7/

While I was there, I've also gone on to show how in the handleDrop function you could write the data from the photo being dragged into the photo you dropped it on, and so achieve your goal of copying one photo onto another:

    // 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());


来源:https://stackoverflow.com/questions/24791721/implementing-html5-drag-and-drop-photos-with-knockout-js-durandal-2-0

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!