$.bind () для элементов SVG прерывается, когда новый SVG заменяет исходный

#javascript #jquery #xml #ajax #svg

#javascript #jquery #xml #ajax #svg

Вопрос:

У меня есть svg с элементами, которые я привязываю к щелчкам и вводам клавиш. Если пользователь редактирует текстовое поле на странице, он обновляет соответствующий текстовый элемент в svg. И наоборот, если пользователь редактирует svg, он обновляет соответствующее текстовое поле в html. С помощью jQuery.

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

После загрузки этого второго svg привязки перестают работать. Я повторно инициализирую все — отменяю привязку и переназначаю — вызывая AB.init () ниже, но пользователь все равно не может редактировать svg. Как мне это исправить?

ОБНОВЛЕНИЕ: все .bind () теперь являются .delegate() согласно комментарию @Pointy. Однако проблема сохраняется. Допустим ли мой синтаксис .delegate() для пространства имен?

 AB = {
  svgns: "http://www.w3.org/2000/svg"

  f: {
      field1: {svg:null, jq:null},
      field2: {svg:null, jq:null}
  },

  /* last activated text field */       
  active:   undefined,

  init: function() {
    AB.f.field1.jq = $('#id_field_1');
    AB.f.field2.jq = $('#id_field_2');
    var svg_container = document.getElementById('svg_container');
    var svg_text_elements = svg_container.getElementsByTagNameNS(svgns, 'text');
    var length = svg_text_elements.length;
    for(var i=0; i < length; i  ) {
      var e = svg_text_elements[i];
      if(e.id) {
        AB.set_svg_for_text_field(e);
      } else {
        var tspans = e.getElementsByTagName('tspan');
        for(var j = 0; j < tspans.length; j  ) {
          var t = tspans[j];
          AB.set_svg_for_text_field(t);
        }
      }
    }
    AB.delegate_and_display_text_fields();
  },

  delegate_and_display_text_fields: function() {
    a = [];
    $.each(AB.f, function(key, value) {
      if(value.svg amp;amp; value.jq){
        $('form').delegate('input', 'keyup click', function() {
          value.svg.textContent = value.jq.val();
          CB.set_active_element(key);
          CB.active = value;
        });
        $('#svg_container svg').delegate('text', 'keyup click', function() {
          value.svg.textContent = value.jq.val();
          CB.set_active_element(key);
          CB.active = value;
        });
        if(value.jq.val()) {
          value.svg.textContent = value.jq.val();
        }
        a.push(value);
        value.jq.parent().fadeIn();
      }
    });
  },
  set_svg_for_text_field: function(e) {
    switch(e.id) {
      case "field_1":
      AB.f.field1.svg = e;
      break;
      case "field_2":
      AB.f.field2.svg = e;
      break;
}
  },
  ...
  

Комментарии:

1. Где код, который на самом деле выполняет привязку?

2. В любом случае, просто найдите метод jQuery «.delegate()» и используйте его для привязки ваших обработчиков событий.

3. @Pointy Я добавил код, который выполняет привязку. Теперь посмотрим на .delegate() …

4. Поскольку вы изменяете элемент (удаляете его и добавляете повторно), в тот момент, когда вы его удалили, привязки перестают работать. Вы пытались обойти проблему, перепривязав все, но поскольку нет кода, который говорит нам, как вы это сделали, я предполагаю, что селекторы не совпадают. Кроме того, для этих целей вам следует использовать jquer’s .live() вместо .bind() .

5. @Pointy или @Michael J.V., я использую «.delegate()» сейчас, но селектор не захватывает пространство имен svn. Идеи?

Ответ №1:

Попробуйте .live()

Он будет привязывать события к элементам, которые соответствуют селектору сейчас и в будущем. У меня были похожие проблемы при динамическом скрытии и отображении элементов. jQuery Live()

Комментарии:

1. Отлично; спасибо. На самом деле я использовал delegate (), но understand live () тоже бы сработал.