JavaScript закрытие: код мелочи, чтобы сохранить обработчик события отдельно


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

В моих усилий, чтобы Выучить JS на фоне СВГ развития, я получил много помощи от так до сих пор. Ответ на предыдущий запрос был лучшим, чтобы понять, закрытия; его использованию и предостережения в очень короткое время. Продолжая эту же линию, я пытался пробоя ниже функция, так что это более читабельным и легким для расширения. Это было частью ответа @Phrogz. Я не мог придумать способ удержать человека закрытие вне цикла.

Если кто-то может помочь мне с псевдо код/скелет как это может быть сделано без слишком много переменных, чтобы сохранить государство (как кнопки кнопку состояние во время движения и т. д.), Это позволит прояснить многие мои сомнения относительно того, как закрытие может быть назначен и т. д. Вам также может нарушить функцию в 3 обработчики событий (событие mousedown, mousemove и mouseup с). Я не мог придумать способ сделать это, сохраняя при этом контекст (событие mousemove срабатывает только когда кнопка мыши нажата, как это в рамках закрытия).

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

for (var a=svg.querySelectorAll('.drag'),i=0,len=a.length;i<len;++i){
        (function(el){
            var onmove; // make inner closure available for unregistration
            el.addEventListener('mousedown',function(e){
                el.parentNode.appendChild(el); // move to top
                var x = el.tagName=='circle' ? 'cx' : 'x';
                var y = el.tagName=='circle' ? 'cy' : 'y';
                var mouseStart   = cursorPoint(e);
                var elementStart = { x:el[x].animVal.value, y:el[y].animVal.value };
                onmove = function(e){
                    var current = cursorPoint(e);
                    pt.x = current.x - mouseStart.x;
                    pt.y = current.y - mouseStart.y;
                    console.log("pt.x:" + pt.x + "pt.y:" + pt.y);
                    var m = el.getTransformToElement(svg).inverse();
                    m.e = m.f = 0;
                    pt = pt.matrixTransform(m);
                    el.setAttribute(x,elementStart.x+pt.x);
                    el.setAttribute(y,elementStart.y+pt.y);
                    var dragEvent = document.createEvent("Event");
                    dragEvent.initEvent("dragged", true, true);
                    el.dispatchEvent(dragEvent);
                };
                document.body.addEventListener('mousemove',onmove,false);
            },false);
            document.body.addEventListener('mouseup',function(){
                document.body.removeEventListener('mousemove',onmove,false);
            },false);
        })(a[i]);
    }


Комментарии
2 ответа


  1. Добавить больше пространства.

  2. Использовать несколько именованных функций. (обернуть все это в обертку аноним, если тебя волнует конфликты пространства имен).

  3. Когда вы используете например, лямбды дают им имена (это делает код легче читать, и вы не получите отображаются в журнале ошибок.

  4. Объявлять переменные в высшие функции, чтобы воспользоваться замыканиями. например, Х, Y, elementStart и mouseStart.

  5. верблюжьего.

  6. Использовать ===, если вы явно хотите заставить литья.

  7. Не заставляй функции в цикле.

http://codr.cc/s/03c0d0af/js

2
ответ дан 7 мая 2011 в 05:05 Источник Поделиться

Функция в цикле вещь:

function innerStuff(el) {
var onmove; // make inner closure available for unregistration
el.addEventListener('mousedown',function(e){
// ... etc etc
}
}

for (var a=svg.querySelectorAll('.drag'),i=0,len=a.length;i<len;++i){
innerStuff(a[i]);
}

Это будет означать, что переменные внутри innerStuff() функция, и вы не создаете новую функцию каждый раз. (не использовать это имя ... сделать свой собственный описательный.)

0
ответ дан 21 ноября 2013 в 05:11 Источник Поделиться