Зависимости форма, медленный JavaScript


Я начал работать на jQuery и порт для этой формы зависимости Диспетчере скриптов. Он отлично работает, и я добавила еще несколько вариантов тоже.

Проблема в скорости. Если вы создаете зависимостей между 20+ форма элементы на странице, вы получаете компьютер работать очень медленно. Firefox-это выбрасывание, что "сценарий является слишком медленным" сообщение. Это, наверное, из-за тяжелых для петель.

У вас есть какие-либо предложения о том, как можно было бы улучшить, или, может быть, новые идеи о том, как реализовать такую функциональность?

(function($){
$.fn.setupDependencies = function(options){

  var defaults = {
        attribute              : 'rules',           // the field attribute which contains the rules (use 'rel' for w3c valid code)
        disable_only           : true,              // if true it will disable fields + label, otherwise it will also hide them
        clear_inactive         : false,             // clears input values from hidden/disabled fields
        identify_by            : 'name',            // attribute used to identify dependencies (ie. DEPENDS ON [identify_by] BEING ...)

        condition_separator    : ' AND ',           // rules...
        possibility_separator  : ' OR ',
        name_value_separator   : ' BEING ',
        depends                : 'DEPENDS ON ',
        conflicts              : 'CONFLICTS WITH ',
        empty                  : 'EMPTY'
      },

      settings = $.extend({}, defaults, options),
      matches = this,

      valueMatches = function(e, v){
        return (e.val() == v || (e.is(':radio') && e.filter(':checked').val() == v));
      },

      // show or enable
      show = function(e){
        $('label[for="' + e.attr('id') + '"]').removeClass('disabled');
        e.removeAttr('disabled');
        if(!settings.disable_only){
          e.show();
          $('label[for="' + e.attr('id') + '"]').show();
        }
        return true;
      },

      // hide or disable
      hide = function(e){
        $('label[for="' + e.attr('id') + '"]').addClass('disabled');
        e.attr('disabled', 'disabled');
        if(!settings.disable_only){
          e.hide();
          $('label[for="' + e.attr('id') + '"]').hide();
        }
        if(settings.clear_inactive == true && !e.is(':submit')) // ignore submit buttons
          if(e.is(':checkbox,:radio')) e.removeAttr('checked'); else e.val('');
        return true;
      };


  return this.bind('change input', function(){  // note: input event not working in IE <= 8, obviously
    var j, k, f, n, isHidden, dep;

    matches.each(function(){

      isHidden = false;
      dep = $(this).attr(settings.attribute);

      if(typeof dep !== 'undefined' && dep !== false)
        for(j = 0, f = dep.split(settings.condition_separator); j < f.length; ++j)
          if(f[j].indexOf(settings.depends) === 0){
            for(k = 0, g = f[j].substr(settings.depends.length).split(settings.possibility_separator); k < g.length; ++k)
              if(g[k].indexOf(settings.name_value_separator) === -1){
                if(matches.filter('[' + settings.identify_by + '="' + g[k] + '"]').is(':checked')) break; else if(k + 1 == g.length) isHidden = hide($(this));

              }else{
                n = g[k].split(settings.name_value_separator);
                if(valueMatches(matches.filter('[' + settings.identify_by+'="' + n[0] + '"]'), n[1])) break; else if(k + 1 == g.length) isHidden = hide($(this));
              }
          }else if(f[j].indexOf(settings.conflicts) === 0){
            if(f[j].indexOf(settings.name_value_separator) === -1){
              if(matches.filter('[' + settings.identify_by + '="' + f[j].substr(settings.conflicts.length) + '"]').is(':checked')){
                isHidden = hide($(this));
                break;
              }
            }else{
              n = f[j].substr(settings.conflicts.length).split(settings.name_value_separator);
              if(valueMatches(matches.filter('[' + settings.identify_by + '="' + n[0] + '"]'), n[1])){
                isHidden = hide($(this));
                break;
              }
            }
          };

      if(!isHidden) show($(this));

    });

    return true;
  }).change();       

};

})(jQuery);

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



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

Все точки ниже я начал писать, глядя на код для выполнения проблему, но не связанные с ним. Честно говоря, после первого чтения я не могу понять, как можно было бы сделать по-другому, чтобы быть быстрее. Один, вероятно, придется сделать некоторые правильного профилирования.

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

Думая об этом, другим решением будет использовать совершенно другой подход и избежать парсинга. Вместо того, чтобы назначать правила через строку в собственность, можно создать методы в jQuery. Что-то вроде: $("#some_form_element").зависит("[имя='mycheckbox']");

Теперь представление несвязанных моментов:


  • Основной блок кода очень трудно читать из-за вложенности еслис и наЫ. Это поможет разделить ее на несколько дополнительных подпрограмм, особенно как полагают, чтобы увидеть некоторые дублирования кода.

  • Кроме того, одна буква переменных делает чтение кода немного сложнее, слишком.

  • Установка пользовательских свойств на дом объекты (isHidden) обычно не рекомендуется - вот почему у тебя были проблемы, как его называли скрытым. Почему ты здесь вообще? Это не кажется, что вы все равно используете значение вне цикла, поэтому простой переменной будет достаточно.

  • если(typeof на деп !== "значение undefined" && отд !== ложные) могут быть упрощены, чтобы если (ДЭП).

  • Я бы посадила по умолчанию объект и все "частные" методы основная функция

  • Реальные придираться: у вас есть лишние точки с запятой после блока заявления

1
ответ дан 23 июня 2011 в 11:06 Источник Поделиться

Я просто отвечал на подобный комментарий код запроса: плагин, который условно отображает элементы, основанные на форме значения .

Я думаю, что мы решаем здесь тот же вопрос. Я желаю, чтобы мы могли слить дискуссию, чтобы найти лучшее решение, но по крайней мере мы можем использовать этот замечательный форум, чтобы понять ваши идеи друг друга. :)

Похоже, вы взяли строку подхода к проблеме. В то время как я взял на себя функции подхода.

У меня нет никаких скоростные ориентиры, но я буду выполнять те в понедельник и можете поделиться ими тут.

У вас есть пример того, как продлить это новое правило? Легко ли это?

1
ответ дан 24 июня 2011 в 10:06 Источник Поделиться