javascriptdom-eventsinternet-explorer-9internet-explorer-10

IE 9, 10: div structure and events


I have a not so complicated <div> structure, which breaks event handlers in IE < 11 (other major browsers like Chrome and Firefox are working).

<div id="container">
    <div id="layer">
        <div id="layer1">
            <img src="http://sopos.org/olli/blindbild.png" style="position: absolute; top: 0; left: 0; width: 100%; height: 100%;" />
        </div>
    </div>
    <div id="controls">
        <div id="controller"></div>
        <input id="slider" type="range" />
    </div>
    <div id="thumbnailer">
        <img src="http://sopos.org/olli/blindbild-thumb.png" />
        <div id="viewArea"></div>
    </div>
</div>

These are the registered event handlers:

$(function () {
    var stopPropagation = function (e) {
        e.stopPropagation();
        e.preventDefault();
        e.stopImmediatePropagation();
    }
    $('#controller').on('mousedown', function (e) {
        console.log('controller mousedown');
    });
    $('#controls').on('mousewheel', function (e) {
        console.log('controls mousewheel');
        stopPropagation(e);
        return false;
    });
    $('#thumbnailer').on('click', function (e) {
        console.log('thumbnailer clicked');
    });
    $('#viewArea').on('click', function (e) {
        console.log('viewarea click');
        stopPropagation(e);
        return false;
    });
    $('#viewArea').on('mousedown', function (e) {
        console.log('viewarea mousedown');
        stopPropagation(e);
        return false;
    });
    $('#slider').on('change', function (e) {
        console.log('slider change');
        stopPropagation(e);
        return false;
    });
});

The main problem seems to be CSS positioning and sizing:

#layer {
    position: absolute;
    top: -175.813008130081px;
    left: -578.615px;
    width: 1421px;
    height: 875px;
}
#layer1, #layer1 img {
    position: absolute;
    top: 0;
    left: 0;
    width: 100%;
    height: 100%;
}
#controls {
    position: absolute;
    top: 0px;
    left: 0px;
    width: 100%;
    height: 100%;
}
#thumbnailer {
    background-color: rgba(150, 150, 150, 0.7);
    border: 1px solid rgb(150, 150, 150);
    position: absolute;
    bottom: 15px;
    right: 10px;
    width: 200px;
    height: 123px;
}
#thumbnailer img {
    width: 100%;
    height: 100%;
}
#viewArea {
    position: absolute;
    top: 25px;
    left: 81px;
    border: 1px solid #f00;
    width: 56%;
    height: 56%;
}
#controller {
    width: 100%;
    height: 100%;
}
#slider {
    position: absolute;
    bottom: 10px;
    left: 200px;
}

In IE < 11, any click or mousedown on viewArea remains unhandled; instead, an event on thumbnailer is fired. Similarily, the mousewheel event on controls and the mousedown on controller don't get handled. The mousewheel event get's fired when the cursor is over the slider element, though.

This strange behaviour seems to be rooted in the size of the two images. However, my application needs to display bigger images in a relative small container (hence overflow: hidden set).

I created a fiddle for that.


Solution

  • The problem seems to be that IE < 11 doesn't trigger events on empty <div>. Adding a transparent <img> to the div solves the problem:

    <div id="container">
        <div id="layer">
            <div id="layer1">
                <img src="http://sopos.org/olli/blindbild.png" style="position: absolute; top: 0; left: 0; width: 100%; height: 100%;" />
            </div>
        </div>
        <div id="controls">
            <div id="controller">
               <img src="data:image/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw==" style="width:100%; height:100%;">
            </div>
            <input id="slider" type="range" />
        </div>
        <div id="thumbnailer">
            <img src="http://sopos.org/olli/blindbild-thumb.png" />
            <div id="viewArea">
               <img src="data:image/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw==" style="width:100%; height:100%;">
            </div>
        </div>
    </div>