Must an element be visible in order to “load” event listener to work?

拥有回忆 提交于 2019-12-25 03:44:40

问题


In my document, there are two svg images: the preview and the result. The result image is computed based on the preview image; I switch between them by adding/removing class hidden-display, which is further affected by css like this:

.hidden-display {
display: none;
}

This seems to be working well.

While the result image is being computed, I want to hide the preview image and show only a progress bar; once the result image is loaded, I want it to be displayed and hide the progress bar. Here's the code that works; see especially the two occurrences of function showResult():

function resultImageLoaded(event) {
    console.log("Inside add event listener function");
    resultImage.removeEventListener("load", resultImageLoaded, false);
    //showResult();    // Doesn't work if uncommented
    hideProgressBar();
    console.log("End event listener");
}

function submitChanges() {
    showProgressBar();

    var inputData = getInputString();
    var uri = "./ResultImage.cshtml?inputData=" + encodeURIComponent(inputData);

    resultImage.data = uri;
    resultImage.addEventListener("load", resultImageLoaded, false);

    hidePreview();
    showResult();    // Doesn't work if commented out
}

Problem: While the code above works, it doesn't do exactly what I wanted: it hides the preview, shows the result and only then the event listener function is called, which hides the progress bar.

If I comment out showResult() in the function submitChanges() and uncomment it in the event listener function instead, the listener function resultImageLoaded(event) is never called - probably meaning the result image is never loaded. This leads me to suspicion that invisible elements don't trigger the "load" event listeners, but that seems strange.

I tested this in two browsers - Internet Explorer 11 and Opera 33.0. In IE, everything works as expected and the event listener is called, but in Opera I encountered the problem described above.

Any help would be most appreciated.


回答1:


Per our discussion, visibility:hidden is solving the event issue. Following is a example addressing your second problem, UI spacing.

function registerEvent() {
  document.getElementById("test").addEventListener("click", function() {
    console.log("Test");
  });
}

function addClass(str) {
  document.getElementById("test").className = str;
}
div {
  height: 100px;
  width: 100px;
  border: 2px solid gray;
  float: left;
  margin: 10px;
  padding: 10px;
}
.display {
  display: none
}
.hidden {
  visibility: hidden
}
.invisible {
  visibility: hidden;
  height: 0px;
  width: 0px;
  margin: 0px;
  padding: 0px;
}
.show {
  visibility: visible;
  display: block;
}
<div id="test">0</div>
<div id="test1">1</div>


<button onclick="addClass('display')">Display</button>
<button onclick="addClass('hidden')">Hidden</button>
<button onclick="addClass('invisible')">Invisible</button>
<button onclick="addClass('show')">Show</button>

Hope it helps!




回答2:


In fact, in Opera one cannot register an event on a node with display:none. Since working with visibility may easily mess up the formatting it may be a solution work with opacity like:

.hide {
  opacity: 0;
  z-index: -20;
}

.show {
  opacity: 1;
  z-index: -1;
}

Just toggle this two classes on the div's you want to show/hide. If the user needs to interact with something in the presented div you will have to add the z-index (as above). This also opens the possibility to add some nice transitions.



来源:https://stackoverflow.com/questions/34290356/must-an-element-be-visible-in-order-to-load-event-listener-to-work

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!