Как программно вызвать перетаскиваемое поведение - PullRequest
6 голосов
/ 10 марта 2011

Я создал «2d слайдер» в jQuery, в котором 2 параметра одновременно обрабатываются путем перетаскивания «маркера» в ограничивающей рамке.

Я реализовал это, вложив div «handle»внутри родительского div и использования плагина jQuery UI для облегчения перетаскивания.HTML выглядит так:

<div class="Slider2d" id="grid_spacing_both">
    <div class="Slider2dHandle" id="grid_spacing_both_handle"></div>
</div>

JQuery выглядит следующим образом:

$(".Slider2dHandle").draggable({
    containment: "parent",
    scroll: false,
    drag: function(event, ui) {
        // calculates position and updates value input boxes
    }
});

Я также создал некоторый код, который перемещает дескриптор в расположение любых кликов в родительском div:

$(".Slider2d").mousedown(function(event){
    // get location of click and reposition handle to click location
});

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

Я нашел несколько предложений здесь и здесь , и попытался реализовать их рекомендации, изменив вышеуказанный метод следующим образом:

$(".Slider2d").mousedown(function(event){
    // get location of click and reposition handle to click location
    handle = $(".Slider2d").children(".Slider2dHandle");
    handle.trigger(event);
});

Это работает в самом техническом смысле, но это очень медленно, и я получаю кучу сообщений об ошибках от Safari, говорящих мне: «RangeError: Превышен максимальный размер стека вызовов».Я думаю, что происходит, когда я запускаю событие на дескрипторе, оно всплывает до родителя, который затем вызывает триггер снова и так далее, и так далее.Я пытался остановить пузыриться, добавив в мой код событие.stopPropagation до и после вызова .trigger (), но безрезультатно.

Итак, если у кого-то есть какие-либо предложения о том, как это получитьработая, я действительно ценю это.У меня есть план резервного копирования здесь , но мне кажется, что это излишне сложно.

Спасибо!

Ответы [ 3 ]

8 голосов
/ 15 марта 2011

Мне удалось заставить это работать.Как я и подозревал, это как-то связано с обработкой событий.

Исправление было простым: я изменил приведенный выше код, чтобы проверить, совпадает ли цель события с элементом, с которым был связан обратный вызовограничитель ползунка).При первоначальном щелчке, который перемещает маркер, это те же самые элементы.Однако, когда срабатывает событие mousedown дескриптора, и событие всплывает до ограничивающей рамки, целью события , которое является дескриптор ползунка.Таким образом, они не совпадают, и событие триггера больше не вызывается, вызывая бесконечный цикл.

По крайней мере, я думаю, что это происходит.В любом случае, вот код, который работал:

$(".Slider2d").mousedown(function(event){
    // get location of click and reposition handle to click location 

    handle = $(".Slider2d").children(".Slider2dHandle");
    if ($(this).attr("id") == $(event.target).attr("id")) {
        handle.trigger(event);
    }
});
1 голос
/ 27 февраля 2013

Или вы можете просто остановить распространение в событии mousedown обработчика, чтобы оно не всплыло до события mousedown ползунка.

$(".Slider2d").mousedown(function(event) {
    // get location of click and reposition handle to click location 

    handle = $(".Slider2d").children(".Slider2dHandle");
    handle.trigger(event);
});

$(".Slider2dHandle").mousedown(function(event) {
    event.stopPropagation();
});
0 голосов
/ 15 марта 2012

Это не работает для меня, поэтому я предполагаю, что я делаю что-то не так.Но мне было интересно, если это работает для вас, почему бы не установить:

if ($(this).attr("id") == $(event.target).attr("id"))

На это:

if (this === event.target)

Я обновлю, как только выясню это.

Все еще ничего: во время этого бесконечного цикла event.target остается в качестве ползунка, а не дескриптора, только тогда фактически запускается второе событие.

EDIT: Понятно, я переключился с jQuery 1.7.1до 1.6.4 и все работает.

...