当新的 SVG 替换原始 SVG 时,SVG 元素上的 $.bind() 会中断

发布于 2024-11-03 23:09:16 字数 2191 浏览 1 评论 0原文

我有一个 svg,其中包含绑定到点击和按键的元素。如果用户编辑页面上的文本字段,它会更新 svg 中相应的文本元素。反之亦然,如果用户编辑 svg,它会更新 html 中相应的文本字段。使用 jQuery。

页面上的按钮允许用户从 DOM 中删除 svg 并在其位置添加不同的 svg(异步)。这个新的 svg 与第一个 svg 具有相同的元素,只是图形设计不同。

加载第二个 svg 后,绑定停止工作。我通过调用下面的 AB.init() 重新初始化所有内容 - 解除绑定和重新绑定 - 但用户仍然无法编辑 svg。我该如何解决这个问题?

更新:根据 @Pointy 的评论,所有 .bind() 现在都是 .delegate() 。然而问题仍然存在。我的 .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 && 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;
}
  },
  ...

I have an svg with elements that I am binding to clicks and keyups. If the user edits a text field on the page, it updates the corresponding text element in the svg. And vice versa, if the user edits the svg, it updates the corresponding text field in the html. Using jQuery.

A button on the page lets the user remove the svg from the DOM and add a different svg in its place (asynchronously). This new svg has the same elements as the first one, it just has a different graphical design.

After loading this second svg, the bindings stop working. I reinitialize everything -- unbinding and rebinding -- by calling AB.init() below but still the user can't edit the svg. How do I fix this?

UPDATE: all .bind()s are now .delegate()s per @Pointy's comment. However the problem persists. Is my .delegate() syntax valid for the namespace?

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 && 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;
}
  },
  ...

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

三寸金莲 2024-11-10 23:09:16

尝试 .live()

它将事件绑定到现在和将来与选择器匹配的元素。我在动态隐藏和显示元素时遇到了类似的问题。
jQuery Live()

Try .live()

It will bind events to elements that match a selector now and in the future. I have had similar issues when dynamically hiding and showing elements.
jQuery Live()

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文