Search code examples
javascriptevent-handlingoperaaddeventlistenerimage-loading

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


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.


Solution

  • 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!