I attached an event listener to my SVG image in order to perform some code after the image has been loaded. As it sometimes happens, a bug might occur in my SVG generating code and the SVG file won't load. In that case, when user clicks another button, I want it to remove the event listener, hide the unsuccessful result and let the user select another SVG image.
我将一个事件监听器附加到我的SVG图像,以便在加载图像后执行一些代码。由于有时会发生错误,我的SVG生成代码中可能会出现错误,并且不会加载SVG文件。在这种情况下,当用户单击另一个按钮时,我希望它删除事件侦听器,隐藏不成功的结果并让用户选择另一个SVG图像。
Here's what I have:
这就是我所拥有的:
// 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();
}
<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>
This came to me as a surprise: for once, in Internet Explorer 11, it does exactly what I want it to do; on the other hand, in Opera it doesn't work (the hell must have frozen I guess).
这让我感到惊讶:曾经,在Internet Explorer 11中,它完全符合我的要求;另一方面,在Opera中它不起作用(地狱必定已经冻结了我猜)。
Testing it on an image case I know for sure it won't load, it attempts to set the viewBox of the result image, fails to find the <svg>
tag, throws an alert message as it goes to editBrush(), removes the listener and allows me to select another SVG file, which it loads correctly then. That means it creates the listener once again, loads the correct URI, recognizes <svg>
tag, sets viewBox, removes the listener in the resultImageLoaded(event)
itself and all is good.
在图像上测试它我确定它不会加载,它会尝试设置结果图像的viewBox,找不到
In Opera, it attempts to set the viewBox of the result image, fails to find the <svg>
tag, throws an alert message as it goes to editBrush() and I suspect now it doesn't actually remove the listener. When I select another SVG image, which it should load correctly now, nothing happens (tried to add another alert to resultImageLoaded(event)
and it wasn't triggered).
在Opera中,它试图设置结果图像的viewBox,无法找到
Things I gave special attention to:
我特别注意的事情:
-
resultImageLoaded(event)
isn't an anonymous function and is located above the code that is using it - reference to the function itself in the add/remove listeners
- resultImage is stored in one variable and both add/remove listeners are on this one object
resultImageLoaded(event)不是匿名函数,位于使用它的代码之上
在add / remove侦听器中引用函数本身
resultImage存储在一个变量中,并且添加/删除侦听器都在这一个对象上
I can't see what I'm doing wrong, any help would be most appreciated.
我看不出我做错了什么,任何帮助都会非常感激。
EDIT: In console in Opera, it shows Internal server error (500) on GET request when I try to load the image that should fail loading. IE shows no such thing. Not sure if this can be of any help.
编辑:在Opera的控制台中,当我尝试加载应该加载失败的图像时,它在GET请求上显示内部服务器错误(500)。 IE显示没有这样的事情。不确定这是否有任何帮助。
EDIT 2: Alright, I just found out this has probably nothing to do with removeEventListener(). Even when I comment out all lines where I remove event listeners, the behaviour is exactly the same as described in both browsers. Could the problem be in Opera reporting an error and IE ignoring it?
编辑2:好吧,我刚刚发现这可能与removeEventListener()无关。即使我注释掉删除事件侦听器的所有行,其行为也与两个浏览器中描述的完全相同。问题可能在Opera报告错误而IE忽略它吗?
And question for mods: when I find out the original question's topic is no more relevant, but the problem still persists and I'm not even sure what might be causing it, what do I do? Brutally edit the original question or make a new one and leave the original one unanswered?
1 个解决方案
#1
0
Try adding event.stopPropagation();
at the end of each eventListener
, this will prevent bubbling of the event to your ancestors and it'll stop at your event.target
尝试添加event.stopPropagation();在每个eventListener的末尾,这将阻止事件冒泡到你的祖先,它将停止在你的event.target
If that doesn't help, try event.stopImmediatePropagation();
如果这没有帮助,请尝试event.stopImmediatePropagation();
http://www.kirupa.com/html5/handling_events_for_many_elements.htm
// 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();
}
<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>
#1
0
Try adding event.stopPropagation();
at the end of each eventListener
, this will prevent bubbling of the event to your ancestors and it'll stop at your event.target
尝试添加event.stopPropagation();在每个eventListener的末尾,这将阻止事件冒泡到你的祖先,它将停止在你的event.target
If that doesn't help, try event.stopImmediatePropagation();
如果这没有帮助,请尝试event.stopImmediatePropagation();
http://www.kirupa.com/html5/handling_events_for_many_elements.htm
// 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();
}
<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>