settimeout giving Uncaught ReferenceError: function is not defined - javascript

Could somebody tell me why this gives an error?
I moved the code into functions to allow me to delay it so it's not so sensitive (was getting annoying)
Uncaught ReferenceError: hideleftnav is not defined
Uncaught ReferenceError: showleftnav is not defined
function showleftnav()
{
$(".leftnavdiv").css('width','500px');
$("body").css('padding-left','510px');
//get measurements of window
var myWidth = 0, myHeight = 0;
if( typeof( window.innerWidth ) == 'number' ) {
//Non-IE
myWidth = window.innerWidth;
myHeight = window.innerHeight;
} else if( document.documentElement && ( document.documentElement.clientWidth || document.documentElement.clientHeight ) ) {
//IE 6+ in 'standards compliant mode'
myWidth = document.documentElement.clientWidth;
myHeight = document.documentElement.clientHeight;
} else if( document.body && ( document.body.clientWidth || document.body.clientHeight ) ) {
//IE 4 compatible
myWidth = document.body.clientWidth;
myHeight = document.body.clientHeight;
}
$('#maindiv').width(myWidth - 540);
}
function hideleftnav()
{
$(".leftnavdiv").width(10);
$("body").css('padding-left','20px');
//get measurements of window
var myWidth = 0, myHeight = 0;
if( typeof( window.innerWidth ) == 'number' ) {
//Non-IE
myWidth = window.innerWidth;
myHeight = window.innerHeight;
} else if( document.documentElement && ( document.documentElement.clientWidth || document.documentElement.clientHeight ) ) {
//IE 6+ in 'standards compliant mode'
myWidth = document.documentElement.clientWidth;
myHeight = document.documentElement.clientHeight;
} else if( document.body && ( document.body.clientWidth || document.body.clientHeight ) ) {
//IE 4 compatible
myWidth = document.body.clientWidth;
myHeight = document.body.clientHeight;
}
$('#maindiv').width(myWidth - 50);
}
$(".leftnavdiv").live({ //code for autohide
mouseenter:
function () {
setTimeout("showleftnav()", 5000);
},
mouseleave:
function () {
setTimeout("hideleftnav()", 5000);
}
});

Looks like you've found one problem with using setTimeout with a string as the first argument. Here's a condensed example illustrating the same problem:
(function() {
function test() {
console.log('test');
}
setTimeout('test()', 500); // ReferenceError: test is not defined
setTimeout(test, 500); // "test"
setTimeout(function() { // "test"
test();
}), 500);
})();
Demo: http://jsfiddle.net/mXeMc/1/
Using the string causes your code to be evaluated with the window context. But since your code is in a callback function, test isn't accessible from window; it's private and restricted only to the scope of the anonymous function.
Referencing the function with just test avoids this problem because you're pointing directly to the function without using eval.

Related

live browser size detection

This code only works based on the size of the browser at the time of loading, just wondering what could I implement for it get the current browser size and work based on that current information.
I have tried wrapping it in resize() but it causes it behave strangely, i.e the toggle goes on and off continuously , or when loading in a shrunk browser it doesnt work at all.
Its a responsive site where the footer menu is just static links on a large screen but turns into drop menu on small screen.
var myWidth = 0, myHeight = 0;
if( typeof( window.innerWidth ) == 'number' ) {
//Non-IE
myWidth = window.innerWidth;
myHeight = window.innerHeight;
} else if( document.documentElement && ( document.documentElement.clientWidth || document.documentElement.clientHeight ) ) {
//IE 6+ in 'standards compliant mode'
myWidth = document.documentElement.clientWidth;
myHeight = document.documentElement.clientHeight;
}
if(myWidth < 980) {
$("#footer h3").click(function () {
$(this).toggleClass("active");
$(this).parent().find("ul").slideToggle('medium');
});
}
var myWidth = 0, myHeight = 0;
function getSize(){
if( typeof( window.innerWidth ) == 'number' ) {
//Non-IE
myWidth = window.innerWidth;
myHeight = window.innerHeight;
} else if( document.documentElement && ( document.documentElement.clientWidth || document.documentElement.clientHeight ) ) {
//IE 6+ in 'standards compliant mode'
myWidth = document.documentElement.clientWidth;
myHeight = document.documentElement.clientHeight;
}
}
getSize(); // run first time
$(window).resize(function(){
getSize(); // do it on resize
});
$("#footer h3").click(function () {
getSize(); // not needed but good to have
if(myWidth < 980) {
$(this).toggleClass("active");
$(this).parent().find("ul").slideToggle('medium');
}
});
You should use css media queries instead:
#media only screen and (max-device-width: 980px) {
// css goes here...
}
OR include conditional style sheets:
<link rel="stylesheet" type="text/css" media="only screen and (max-device-width: 480px)" href="small-device.css" />
Here is a great article disusing responsive design
Try something like this:
var waitForFinalEvent = (function () {
var timers = {};
return function (callback, ms, uniqueId) {
if (!uniqueId) uniqueId = "Don't call this twice";
if (timers[uniqueId]) clearTimeout (timers[uniqueId]);
timers[uniqueId] = setTimeout(callback, ms);
};
})();
$(window).resize(function(){
waitForFinalEvent(function(){
// put all your code here
}, 20, "resize"); // replace 20 with every milliseconds to execute during
// resize
})
The code you put in there will execute every time the window resizes, simply using resize() won't always work because it doesn't necessarily check as you're resizing.

Dynamically Resizing Image Maps?

Hope you can help with this problem I've been trying to nut out.
I've found the examples on http://home.comcast.net/~urbanjost/semaphore.html very awesome and work perfectly for what I need.
Only problem is that I'd like the coordinates to dynamically change based on the window size first. The way it works at the moment is that it loads the default coords (works great for resolutions of 1920x1080 but is hugely unaligned on 1024x768) and will then resize on window resize.. I'd like it to detect the size of the browser window for smaller screens first, then display the code accordingly.
Here's my javascript:
<script type="text/javascript" >
//||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||| |||||||||||||||||||||||||||||||||||||||||
GLOBAL_AREAS= new Array();
GLOBAL_SUFFIX= "g";
GLOBAL_WIDTH=-1;
GLOBAL_HEIGHT=-1;
GLOBAL_NEW_AREAS= new Array();
//---------------------------------------------------------------------------
function setglobal(){
// place original AREA coordinate strings into a global array, called first time setXY is called
var arrayAreas = document.body.getElementsByTagName("AREA" );
GLOBAL_WIDTH= document.getElementById("tclteam_s1" ).width; // get original width
GLOBAL_HEIGHT= document.getElementById("tclteam_s1" ).height; // get original height
for(var i = 0; i < arrayAreas.length; i++) {
GLOBAL_AREAS[i]= arrayAreas[i].coords;
}
document.body.onresize=setXY('tclteam_s1',XSIZE(),YSIZE());
// alert("GLOBAL_AREAS" + GLOBAL_AREAS );
}
//---------------------------------------------------------------------------
function setXY(elementid,newwidth,newheight){
if (GLOBAL_WIDTH == -1 ){
setglobal();
}
document.getElementById(elementid).width=newwidth;
document.getElementById(elementid).height=newheight;
scaleArea();
}
//---------------------------------------------------------------------------
function XSIZE(){ // get browser window.innerWidth , dealing with ie
var myWidth = 1;
if( typeof( window.innerWidth ) == 'number' ) {
//Non-IE
myWidth = window.innerWidth;
} else if( document.documentElement && ( document.documentElement.clientWidth ) ) {
//IE 6+ in 'standards compliant mode'
myWidth = document.documentElement.clientWidth;
} else if( document.body && ( document.body.clientWidth ) ) {
//IE 4 compatible
myWidth = document.body.clientWidth;
}
return myWidth;
}
//---------------------------------------------------------------------------
function YSIZE(){ // get browser window.innerHeight, dealing with ie
var myHeight = 1;
if( typeof( window.innerHeight ) == 'number' ) {
//Non-IE
myHeight = window.innerHeight;
} else if( document.documentElement && ( document.documentElement.clientHeight ) ) {
//IE 6+ in 'standards compliant mode'
myHeight = document.documentElement.clientHeight;
} else if( document.body && ( document.body.clientHeight ) ) {
//IE 4 compatible
myHeight = document.body.clientHeight;
}
return myHeight;
}
//---------------------------------------------------------------------------
function scaleArea() { // using values stored at load, recalculate new values for the current size
var arrayAreas = document.body.getElementsByTagName("AREA" );
message = " "
for(var i = 0; i < arrayAreas.length; i++) {
ii=i+1;
rescaleX= document.getElementById("tclteam_s1" ).width/GLOBAL_WIDTH ;
rescaleY= document.getElementById("tclteam_s1" ).height/GLOBAL_HEIGHT ;
sarray=GLOBAL_AREAS[i].split("," ); // convert coordinates to a numeric array assuming comma-delimited values
var rarray =new Array();
for(var j = 0; j < sarray.length; j += 2) {
rarray[j]=parseInt(sarray[j])*rescaleX; // rescale the values
rarray[j]=Math.round(rarray[j]);
rarray[j+1]=parseInt(sarray[j+1])*rescaleY; // rescale the values
rarray[j+1]=Math.round(rarray[j+1]);
}
message = message + rarray.join("," ) + '\n';
arrayAreas[i].coords=rarray.join("," ); // put the values back into a string
GLOBAL_NEW_AREAS[i]= arrayAreas[i].coords;
}
// alert(rescaleX + " " + rescaleY + "\n" + GLOBAL_WIDTH + " " + GLOBAL_HEIGHT + "\n" + " GLOBAL_AREAS" + GLOBAL_AREAS + "\nSCALED AREAS" + message);
}
//||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
</script>
The following script here detects the browser window size. So I'm hoping to include this in the above so the image map will dynamically resize from the browser window size first:
<script type="text/javascript">
var winW = 630, winH = 460;
if (document.body && document.body.offsetWidth) {
winW = document.body.offsetWidth;
winH = document.body.offsetHeight;
}
if (document.compatMode=='CSS1Compat' &&
document.documentElement &&
document.documentElement.offsetWidth ) {
winW = document.documentElement.offsetWidth;
winH = document.documentElement.offsetHeight;
}
if (window.innerWidth && window.innerHeight) {
winW = window.innerWidth;
winH = window.innerHeight;
}
</script>
Is there a way to code this so it will read the browser window size first (using the code directly above), then load the image map accordingly?

Making DOM IE Friendly

How can I make this script IE friendly? The only parts that aren't IE friendly are the variables scrolledtonum and heightofbody...
function getheight() {
var myWidth = 0,
myHeight = 0;
if (typeof (window.innerWidth) == 'number') {
//Non-IE
myWidth = window.innerWidth;
myHeight = window.innerHeight;
} else if (document.documentElement && (document.documentElement.clientWidth || document.documentElement.clientHeight)) {
//IE 6+ in 'standards compliant mode'
myWidth = document.documentElement.clientWidth;
myHeight = document.documentElement.clientHeight;
} else if (document.body && (document.body.clientWidth || document.body.clientHeight)) {
//IE 4 compatible
myWidth = document.body.clientWidth;
myHeight = document.body.clientHeight;
}
var scrolledtonum = window.pageYOffset + myHeight + 2;
var heightofbody = document.body.offsetHeight;
if (scrolledtonum >= heightofbody) {
document.body.scrollTop = 0;
}
}
window.onscroll = getheight;
function func() {
window.document.body.scrollTop++;
}
window.document.onmouseover = function () {
clearInterval(interval);
};
window.document.onmouseout = function () {
interval = setInterval(func, 20);
};
var interval = setInterval(func, 20);
The mozilla MDN documentation for scrollY contains sample code for dealing with compatibility issues with pageYOffset: https://developer.mozilla.org/En/DOM/Window.scrollY.
It says the following:
For cross-browser compatibility, use window.pageYOffset instead of window.scrollY, except use
(((t = document.documentElement) || (t = document.body.parentNode)) && typeof t.ScrollTop == 'number' ? t : document.body).ScrollTop
when window.pageYOffset (and window.scrollY) is undefined.

Detecting and acting on scroll to bottom of page event

http://dabbler.org/home/asdf/scrolling/test.html
Does anyone see anything wrong with this code?
I can't figure out what is wrong with it, but my intentions are such that when the user hits the bottom of the page, the page scrolls to the top.
Thanks.
You missed a closing parenthesis:
function getheight() {
var myWidth = 0,
myHeight = 0;
if (typeof (window.innerWidth) == 'number') {
//Non-IE
myWidth = window.innerWidth;
myHeight = window.innerHeight;
} else if (document.documentElement && (document.documentElement.clientWidth || document.documentElement.clientHeight)) {
//IE 6+ in 'standards compliant mode'
myWidth = document.documentElement.clientWidth;
myHeight = document.documentElement.clientHeight;
} else if (document.body && (document.body.clientWidth || document.body.clientHeight)) {
//IE 4 compatible
myWidth = document.body.clientWidth;
myHeight = document.body.clientHeight;
}
var scrolledtonum = window.pageYOffset + myHeight - 16;
var heightofbody = document.body.offsetHeight;
if (scrolledtonum = heightofbody) {
alert('asdf!')
}
//???? } <--
Here is a working version with some code fixes: http://jsfiddle.net/maniator/8zhmg/
On your last line you have
if (scrolledtonum = heightofbody)
That should be
if (scrolledtonum == heightofbody)
Not sure if that'll be the problem though
Your missing a closing tag on your function! (at the very end!)
Argh.. #Neal beat me to it!

Detecting browser client area size on wide screen using javascript

I've been using the following code to detect browser client area width for ages and it wokred 100% with all browsers, including FF, Safari and various versions of IE. However, now when I switched to a new monitor with widescreen resolution (1280x800) this code fails on IE8. It reports clientwidth of 1024 !!!???
Any ideas how to get the correct client area width ?
function getClientWidth() {
var v=0,d=document,w=window;
if((!d.compatMode || d.compatMode == 'CSS1Compat') && !w.opera && d.documentElement && d.documentElement.clientWidth)
{v=d.documentElement.clientWidth;}
else if(d.body && d.body.clientWidth)
{v=d.body.clientWidth;}
else if(xDef(w.innerWidth,w.innerHeight,d.height)) {
v=w.innerWidth;
if(d.height>w.innerHeight) v-=16;
}
return v;
}
Non-jquery code I used some time ago:
function detectBrowserSize() {
var myWidth = 0, myHeight = 0;
if (typeof (window.innerWidth) == 'number') {
//Non-IE
myWidth = window.innerWidth;
myHeight = window.innerHeight;
} else if (document.documentElement && (document.documentElement.clientWidth || document.documentElement.clientHeight)) {
//IE 6+ in 'standards compliant mode'
myWidth = document.documentElement.clientWidth;
myHeight = document.documentElement.clientHeight;
} else if (document.body && (document.body.clientWidth || document.body.clientHeight)) {
//IE 4 compatible
myWidth = document.body.clientWidth;
myHeight = document.body.clientHeight;
}
alert(myWidth + ' - ' + myHeight)
}
The bits in your code where you check for window.opera and subtract 16 pixels are worrying. comp.lang.javascript's FAQ has a decent implementation of this.

Categories