Pregunta

I am trying to use .bind() with 'dragenter', 'dragover', and 'drop' so I can drag a file from my desktop to my browser.

Please see attached jsfiddle. http://jsfiddle.net/v82An/23/

$(function(){
    function dragenter(e) {
        e.stopPropagation();
        e.preventDefault();
    }
    function dragover(e) {
        e.stopPropagation();
        e.preventDefault();
    }    
    function drop(e) {
        e.stopPropagation();
        e.preventDefault();        
        alert('hi')
    }

    $('#drop').bind('dragenter', dragenter, false);
    $('#drop').bind('dragover', dragover, false);
    $('#drop').bind('drop', drop, false);    
});

This fiddle attaches these events properly in 1.5, but in 1.6 they simply don't work.

Anyone know if I'm just doing it wrong?

¿Fue útil?

Solución

It seems to work if you don't set preventBubble to false:

$('#drop').bind('dragenter', dragenter);
$('#drop').bind('dragover', dragover);
$('#drop').bind('drop', drop);   

DEMO

Update: If you look at the documentation, passing three parameters where the last one is a boolean, is interpreted as:

.bind( eventType, [eventData], preventBubble )

which means that the handler is not used as event handler but as event data.

They changed how they detect the handler though. In jQuery 1.5.2, it was:

if ( jQuery.isFunction( data ) || data === false ) {
    fn = data;
    data = undefined;
}

You see, when the second argument was a function, then this one was used as event handler (instead of the third one).

But it was changed in jQuery 1.6.2 to:

if ( arguments.length === 2 || data === false ) {
    fn = data;
    data = undefined;
}

Now it is only tested how many arguments are passed. As, in your case, data is not false (it is a function) and you pass three arguments, fn is not changed. It stays false.

When the handler is false, then this happens:

if ( handler === false ) {
    handler = returnFalse;
} else if ( !handler ) {
    // Fixes bug #7229. Fix recommended by jdalton
    return;
}

So this could actually be seen as bug in jQuery 1.5 which is now fixed and is not a problem with these particular events.

Otros consejos

I found that my issue lied with jQuery glorifying the original event object during the bind process.

My code looked like this:

$dropArea = $(".dropArea");
$dropArea.bind({
    dragover: function (ev) {
        $(this).addClass('hover');
        ev.preventDefault();
        return false;
    },
    dragend: function () {
        $(this).removeClass('hover');
        return false;
    },
    dragleave: function () {
        $(this).removeClass('hover');
        return false;
    },
    drop: function (ev) {
        ev.preventDefault();
        //e = e || window.event;
        var data = ev.dataTransfer.getData("text/html");
        ev.target.appendChild(document.getElementById(data));

        console.log("dropping element.");
        return false;
    });

jQuery was wrapping the old event object up into a newer more glorified jQuery version of the event object.

I added this line:

ev = ev.originalEvent; 

to get the original event object back, upon which I could call the preventDefault(), and all worked well once again.

I hope this helps save someone time! (Still wrapping my head around the jQuery objects and functions associated with them, as they relate back to the original javascript objects).

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top