Вопрос по html5, drag-and-drop – Изменение курсора мыши для файлов перетаскивания HTML5 (GMail Drag Drop)

14

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

Теперь я пытаюсь исправить ситуацию, изменив курсор мыши, когда мышь находится над любым другим элементом, кроме элемента 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>
Привет, я боролся с этим сам в течение нескольких часов. Ваш код работает намного лучше, чем мой. Можете ли вы объяснить, для чего служит задержка времени сброса? benb
Это предотвращает ложные срабатывания для события Dragleave. Когда вы привязываете dragover / dragleave к элементу с кучей подэлементов, события будут срабатывать, когда вы переходите от подэлемента к подэлементу. Я заменил время ожидания звонкомreset, так что вы можете видеть, насколько это плохо, когда вы перетаскиваетеjsfiddle.net/guYWx/20 (много скрытия / показа в Chrome). Langdon

Ваш Ответ

3   ответа
-3

cursor CSS свойство

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

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

Я знаю, что могу изменить курсор, но GMail этого не делает. Существует огромная разница между курсором: без выпадения и тем, как выглядит курсор в GMail. Langdon
4

что указали именно то, что мне нужно! Я проголосовал за это.

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

Я использовал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
});
26

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

dataTransfer.dropEffect

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

из:http://www.html5rocks.com/en/tutorials/dnd/basics/

Редактировать: вот что я закончил с:http://jsfiddle.net/guYWx/16/

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

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

Похожие вопросы