Scrolling is jumpy in IE9

I need to create a layout with a fixed header bar on the top that will hold different controls, and big scrollable svg area under it where I will be placing different svg elements. That area will have header on the top (timeline) and on the left (location names).

The scrollable area should behave like a data grid view with column headers on the top and row headers on the left, but the grid content does not have cells but svg (or canvas).

This jsfiddle should give better idea what I am trying to accomplish (I use opacity just to see how elements behave during scrolling):

http://jsfiddle.net/serge_s/bLy61krL/2/

HTML:

<!DOCTYPE html>

<html>
<head runat="server">
    <title>Page 1</title>

    <link href="ForStackOverflow.css" rel="stylesheet" />

    <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.3/jquery.min.js"></script>
    <script type="text/javascript" src="http://mbostock.github.com/d3/d3.js"></script>
    <script src="ForStackOverflow.js?1" type="text/javascript"></script>
</head>
<body>
    <form id="form1">
        <header id="toolbar" class="header">
            <span id="scroll"></span>
            <span>This is my header with controls</span>
        </header>

        <div id="date" class="disp_date">bla-bla</div>

        <svg id="rooms" class="rooms">
        </svg>

        <div id="container" class="container">
            <svg id="times" class="times"></svg>
            <svg id="canv"></svg>


        </div>



    </form>
</body>
</html>

<script type="text/javascript">
    $(document).ready(function () {

        myLoad();
    });
</script>

Javascript code:

var roomWidth = 150, roomHeight = 50;
var timesHeight = 45;
// width of 30 minutes slot
var min30 = 150;
var vscrolled, hscrolled;

var room_count = 30;


function myLoad() {

    $(window).bind('scroll', function (e) { myScroll(); });

    getTimeSlots();
    getRooms();


    // draw something
    var canv = d3.select('#canv');
    for(var i=0; i < 20; i++) {
        var xtime = Math.floor((Math.random() * 30) + 1) * min30;
        var xw = Math.floor((Math.random() * 500) + 1);
        var y = Math.floor(Math.random() * (room_count-1) * roomHeight);
        canv.append("rect")
            .attr("x", xtime)
            .attr("width", xw)
            .attr("y", y)
            .attr("width", roomWidth)
            .attr("height", roomHeight)
            .attr("class","rect2");
    }


}





function getRooms() {
    var d3rooms = d3.select('#rooms');
    var y = 0;
    var text_y = 0;

    for (i=0; i < room_count; i++) {
        var room_name = "Row " + i;
        text_y = y + roomHeight / 2;
        d3rooms.append("rect")
            .attr("class", 'rect')
            .attr("x", 0)
            .attr("y", y)
            .attr("width", roomWidth)
            .attr("height", roomHeight);
        d3rooms.append("text")
            .attr("x", 0)
            .attr("y", text_y)
            .text(room_name);
        y += roomHeight;
    }
    $('#rooms').css({height:y});
    $('.container').css({height:y + timesHeight});
    $('#canv').css({height:room_count*roomHeight});
}



// generate time slot header text
function getTimeSlots() {
    var minutes = ["00", "30"];
    d3svg = d3.select('#times');
    var y = 0, text_y = y + 30;
    for (var hh = 0; hh < 24; hh++) {
        for (var mins = 0; mins < 2; mins++) {
            var time = hh + ':' + minutes[mins] + (hh < 12 ? ' am' : ' pm');
            var rect_x = min30 * (hh * 2 + mins);
            d3svg.append("rect")
                .attr("class", 'rect')
                .attr("x", rect_x)
                .attr("y", y)
                .attr("width", min30)
                .attr("height", timesHeight);
            d3svg.append("text")
                .attr("x", rect_x)
                .attr("y", text_y)
                .text(time);
        }
    }
    $("#times").css({ width: min30 * 48, height: roomHeight });
    $('.container').css({width:min30*48});
    $('#canv').css({top:timesHeight,width:min30*48});

}



function myScroll() {
    vscrolled = $(window).scrollTop();
    hscrolled = $(window).scrollLeft();
    $('#times').css({ top: vscrolled + "px" });
    $('#rooms').css({ left: hscrolled + "px" });
}

CSS:

body {
    margin:0;
}

/* header - this is where the toolbar and running text go */
.header {
    width:100%;
    height: 60px;
    background:lightblue;
    border:1px solid green;
    position: fixed;
    margin:0px auto;
    top:0px;
    z-index:10;
}

/* this is where current date and calendar button go */ 
.disp_date {
    width:150px;
    height:50px;
    background: white;
    position:fixed;
    left:0px;
    top:60px;
    z-index:5;
}

/* room list (vertical) */
.rooms {
    fill:yellow;
    position:absolute;
    left:0px;
    top:110px;
    /*border: 3px solid red;*/
    z-index:2;
    width: 150px;
    height:auto;
}

/* actual room rects */
.rect
{
    fill:green;
    stroke:black;
    stroke-width:1;
    opacity:0.5;
}



/* this is time slots header */
.times {
    position:absolute;
    left: 0px; /*150px;*/
    opacity:0.5;
    z-index:1;
}



/* includes tim slots header, canvas (background grid) and cases */     
.container {
    background:pink;
    position:absolute;
    left:150px;
    top:60px;
}

#canv {
    background:yellow;
    opacity:0.5;
    position:relative;
}

.rect2
{
    fill:blue;
    stroke:black;
    stroke-width:1;
    opacity:0.5;
}

The problem is that it runs fine in Firefox or Chrome but very jumpy in IE9. Unfortunately I have to stick with IE9 because it's a corporate environment.

I wonder if I can achieve the same scrollable layout with just html/ccs or if someone could tell me how to avoid the jerky scrolling in IE9.

I am just learning html/css. Any help will be appreciated.

Answers


I made changes to the layout and code and it's working now in IE 9 as well. Here is a link to fixed JSFiddle

HTML:

    <!DOCTYPE html>
<head runat="server">
  <title>Page 1</title>
</head>
<body>
    <form id="form1">
        <header id="toolbar" class="header">
            <span id="scroll"></span>
            <span>This is my header with controls</span>
        </header>

        <div id="date" class="disp_date">bla-bla</div>
        <div id="divtimes">
            <svg id="times" class="times"></svg>
        </div>
        <div id="divrooms">
            <svg id="rooms" class="rooms"></svg>
        </div>

        <div id="scrl">
            <svg id="canv"></svg>
        </div>

    </form>
</body>

<script type="text/javascript">
   $(document).ready(function () {
      myLoad();
   });
</script>

Javascript:

var roomWidth = 150, roomHeight = 50;
var headerHeight = 60;
var timesHeight = 45;
// width of 30 minutes slot
var min30 = 150;
var vscrolled, hscrolled;

var room_count = 30;
var scrollBarWidth = 0;


function setSizes() {
    $('.header').css({ height: headerHeight});
    $('#scrl').css({ left: roomWidth, top: headerHeight + timesHeight });
    $('.disp_date').css({ height: timesHeight, width: roomWidth, top: headerHeight });
    $('#divrooms').css({ width: roomWidth, top: headerHeight + timesHeight });
    $('#divtimes').css({ left: roomWidth, top: headerHeight });
    $('.rooms').css({ width: roomWidth });


}

function myLoad() {

    scrollBarWidth = getScrollbarWidth();
    // reset css sizes
    setSizes();


    var h = $(window).height() - timesHeight - $('.header').height();
    var w = $(window).width() - roomWidth;
    $('#scrl').css({ height: h, width: $(window).width() - roomWidth });
    $('#divrooms').css({ height: h - scrollBarWidth });
    $('#divtimes').css({ width: w - scrollBarWidth });

    $('#scrl').bind('scroll', function (e) { myScroll(); });
    getTimeSlots();
    getRooms();


    drawGrid();

}


// draw time grid
function drawGrid() {

    var canv = d3.select('#canv');
    var y2 = $('#canv').height();
    for (var i = 0; i < 48; i++) {
        canv.append("line")
            .attr("x1", i * min30)
            .attr("y1", 0)
            .attr("x2", i * min30)
            .attr("y2", y2)
            .attr("stroke", "gray")
            .attr("stroke-width",1);
    }

    var x2 = $('#canv').width();
    for (var i = 0; i < room_count; i++) {
        canv.append("line")
            .attr("x1", 0)
            .attr("y1", i * roomHeight)
            .attr("x2", x2)
            .attr("y2", i * roomHeight)
            .attr("stroke", "gray")
            .attr("stroke-width", 1);
    }



}


// generate time slot header text
function getTimeSlots() {
    var minutes = ["00", "30"];
    d3svg = d3.select('#times');
    var y = 0, text_y = y + 30;
    for (var hh = 0; hh < 24; hh++) {
        for (var mins = 0; mins < 2; mins++) {
            var time = hh + ':' + minutes[mins] + (hh < 12 ? ' am' : ' pm');
            var rect_x = min30 * (hh * 2 + mins);
            d3svg.append("rect")
                .attr("class", 'rect')
                .attr("x", rect_x)
                .attr("y", y)
                .attr("width", min30)
                .attr("height", timesHeight);
            d3svg.append("text")
                .attr("x", rect_x)
                .attr("y", text_y)
                .text(time);
        }
    }
    $("#times").css({ width: min30 * 48, height: roomHeight });
    $('#canv').css({ width: min30 * 48 });




}



function getRooms() {
    var d3rooms = d3.select('#rooms');
    var y = 0;
    var text_y = 0;

    for (i=0; i < room_count; i++) {
        var room_name = "Row " + i;
        text_y = y + roomHeight / 2;
        d3rooms.append("rect")
            .attr("class", 'rect')
            .attr("x", 0)
            .attr("y", y)
            .attr("width", roomWidth)
            .attr("height", roomHeight);
        d3rooms.append("text")
            .attr("x", 0)
            .attr("y", text_y)
            .text(room_name);
        y += roomHeight;
    }
    //$('#divrooms').css({height:y});
    $('#rooms').css({height:y});
    $('#canv').css({height:room_count*roomHeight});
}



function getScrollbarWidth() {
    var outer = document.createElement("div");
    outer.style.visibility = "hidden";
    outer.style.width = "100px";
    outer.style.msOverflowStyle = "scrollbar"; // needed for WinJS apps

    document.body.appendChild(outer);

    var widthNoScroll = outer.offsetWidth;
    // force scrollbars
    outer.style.overflow = "scroll";

    // add innerdiv
    var inner = document.createElement("div");
    inner.style.width = "100%";
    outer.appendChild(inner);

    var widthWithScroll = inner.offsetWidth;

    // remove divs
    outer.parentNode.removeChild(outer);

    return widthNoScroll - widthWithScroll;
}

function myScroll() {
    vscrolled = $('#scrl').scrollTop();
    hscrolled = $('#scrl').scrollLeft();

    $('#times').css({ left: -hscrolled + "px" });
    $('#rooms').css({ top: -vscrolled + "px" });
}

myLoad();

CSS:

body {
    margin:0;
}

/* header - this is where the toolbar and running text go */
.header {
    width:100%;
    height: 60px;
    background:lightblue;
    position: fixed;
    margin:0px auto;
    top:0px;
    z-index:10;
    overflow:hidden;
}

#scrl {
    overflow:scroll;
    position:absolute;
    left:150px;
    top:105px;
}

/* this is where current date and calendar button go */ 
.disp_date {
    width:150px;
    height:50px;
    background: white;
    position:relative;
    left:0px;
    top:60px;
    z-index:5;
    display:inline;
}

#divrooms {
    overflow:hidden;
    position:fixed;
    left:0px;
    top:105px; /* height of header + times*/
    width: 150px;
}       

#divtimes {
    overflow:hidden;
    position:fixed;
    left:150px;
    top:60px; /* height of header */
}

/* room list (vertical) */
.rooms {
    fill:yellow;
    position:relative;
    left:0px;
    top:0px;
    z-index:2;
    width: 150px;
    height:auto;
    overflow:hidden;
}

/* actual room rects */
.rect
{
    fill:green;
    stroke:black;
    stroke-width:1;
    opacity:0.5;
}



/* this is time slots header */
.times {
    position:relative;
    left: 0px; /*150px;*/
    top:0px;
    opacity:0.5;
    z-index:1;
    overflow:hidden;
}


#canv {
    background:yellow;
    opacity:0.5;
    position:relative;
}

.rect2
{
    fill:blue;
    stroke:black;
    stroke-width:1;
    opacity:0.5;
}

Need Your Help

Removing a subset of a dict from within a list

python list containers

This is really only easy to explain with an example, so to remove the intersection of a list from within a dict I usually do something like this:

Best Small & Mid-Size Application Arcitecture

asp.net wpf asp.net-mvc architecture

I am Developing a mid-size application and want to implement Application Architecture, I've read some Architecture Books and Approach and think about