RemoveEventListener似乎不起作用

时间:2015-11-28 11:03:42

标签: javascript html svg event-handling event-listener

我将一个事件监听器附加到我的SVG图像,以便在加载图像后执行一些代码。有时会发生错误,我的SVG生成代码中可能会出现错误,SVG文件无法加载。在这种情况下,当用户单击另一个按钮时,我希望它删除事件监听器,隐藏不成功的结果并让用户选择另一个SVG图像。

以下是我所拥有的:



// In external .js file, loaded prior to the other code in <head>
function setResultViewBox() {
  var objectEl = document.getElementById("resultImage");
  var svgDoc = objectEl.contentDocument;
  var svg = svgDoc.childNodes[0];
  // If there's no SVG tag, remove the listener etc. 
  // Tested via alert() and console messages that this actually works.
  if (svg.tagName !== "svg") {
    editBrush();
    return;
  }
  // some other code to set the viewBox
}

// Attached to the main file at the end of <body>
var resultImage = document.getElementById("resultImage");

    function resultImageLoaded(event) {
      resultImage.removeEventListener("load", resultImageLoaded, false);
      setResultViewBox();
      hideProgressBar();
    }

    submitChanges() {
      // Compute URI here
      resultImage.data = uri;
      resultImage.addEventListener("load", resultImageLoaded, false);
      hidePreview();
    }

    function editBrush() {
      alert();
      resultImage.removeEventListener("load", resultImageLoaded, false);
      hideResult();
      hideProgressBar();
    }
&#13;
<object id="resultImage" type="image/svg+xml" width="420" height="420" data=""></object>

<a href="javascript:void(0)" onclick="submitChanges()">Make outline</a>
<a href="javascript:void(0)" onclick="editBrush()">Edit brush</a>
&#13;
&#13;
&#13;

这让我感到惊讶:曾经,在Internet Explorer 11中,它完全符合我的要求;另一方面,在Opera中,它不起作用(地狱必定已经冻结了)。

在图像上测试它我肯定知道它不会加载,它会尝试设置结果图像的viewBox,找不到<svg>标记,随着它发出警告信息to editBrush(),删除监听器,并允许我选择另一个正确加载的SVG文件。这意味着它再次创建了监听器,加载了正确的URI,识别<svg>标签,设置了viewBox,删除了resultImageLoaded(event)本身的监听器,一切都很好。

在Opera中,它试图设置结果图像的viewBox,找不到<svg>标签,当它转到editBrush()时抛出一条警告信息,我怀疑它现在并没有删除监听器。当我选择另一个现在应该正确加载的SVG图像时,没有任何反应(试图向resultImageLoaded(event)添加另一个警报并且它没有被触发)。

我特别注意的事项:

  • resultImageLoaded(event)不是匿名函数,位于使用它的代码上方
  • 在添加/删除侦听器中引用函数本身
  • resultImage存储在一个变量中,并且添加/删除侦听器都在这个对象上

我无法看到自己做错了什么,任何帮助都会受到最高的赞赏。

编辑:在Opera的控制台中,当我尝试加载应该加载失败的图像时,它会在GET请求中显示内部服务器错误(500)。 IE显示没有这样的事情。不确定这是否有任何帮助。

编辑2:好吧,我刚发现这可能与removeEventListener()无关。即使我注释掉删除事件侦听器的所有行,其行为也与两种浏览器中描述的完全相同。问题可能在Opera报告错误而IE忽略它吗?

<小时/> 对于mods的问题:当我发现原始问题的主题不再相关时,但问题仍然存在,而且我甚至不确定可能导致它的原因,我该怎么办?粗暴地编辑原始问题或制作一个新问题并保留原始问题?

1 个答案:

答案 0 :(得分:0)

尝试在每个event.stopPropagation();的末尾添加eventListener,这样可以防止事件冒泡到您的祖先,并且它会停在您的event.target

如果这没有帮助,请尝试event.stopImmediatePropagation();

http://www.kirupa.com/html5/handling_events_for_many_elements.htm

&#13;
&#13;
// In external .js file, loaded prior to the other code in <head>
function setResultViewBox() {
  var objectEl = document.getElementById("resultImage");
  var svgDoc = objectEl.contentDocument;
  var svg = svgDoc.childNodes[0];
  // If there's no SVG tag, remove the listener etc. 
  // Tested via alert() and console messages that this actually works.
  if (svg.tagName !== "svg") {
    editBrush();
    return;
  }
  // some other code to set the viewBox
}

// Attached to the main file at the end of <body>
var resultImage = document.getElementById("resultImage");

    function resultImageLoaded(event) {
      resultImage.removeEventListener("load", resultImageLoaded, false);
      setResultViewBox();
      hideProgressBar();
      event.stopPropagation();
    }

    submitChanges() {
      // Compute URI here
      resultImage.data = uri;
      resultImage.addEventListener("load", resultImageLoaded, false);
      hidePreview();
      event.stopPropagation();
    }

    function editBrush() {
      alert();
      resultImage.removeEventListener("load", resultImageLoaded, false);
      hideResult();
      hideProgressBar();
      event.stopPropagation();
    }
&#13;
<object id="resultImage" type="image/svg+xml" width="420" height="420" data=""></object>

<a href="javascript:void(0)" onclick="submitChanges()">Make outline</a>
<a href="javascript:void(0)" onclick="editBrush()">Edit brush</a>
&#13;
&#13;
&#13;