Подтвердить что ты не робот

Изменение курсора мыши для HTML5 Перетащите файлы (GMail Drag Drop)

Я пытаюсь воспроизвести, как GMail обрабатывает вложения html5 drag/drop - где, как только вы перетаскиваете файлы по странице, он отображает новый элемент для вас. Я разработал эту часть (это было не так прямо, как я думал, это будет).

Теперь я пытаюсь отполировать его, изменяя курсор мыши, когда мышь находится над любым другим элементом, отличным от элемента drop, чтобы сообщить пользователю о сбросе. Я предполагаю, что могу сделать это с помощью пользовательского курсора, но, похоже, это не то, что делает GMail. Спецификация предложила бы также изменить курсор мыши, но я не могу заставить его работать правильно, используя dropzone/effectAllowed.

Любая помощь будет оценена, здесь моя текущая настройка: http://jsfiddle.net/guYWx/1/

ETA: Вот что я закончил: http://jsfiddle.net/guYWx/16/

<body style="border: 1px solid black;">
    <div id="d0" style="border: 1px solid black;">drag files onto this page</div>
    <div id="d1" style="border: 1px solid black; display: none; background-color: red;">-&gt; drop here &lt;-</div>
    <div id="d2" style="border: 1px solid black;">and stuff will happen</div>
    <div style="float: left;">mouse them all over&nbsp;</div>
    <div style="float: left;">these elements</div>
    <br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/>
    <div>end page</div>
</body>
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.4.2/jquery.min.js"></script>
<script type="text/javascript">
    var resetTimer;

    var reset = function()
    {
        $('#d1').hide();
    };

    var f = function(e)
    {
        var srcElement = e.srcElement? e.srcElement : e.target;

        if ($.inArray('Files', e.dataTransfer.types) > -1)
        {
            e.stopPropagation();
            e.preventDefault();

            e.dataTransfer.dropEffect = (srcElement.id == 'd1') ? 'copy' : 'none';

            if (e.type == "dragover")
            {
                if (resetTimer)
                {
                    clearTimeout(resetTimer);
                }
                $('#d1').show();
                console.info('dropped on <' + srcElement.tagName.toLowerCase() + ' id="' + srcElement.id + '">\n\ne.dataTransfer.types is ' + e.dataTransfer.types + '\n\ne.dataTransfer.files.length is ' + e.dataTransfer.files.length);

            }
            else if (e.type == "dragleave")
            {
                resetTimer = window.setTimeout(reset, 25);
            }
            else if (e.type == "drop")
            {
                reset();
                alert('dropped on <' + srcElement.tagName.toLowerCase() + ' id="' + srcElement.id + '">\n\ne.dataTransfer.files.length is ' + (e.dataTransfer.files ? e.dataTransfer.files.length : 0));
            }
        }
    };

    document.body.addEventListener("dragleave", f, false);
    document.body.addEventListener("dragover", f, false);
    document.body.addEventListener("drop", f, false);
</script>
4b9b3361

Ответ 1

Произошел какой-то рывок через источник и обнаружил, что вы должны установить event.dataTransfer.dropEffect = 'move'; внутри вашего обработчика событий dragover. Googled для dropEffect, чтобы узнать больше и нашел:

dataTransfer.dropEffect

Управляет обратной связью, которую пользователь дает во время перетаскивания и события перетаскивания. Когда пользователь наводится над целевым элементом, курсор браузера укажет, какой тип операции будет принимать место (например, копия, перемещение и т.д.). Эффект может принимать один из следующие значения: none, copy, link, move.

from: http://www.html5rocks.com/en/tutorials/dnd/basics/

Изменить: вот что я закончил: http://jsfiddle.net/guYWx/16/

Пришлось сделать еще один трюк, чтобы заставить его работать отлично. Сделал ли это так, что капельница не появится, когда вы выберете текст и перетащите его по странице:

if ($.inArray('Files', e.dataTransfer.types) > -1)

Ответ 2

@Langdon - Спасибо, что указали именно то, что мне нужно! Я поддержал это.

Проведя так много часов, я получил это предложение, работающее точно так, как предполагалось.

Я использовал effectAllowed в сочетании с dropEffect, чтобы обеспечить визуальные подсказки при выполнении операций перетаскивания. Полностью перекрестный браузер!

$(document).on('dragstart dragenter dragover', function(event) {    
    // Only file drag-n-drops allowed, http://jsfiddle.net/guYWx/16/
    if ($.inArray('Files', event.originalEvent.dataTransfer.types) > -1) {
        // Needed to allow effectAllowed, dropEffect to take effect
        event.stopPropagation();
        // Needed to allow effectAllowed, dropEffect to take effect
        event.preventDefault();

        $('.dropzone').addClass('dropzone-hilight').show();     // Hilight the drop zone
        dropZoneVisible= true;

        // http://www.html5rocks.com/en/tutorials/dnd/basics/
        // http://api.jquery.com/category/events/event-object/
        event.originalEvent.dataTransfer.effectAllowed= 'none';
        event.originalEvent.dataTransfer.dropEffect= 'none';

         // .dropzone .message
        if($(event.target).hasClass('dropzone') || $(event.target).hasClass('message')) {
            event.originalEvent.dataTransfer.effectAllowed= 'copyMove';
            event.originalEvent.dataTransfer.dropEffect= 'move';
        } 
    }
}).on('drop dragleave dragend', function (event) {  
    dropZoneVisible= false;

    clearTimeout(dropZoneTimer);
    dropZoneTimer= setTimeout( function(){
        if( !dropZoneVisible ) {
            $('.dropzone').hide().removeClass('dropzone-hilight'); 
        }
    }, dropZoneHideDelay); // dropZoneHideDelay= 70, but anything above 50 is better
});

Ответ 3

Вам нужно изменить свойство cursor CSS.

Здесь вы найдете список различных значений cursor здесь.

Вы также можете указать собственное изображение курсора с помощью cursor: url('foo.png');.