it-swarm.com.ru

jQuery drag and drop - проверка на наличие выпадающего списка

Мои извинения, если на этот вопрос был дан ответ в другом вопросе, я не смог найти ответ, относящийся к моей проблеме!

Я пытаюсь проверить, отбрасывается ли jQuery-перетаскиваемый объект за пределы допустимого. Обычно это решается в 90% случаев путем возврата перетаскиваемого объекта, но я не хочу этого делать. Вместо этого я хочу сделать одну вещь, если перетаскиваемый объект помещен на предмет сброса (работает отлично!), И что-то еще, если его отбрасывают за пределы всех возможных предметов сбрасывания (в настоящее время меня одолевают!).

В двух словах:

jQuery('#droppable').droppable(
{
    accept: '#draggable',
    drop: function(event, ui)
    {
        // awesome code that works and handles successful drops...
    }
});

jQuery('#draggable').draggable(
{
    revert: false,
    stop: function()
    {
        // need some way to check to see if this draggable has been dropped
        // successfully or not on an appropriate droppable...
        // I wish I could comment out my headache here like this too...
    }
});

Я чувствую, что упускаю что-то действительно очевидное ... заранее спасибо за любую помощь!

36
Chris Kempen

Поскольку событие drop для dropppable срабатывает перед событием stop draggable, я думаю, вы можете установить флаг для перетаскиваемого элемента в событии drop следующим образом:

jQuery('#droppable').droppable(
{
    accept: '#draggable',
    drop: function(event, ui)
    {
        ui.helper.data('dropped', true);
        // awesome code that works and handles successful drops...
    }
});

jQuery('#draggable').draggable(
{
    revert: false,
    start: function(event, ui) {
        ui.helper.data('dropped', false);
    },
    stop: function(event, ui)
    {
        alert('stop: dropped=' + ui.helper.data('dropped'));
        // Check value of ui.helper.data('dropped') and handle accordingly...
    }
});
53
Luke Girvin

Я вижу, что вы уже получили ответ; В любом случае, сегодня у меня была такая же проблема, и я решил ее так:

var outside = 0;

// this one control if the draggable is outside the droppable area
$('#droppable').droppable({
    accept      : '.draggable',
    out         : function(){
        outside = 1;
    },
    over        : function(){
        outside = 0;
    }
});

// this one control if the draggable is dropped
$('body').droppable({
    accept      : '.draggable',
    drop        : function(event, ui){
        if(outside == 1){
            alert('Dropped outside!');
        }else{
            alert('Dropped inside!');
        }
    }
});

Мне это было нужно, потому что я не мог изменить параметры моих перетаскиваемых объектов, поэтому мне приходилось работать только с дескрипторами (мне это нужно было внутри удивительного FullCalendar plugin) . Я полагаю, что при использовании «жадный» вариант с каплями, но он должен работать в большинстве случаев.

PS: извините за мой плохой английский.

EDIT: Как и предполагалось, я создал версию, используя jQuery.data; это можно найти здесь: jsfiddle.net/Polmonite/WZma9/

В любом случае, документация jQuery.data гласит:

Обратите внимание, что этот метод в настоящее время не обеспечивает кроссплатформенную поддержку для настройки данных в документах XML, поскольку Internet Explorer не позволяет прикреплять данные через свойства expando.

(это означает, что он не работает на IE до 8)

EDIT 2: Как отметил @Darin Peterson, предыдущий код не работает с несколькими областями размещения; это должно решить эту проблему: http://jsfiddle.net/Polmonite/XJCmM/

EDIT 3: Пример из EDIT 2 содержит ошибку. Если я перетащить "Перетащите меня!" в нижнюю часть, затем перетащите «Перетащите меня тоже» в верхнюю часть и затем опустите «Перетащите меня тоже» снаружи, появится предупреждение «Упал внутри!» Так что не используйте его.

EDIT 4: Как отметил @Aleksey Gor, пример в Edit 2 был неверным; на самом деле, это был скорее пример, объясняющий, как перебрать все draggables/droppables, но я на самом деле забыл удалить предупреждающие сообщения, так что это было довольно странно. Здесь обновленная скрипка.

9
Polmonite

Попробуйте использовать событие "out" элемента droppable.

Это документация

«Это событие вызывается, когда принятый перетаскиваемый объект перетаскивается (в пределах допуска) на этот сбрасываемый объект.» Если я прав, это то, что вам нужно.

Также возможно создать элемент наложения на всю страницу. Если элемент упал там, вы запускаете ваше событие. Не самый лучший, но я думаю, что единственный способ сделать это. Потому что вам нужен какой-то другой «сбрасываемый» предмет для запуска этих событий.

4
ggzone

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

Свойство перетаскиваемого возврата может иметь функцию (значение) {}. В качестве аргумента передается значение, указывающее, был ли хелпер удален на элемент (элемент drop), или 'false', если не был удален на элемент (исключен или не принят). 

Примечание: вам нужно вернуть правильное значение bool из этого функция возврата, чтобы указать помощнику, возвращаться или нет (Истина/ложь). Истина означает да, верните помощника обратно в исходное состояние положение, перемещая его обратно в медленном движении (из коробки). Ложь означает нет, просто .__ удалите помощника внезапно. Установка свойства revert в 'invalid', это ярлык 

  • «да, если выпадет на улицу, то отменить помощник»
  • «нет, если упал на элемент, который можно сбрасывать и принял, а затем убить помощника».

Я предполагаю, что вы можете добавить текущий помощник пользовательского интерфейса в перетаскиваемый контейнер со свойством data во время события start. Затем выберите его в функции возврата из свойства данных. Затем добавьте свойство к помощнику, указав, было ли оно удалено или нет. Затем в конечном итоге в событии stop проверьте значение этого свойства данных и сделайте то, что вы хотели.

Порядок вызовов событий/функций для перетаскиваемых: Start-revert-stop

Это может быть примером:

jQuery('#draggable').draggable(
{
    start: function(event, ui) {
        $(this).data('uihelper', ui.helper);
    },
    revert: function(value){
        var uiHelper = (this).data('uihelper');
        uiHelper.data('dropped', value !== false);
        if(value === false){
             return true;
        }
        return false;
    },
    stop: function(event, ui)
    {
        if(ui.helper.data('dropped') === true){
            // handle accordingly...
        }
    }
});

Вы даже можете вернуть true в функцию revert и просто удалить помощник во время события stop, в зависимости от значения данных («drop») с помощью ui.helper.remove (). Или вы можете даже взорвать его с помощью CSS3, если у вас все еще плохой день;)

1
Bogmag

Я добавляю решение, которое я принял, поскольку вы можете легко понять это по классам css объекта, который вы перемещаете:

jQuery('#draggable').draggable({
  stop: function(event, ui) {
    if (ui.helper.hasClass('ui-draggable-dragging')) {
      console.log('dropped out');
    } else {
      console.log('dropped successfully');
    }
  }
});
0
coorasse