P
phocis
I wrote a pair of functions to enable scoped or referenced setTimeout
calls. I did this because I have an object factory that creates
multiple objects and those objects need to delay a few calls on
themselves at a certain point in time.
This code works fine for normal objects. However, my issue occurs if
at any point, an event object is passed across in IE.
It seems, that events methods and variables in IE are PRIVATE (!)
after the initial callstack has been finished.
The following is the code required to view this bug(?) in IE, and
success in FF.
<html>
<head>
<script>
/*****************************************
Here is the code for the delaying:
******************************************/
// Global variables.
var delayObjects = {}; // Hold the object references.
var delayObjectsIndex = 0; // Keep track of the index.
function delayObjectMethodCall(obj,exp,ms){
delayObjectsIndex++;
delayObjects[delayObjectsIndex] = obj; // This assigns
by reference.
// This is the eval that is to be run.
expNew = '\
if(delayObjects['+delayObjectsIndex+']){\
with(delayObjects['+delayObjectsIndex+']){\
'+exp+';\
}\
delayObjects['+delayObjectsIndex+'] =
undefined}\
';
document.getElementById('result').innerHTML = 'Delay
was called: (event.keyCode = '+obj.event.keyCode+')<br/
return delayObjectsIndex;
}
function delayObjectMethodCallCancel(id){
if(typeof id != 'undefined' && delayObjects[id]){
clearTimeout(id);
delayObjects[id] = undefined;
return true;
}
}
/*********************************************
* Onload
********************************************/
window.onload = function(){
document.getElementById('test').onkeydown=function(e){
if(!e){e=window.event;}
document.getElementById('result').innerHTML =
'Event was fired: (event.keyCode = '+e.keyCode+')<br/
'Before Delay: Input Value: '+this.value + '<br/
delayObjectMethodCall(
// Object To pass
{input:this,event:e,other:'staticObject'},
// String to eval
"\
document.getElementById('result').innerHTML = 'START OF DELAY
PAYLOAD<br/>'+document.getElementById('result').innerHTML;\
document.getElementById('result').innerHTML = 'After Delay: Input
Value: '+input.value + '<br/
document.getElementById('result').innerHTML = 'After Delay: Other
Value: '+other + '<br/>'+document.getElementById('result').innerHTML;\
try{\
document.getElementById('result').innerHTML = 'Event keyCode:
'+event.keyCode + '<br/>'+document.getElementById('result').innerHTML;
\
}catch(e){\
document.getElementById('result').innerHTML = '<span style=\"color:red
document.getElementById('result').innerHTML = '<span style=\"color:red
document.getElementById('result').innerHTML = '<span style=\"color:red
document.getElementById('result').innerHTML = 'END OF DELAY PAYLOAD<br/
100
);
return true;
}
}
</script>
</head>
<body>
<input id="test" type="text" value="change this somehow"/>
<input type="button" value="clear"
onclick="document.getElementById('result').innerHTML = '';"/>
<div id="result"></div>
</body>
</html>
calls. I did this because I have an object factory that creates
multiple objects and those objects need to delay a few calls on
themselves at a certain point in time.
This code works fine for normal objects. However, my issue occurs if
at any point, an event object is passed across in IE.
It seems, that events methods and variables in IE are PRIVATE (!)
after the initial callstack has been finished.
The following is the code required to view this bug(?) in IE, and
success in FF.
<html>
<head>
<script>
/*****************************************
Here is the code for the delaying:
******************************************/
// Global variables.
var delayObjects = {}; // Hold the object references.
var delayObjectsIndex = 0; // Keep track of the index.
function delayObjectMethodCall(obj,exp,ms){
delayObjectsIndex++;
delayObjects[delayObjectsIndex] = obj; // This assigns
by reference.
// This is the eval that is to be run.
expNew = '\
if(delayObjects['+delayObjectsIndex+']){\
with(delayObjects['+delayObjectsIndex+']){\
'+exp+';\
}\
delayObjects['+delayObjectsIndex+'] =
undefined}\
';
document.getElementById('result').innerHTML = 'Delay
was called: (event.keyCode = '+obj.event.keyCode+')<br/
setTimeout(expNew, ms);'+document.getElementById('result').innerHTML;
return delayObjectsIndex;
}
function delayObjectMethodCallCancel(id){
if(typeof id != 'undefined' && delayObjects[id]){
clearTimeout(id);
delayObjects[id] = undefined;
return true;
}
}
/*********************************************
* Onload
********************************************/
window.onload = function(){
document.getElementById('test').onkeydown=function(e){
if(!e){e=window.event;}
document.getElementById('result').innerHTML =
'Event was fired: (event.keyCode = '+e.keyCode+')<br/
document.getElementById('result').innerHTML ='+document.getElementById('result').innerHTML;
'Before Delay: Input Value: '+this.value + '<br/
// This is the call'+document.getElementById('result').innerHTML;
delayObjectMethodCall(
// Object To pass
{input:this,event:e,other:'staticObject'},
// String to eval
"\
document.getElementById('result').innerHTML = 'START OF DELAY
PAYLOAD<br/>'+document.getElementById('result').innerHTML;\
document.getElementById('result').innerHTML = 'After Delay: Input
Value: '+input.value + '<br/
'+document.getElementById('result').innerHTML;\
document.getElementById('result').innerHTML = 'After Delay: Other
Value: '+other + '<br/>'+document.getElementById('result').innerHTML;\
try{\
document.getElementById('result').innerHTML = 'Event keyCode:
'+event.keyCode + '<br/>'+document.getElementById('result').innerHTML;
\
}catch(e){\
document.getElementById('result').innerHTML = '<span style=\"color:red
\">Error: said:'+document.getElementById('result').innerHTML;\
document.getElementById('result').innerHTML = '<span style=\"color:red
\">Error: said:'+document.getElementById('result').innerHTML;\
document.getElementById('result').innerHTML = '<span style=\"color:red
}\\">Error: said:'+document.getElementById('result').innerHTML;\
document.getElementById('result').innerHTML = 'END OF DELAY PAYLOAD<br/
",<br/>'+document.getElementById('result').innerHTML;\
100
);
return true;
}
}
</script>
</head>
<body>
<input id="test" type="text" value="change this somehow"/>
<input type="button" value="clear"
onclick="document.getElementById('result').innerHTML = '';"/>
<div id="result"></div>
</body>
</html>