This tutorial is
going to be split into 4 sections. The
goal of this tutorial is to create a simple web site that has a top bar with a static
Height, a left tool bar with a static width, and a variable "display
area" which will take up the rest of the space.
This tutorial will
start where the last tutorial finished were the problem
Of resizing on a
window resize was not yet solved.
I also made a video of this tutorial check it out at
http://youtu.be/tqkxwNwyIzY
The other tutorials can be found here
1st http://www.whiteboardcoder.com/2014/04/jquery-site-setup-positioning-1-of-4.html
3rd http://www.whiteboardcoder.com/2014/05/jquery-site-setup-positioning-3-of-4.html
4th http://www.whiteboardcoder.com/2014/05/jquery-site-setup-positioning-4-of-4.html
Output to console
Edit the JavaScript
to write to the console.
> vi js/main.js
|
And update it the
following
(function (window, undefined) {
$(window).load(function () {
setSizes()
})
$(window).resize(function () {
console.log("(" +
$(window).width() + ", "
+
$(window).height() + ")")
})
function setSizes() {
$("#nav-display-area").height(
$(window).height() - $("#nav-top").height() - 10)
.width(
$(window).width() - $("#nav-left-outer").width() - 10)
}
})(this)
|
Open the console.
From google chrome
you can use the hot key
Ctrl+shift+j
Or you can click on
the menu and select Tools -> JavaScript Console
Now resize the
screen a bit and you will see the console update its data
Here you can see the
information scrolling by as you resize the window.
The resize event
kicks off rather quickly.
In fact it kicks off
too much. The resize of the element
sizes does not need to occur every millisecond but rather every 250 or 500
milliseconds is more than fast enough and reduces CPU usage.
Resize Elements to fit window size
To accomplish this
you can use the JavaScript setTimeout function see http://www.w3schools.com/jsref/met_win_settimeout.asp [1] for more details.
I am using the code
suggested as the solution at http://stackoverflow.com/questions/599288/cross-browser-window-resize-event-javascript-jquery [2]
Edit the JavaScript
> vi js/main.js
|
And update it the
following
(function (window, undefined) {
$(window).load(function () {
setSizes()
})
var resizeTimer
$(window).resize(function () {
console.log("(" +
$(window).width() + ", "
+
$(window).height() + ")")
clearTimeout(resizeTimer)
resizeTimer =
setTimeout(function () {
setSizes()
console.log("Finish
Resizing")
}, 250)
})
function setSizes() {
$("#nav-display-area").height(
$(window).height() - $("#nav-top").height() - 10)
.width($(window).width() -
$("#nav-left-outer").width() - 10)
}
})(this)
|
This will run the
setSizes function 250 milliseconds after the last resize event occurs.
Reload the page and
resize it
You will see that
the display area resizes with the browser (almost perfectly)
Sometimes the bottom
has this little gap, which is from the scrollbars
In the case of IE
you see the gap on both sides.
To better see what
is going on up the timeout to 5000 (5 seconds) and change the size of the
window.
When you shrink the
window you will see the scroll bars appear.
These effectively reduce the $(window).height() and
$(window).width(). As a result the setSizes
function makes the div fit within the
scroll bars, which makes the scroll bars unnecessary and then they are removed
leaving your div a little too small.
So…. What is a good way to fix this problem?
One way is to run
setSizes twice if the browser window has been reduced (either its width or
height).
Edit the JavaScript
> vi js/main.js
|
And update it the
following
(function (window, undefined) {
$(window).load(function () {
setSizes()
})
var resizeTimer
$(window).resize(function () {
console.log("(" + $(window).width()
+ ",
"
+ $(window).height() + ")")
clearTimeout(resizeTimer)
resizeTimer = setTimeout(function () {
setSizes()
console.log("Finish
Resizing")
}, 250)
})
function setSizes() {
priorHeight = $("#nav-display-area").height()
priorWidth =
$("#nav-display-area").width()
$("#nav-display-area").height(
$(window).height() - $("#nav-top").height() - 10)
.width($(window).width() -
$("#nav-left-outer").width() - 10)
if (priorHeight > $("#nav-display-area").height()
||
priorWidth > $("#nav-display-area").width()) {
//Call setSizes again
setSizes()
}
}
})(this)
|
That worked!
A better way is just to remove the scroll bars temporarily while you
resize.
Edit the JavaScript
> vi js/main.js
|
And update it the
following
(function (window, undefined) {
$(window).load(function () {
setSizes()
})
var resizeTimer
$(window).resize(function () {
console.log("(" + $(window).width()
+ ",
"
+ $(window).height() + ")")
clearTimeout(resizeTimer)
resizeTimer = setTimeout(function () {
setSizes()
console.log("Finish
Resizing")
}, 250)
})
function setSizes() {
$('body').css('overflow', 'hidden')
//Temporarily remove the scroll bars
$("#nav-display-area").height(
$(window).height() - $("#nav-top").height() - 10)
.width($(window).width() -
$("#nav-left-outer").width() - 10)
$('body').css('overflow', 'visible')
//Make them visible again if need be
}
})(this)
|
That worked!
And in a much simpler way
Another way, using CSS calc function
There is another way
to do this using the CSS function calc http://www.w3.org/TR/css3-values/#calc [3]
If I turn off my
javascript and edit my nav.css as follows
html, body {
margin: 0;
background-color:yellow;
}
#nav{
position:relative
background-color:red;
height:100%;
}
#nav-top{
position:absolute;
top:0px;
right:0px;
height:200px;
width:100%;
background-color:#f58a22;
z-index:2;
}
#nav-left-outer{
position:absolute;
top:0px;
left:0px;
width:200px;
height:100%;
background-color:#000000;
z-index:1;
}
#nav-left{
position:absolute;
top:200px;
left:0px;
background-color:#000000;
color:#FFFFFF;
}
#nav-display-area-outer{
position:absolute;
top:0px;
left:0px;
width:100%;
height:100%;
background-color:#80dd77;
}
#nav-display-area{
position:absolute;
top:200px;
left:200px;
background-color:#80dd77;
border:solid 5px red;
width:calc(100% - 200px - 10px);
height:calc(100% - 200px - 10px);
}
|
Now reload the page
and resize it.
You can see that
this works just fine, however before you choose to use the calc CSS tool you
should see how cross-browser friendly it is.
Firefox and chrome
has supported it for some time, but IE only fully supported it in IE 10 and
even safari in version 6.0
Using Underscore debounce function
Finally, I would
like to go over a little clean up the setTimeout function clearTimeout seems a
little long winded in this day and age.
The Underscore.js library http://underscorejs.org/ [1] provides a shorter way of doing this
with the debounce functions
Download underscore.js
> cd js
> wget http://underscorejs.org/underscore.js
> cd ..
|
Now add it to the
index.html
> vi index.html
|
<html>
<head>
<link rel="stylesheet" href="css/main.css" type="text/css"/>
</head>
<body>
<div id="nav">
<div id="nav-top">
<h1>This is the Top Area</h1>
</div>
<div id="nav-left-outer">
<div id="nav-left">
<h1>Side Area<br/><br/>Static Width</h1>
</div>
</div>
<div id="nav-display-area-outer">
<div id="nav-display-area">
<h1>Resizeable Display Area</h1>
</div>
</div>
</div>
<script src="//ajax.googleapis.com/ajax/libs/jquery/2.1.0/jquery.min.js"></script>
<script src="js/underscore.js"></script>
<script src="js/main.js"></script>
</body>
</html>
|
Edit main.js
JavaScript to use it
> vi js/main.js
|
And edit it to the
following
(function (window, undefined) {
$(window).load(function () {
setSizes()
})
$(window).resize(_.debounce(function () {
setSizes()
}, 250))
function setSizes() {
priorHeight = $("#nav-display-area").height()
priorWidth = $("#nav-display-area").width()
$("#nav-display-area").height(
$(window).height() - $("#nav-top").height() - 10)
.width($(window).width() -
$("#nav-left-outer").width() - 10)
console.log("(" + $(window).width()
+ ",
"
+ $(window).height() + ")")
if (priorHeight > $("#nav-display-area").height()
|| priorWidth > $("#nav-display-area").width()) {
//Call setSizes again
setSizes()
}
}
})(this)
|
The debounce
function makes code look a lot cleaner.
The resizable area
is done and working, the next tutorial will go over using JQuery load function
to add clickable buttons that will upload information to a div asynchronously.
The next tutorial can be found at
http://www.whiteboardcoder.com/2014/05/jquery-site-setup-positioning-3-of-4.html
References
[1] W3C
School setTimeout function
Accessed
03/2014
[2] Cross-browser
window resize event - JavaScript / jQuery
Accessed
03/2014
[3] Cross-browser
window resize event - JavaScript / jQuery
Accessed
03/2014
[4] Can I
use calc() as CSS unit value?
Accessed
03/2014
No comments:
Post a Comment