2017-02-13 12 views
2

У меня есть визуализация D3 (v4) с множеством форм, которые в некоторых случаях ожидают новые позиции в течение примерно трех секунд. У этих фигур есть прослушиватели событий щелчка и мыши, которые я хочу быть активными только тогда, когда виз не перемещается.События короткого замыкания в d3?

Наивный способ сделать это прост. У меня есть булева переменная is_animating, которая устанавливается на true, когда анимация начинается и false на обратный вызов, так что я просто добавил это к слушателям событий:

shapes.on("click", function(d) { 
    if (is_animating) { 
    return; 
    } 
    // otherwise, business as usual 
}) 

Это хорошо, но я планирую добавить много слушатели событий в форме и хотели бы, если бы был более элегантный способ перехватить события выше в пузырьках и просто сделать это один раз вместо того, чтобы добавлять эту проверку к каждому событию. Но я не совсем понимаю d3.event и как он справляется с пузырями. Есть ли простое «masterene listenever», если вы это сделаете, что бы стрелять в любое время, когда пользователь пытается что-то сделать, что может привести к короткому замыканию события, если is_animating верно?

ответ

3

В API-интерфейсах D3-переходов есть способ управления наличием каких-либо активных переходов, связанных с данным узлом (d3.active).

Вы можете использовать его для обнаружения активных переходов на узле без введения дополнительной переменной.

shapes.on("click", function(d) { 
    if (d3.active(this)) { 
    return; 
    } 
    // otherwise, business as usual 
}) 
+0

Спасибо, приятно знать! Это все равно означало бы делать проверку вместо каждого слушателя, но очень полезную информацию. –

0

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

shapes 
    .transition() 
    .attr(...) // apply new positions, styles, etc 
    .on('end', function() { 
    // called per element once its transition has completed 
    d3.select(this) 
     .on('click', function() { /* business as usual */ }) 
    }) 

Другой полезный бит, который может вступить в игру для вас заключается в том, что вам необязательно регистрировать прослушиватели событий по выбору shapes, что дает несколько слушателей. Вместо этого вы можете подписаться на события своего родителя. Если родитель были Г в выборе d3, это будет выглядеть следующим образом

svg // assumes svg is a d3 selection containing every shape 
    .on('click', function() { 
    // to get the clicked element 
    d3.select(d3.event.target) 
     .attr(...) 

    // or, if you just want d, the datum of the shape 
    // that was clicked: 
    var d = select(d3.event.target).datum() 
    }) 

Я не думаю, что есть способ, чтобы предотвратить образование пузырьков, как вы описали. Я не знаю почему; Я ожидаю, что это сработает, но мое тестирование не получилось. Следует отметить, что даже если вы смогли остановить распространение, это будет распространение от ребенка к родительскому, а не к ребенку.

+0

Обе хорошие идеи! Я согласен с тем, что кажется, что должно быть пузырящее решение, но я не могу заставить его работать - и хороший момент в отношении направления. Может быть, решение заключается в перехвате во время фазы _capturing_? –