'light loader' question

P

Paul Gorodyansky

Hi,

User call my Virtual Keyboard by pressing a button. But many user may never need it,
so I don't want to load 100k of JavaScript code _when page is being loaded_ -
I want to load my JavaScript code only when a person clicks that button -
is it possible?


<head>
....
/* very small .js with variables initiation and v_load() function */
<script type="text/javascript" src="Vk_init.js"></script>
....
</head>
<body>
....
<button id="vk" onclick="v_load(); v_showKbd">Virtual Keyboard</button>
....


v_load() loads all 100k of JavaScript - v_code.js file -
including the function v_showKbd()

But whatever I do, button click produces JavaScript error -
"v_showKbd is undefined" - as well as any variable initiated in v_code.js
if say I place alert() with it into the same button's code

So how to make v_load()-produced stuff be known to the JavaScript in the same
button?
If I load v_code.js in <head> then, surely, v_showKbd() on a button click
works just fine, but I don't want to load 100k v_code.js such way -
it may never be needed...


I tried these two approaches for v_load() which loads v_code.js but both of them failed,
that is, still get JavaScript error "v_showKbd undefined" when click the button:


1) v_load() runs and adds a child to <BODY> which loads .js file:

v_bobj = document.getElementsByTagName('body')[0];
script1 = document.createElement('script');
script1.type = 'text/javascript';
script1.src = "v_code.js";
v_bobj.appendChild(script1);

That is, a child like
<script type="text/javascript" src="v_code.js"></script>


Nope. I tried the same with adding such child to <head> object - same negative result -

that is, v_code.js _is_ loaded - I placed alert("***"); there at the top, BUT its
functions and variables are unknown in the Button's onclick() code -
I press the button and get "v_showKbd() is undefined


2) Tried to add in v_load() that not as DOM object but as HTML using existing (empty)
<div id="v_divTmp">:


v_tmp = document.getElementById("v_divTmp");
v_add = "<scri"+"pt type='text/javascript' src='v_code.js'></scr"+"ipt>";

v_tmp.innerHTML=v_add;

Same negative result - "v_showKbd is undefined

(side note: and this time looks like v_code.js was not loaded at all -
its alert("**"); did not work).



Any suggestions? Should be kind of common issue, I guess...
 
P

Paul Gorodyansky

Just to clarify - I want variables and function of the freshly loaded (via DOM way) v_code.js
be known in the _same_ button's code, but it is not known:

<button id=B1 type="button onclick="v_load(); alert(v_VarFromLoadedJs); v_showKbd()">Vk</button>

produces "v_VarFromLoadedJs is undefined v_showKbd is undefined"


If I try to use variables or functions of that dynamically loaded .js _later_, say
in another button's code, then it's fine, everything works:

<button id=B2 .onclick = "alert(v_VarFromLoadedJs); v_showKbd()">Another button</button>

but it's not what I need...
 
V

Vince Morgan

Paul Gorodyansky said:
Hi,

User call my Virtual Keyboard by pressing a button. But many user may never need it,
so I don't want to load 100k of JavaScript code _when page is being loaded_ -
I want to load my JavaScript code only when a person clicks that button -
is it possible?
The code below will allow you to load a script conditionaly, and it should
parse as if it were included on startup.

If (condition)
{
var script=document.createElement("script");
script.type="text/javascript";
script.src="YourJS.js";
document.getElementsByTagName("head")[0].appendChild(script);
}

HTH
Vince Morgan
 
F

Frederik Vanderstraeten

Paul Gorodyansky schreef:
Hi,

User call my Virtual Keyboard by pressing a button. But many user may never need it,
so I don't want to load 100k of JavaScript code _when page is being loaded_ -
I want to load my JavaScript code only when a person clicks that button -
is it possible?


<head>
...
/* very small .js with variables initiation and v_load() function */
<script type="text/javascript" src="Vk_init.js"></script>
...
</head>
<body>
...
<button id="vk" onclick="v_load(); v_showKbd">Virtual Keyboard</button>
...


v_load() loads all 100k of JavaScript - v_code.js file -
including the function v_showKbd()

But whatever I do, button click produces JavaScript error -
"v_showKbd is undefined" - as well as any variable initiated in v_code.js
if say I place alert() with it into the same button's code

So how to make v_load()-produced stuff be known to the JavaScript in the same
button?
If I load v_code.js in <head> then, surely, v_showKbd() on a button click
works just fine, but I don't want to load 100k v_code.js such way -
it may never be needed...


I tried these two approaches for v_load() which loads v_code.js but both of them failed,
that is, still get JavaScript error "v_showKbd undefined" when click the button:


1) v_load() runs and adds a child to <BODY> which loads .js file:

v_bobj = document.getElementsByTagName('body')[0];
script1 = document.createElement('script');
script1.type = 'text/javascript';
script1.src = "v_code.js";
v_bobj.appendChild(script1);

That is, a child like
<script type="text/javascript" src="v_code.js"></script>


Nope. I tried the same with adding such child to <head> object - same negative result -

that is, v_code.js _is_ loaded - I placed alert("***"); there at the top, BUT its
functions and variables are unknown in the Button's onclick() code -
I press the button and get "v_showKbd() is undefined


2) Tried to add in v_load() that not as DOM object but as HTML using existing (empty)
<div id="v_divTmp">:


v_tmp = document.getElementById("v_divTmp");
v_add = "<scri"+"pt type='text/javascript' src='v_code.js'></scr"+"ipt>";

v_tmp.innerHTML=v_add;

Same negative result - "v_showKbd is undefined

(side note: and this time looks like v_code.js was not loaded at all -
its alert("**"); did not work).



Any suggestions? Should be kind of common issue, I guess...

The v_load function doesn't freeze until the script is loaded.
This happens:
I've also added a time to it, which isn't completely right but gives an
idea of what's happening when.
Function call: | What javascript does: | Time (in ms):
------------------+-----------------------------------+----------------
v_load(); | Puts script tag in document | 1
| Starts loading script | 2
| Doesn't freeze, but continues to | 2
| parse the next command |
v_showKbd(); | Tries to load keyboard and fails | 3
------------------+--------- A little later ----------+----------------
| The script is loaded | 1156
| v_showKbd exists now | 1157

So what you should do:
If you always want to call v_showKbd after loading v_code.js, put
v_showKbd at the end of the v_code.js file.
If you don't want this, write this code instead of v_showKbd();
v_loaded_callback = function(){ v_showKbd(); };
At the end of the v_code.js file, write:
v_loaded_callback();

If the callback function doesn't accept arguments, you could also just do:
v_loaded_callback = v_showKbd;
Instead of:
v_loaded_callback = function(){ v_showKbd(); };
 
P

Paul Gorodyansky

Jim Land said:
Don't call v_showKbd until v_load has finishe loading. Since you plan to
call v_load only when you need the keyboard displayed, why don't you just
put the v_showKbd call as the last line of v_load?

Thanks for the idea - I'll try that!
 
P

Paul Gorodyansky

Hi,

... it should parse as if it were included on startup.

This is exactly what I was looking for, just could not express as clear as you did -
yes, load .js on the button press and behave as it was inside <head> section.

I've already tried that - both with
document.getElementsByTagName("head")[0].appendChild(script);
and
document.getElementsByTagName("body")[0].appendChild(script);

The issue is that it does work as you described (I placed alert() there
to make sure it has been loaded and parsed) but next statement in the same
button onclick() code is unaware of that fact.
I need to try Jim's suggestion - I did not think about that - that may be
it's just a timing issue - .js was not fully loaded yet when next statement fires....
 
V

VK

Paul said:
User call my Virtual Keyboard by pressing a button. But many user may never need it,
so I don't want to load 100k of JavaScript code _when page is being loaded_ -
I want to load my JavaScript code only when a person clicks that button -
is it possible?


<head>
...
/* very small .js with variables initiation and v_load() function */
<script type="text/javascript" src="Vk_init.js"></script>
...
</head>
<body>
...
<button id="vk" onclick="v_load(); v_showKbd">Virtual Keyboard</button>
...


v_load() loads all 100k of JavaScript - v_code.js file -
including the function v_showKbd()

But whatever I do, button click produces JavaScript error -
"v_showKbd is undefined" - as well as any variable initiated in v_code.js
if say I place alert() with it into the same button's code

Unlike Java, JavaScript doesn't have synchronized modifier and
respectively synchronized methods - with the exception of
XMLHttpRequest.

So after having executed v_load()- right after that it attempts to
execute v_showKbd from that library. While DOM update caused by
v_load() takes only 100-200ms, the actual library load and parsing may
take several seconds or more - heavily dependant on the connection
speed and the system performance.

There is nothing reliable you can do with the current architecture. If
the changes listed below are too troublesome then simply leave it as it
is (with all libraries loaded right away). I'm mentioning the update
troubles because I happened to know your virtual keyboard and I know
that - with numerous consecutive updates and compatibility fixes - it
exists for a decade by now.

1) In your library add v_showKbd() call as the very last line:

// functions

function v_showKbd() {
// ...
}

// even more functions

v_showKbd();

This way after the library is successfully loaded and parsed on the
last statement it will execute the newly obtained v_showKbd function.

2) On your page
<button id="vk" onclick="v_load(); v_showKbd()">Virtual
Keyboard</button>
has to be replaced by:
<button id="vk" onclick="v_load();">Virtual Keyboard</button>

3) v_load has to be remodeled in order to:
i) start loading the library (this is already implemented I guess)
ii) give to the user a visual feedback that her click is not ignored
but that something important is going on. The simplest could be a
message in the textarea, more friendly and noticeable would be a
"popup" DIV with a message.
iii) prevent user from keep adding <script> block by pressing the
button. The actual load of a 100Kb .js may take up to 7 seconds - from
my experience with GSM modem during my stay in Europe last summer. At
the same time the "speeding things up" by torturing links and buttons
is the most common (mis)behavior of an average user. This way some
true/false flag to execute methods only on the first call is an
absolute must wherever a noticeable delay may be expected.

4) v_showKbd in your library has to be remodeled so besides other
things it would remove "Loading..." message from the screen (placed in
there on the step 3.ii

P.S. Another approach could be over synchronous XHR call with further
eval() of the retrieved code. IMO that is overkill for the given
situation plus it uglies up and complicates things w/o any need. In any
case a visual feedback has to be provided to your user during the call.
 
P

Paul Gorodyansky

Hi,

Thanks for the suggestions!

No my Virtual Keyboard does not exist for a decade :) -
I started to develop it in the middle of 2003 - was waiting until Mozilla
let me to catch a key pressed and replace with what I want -
IE-only Keyboard were already available so it was no reason to build just
another one.
I was watching this news conference (and posted that question about
Mozilla from time to time) until saw here in the Summer of 2003 that
it's finally implemented in Mozilla 1.03

I can see now that I may be able to use already existing
"Wait... Keyboard is loading" feature - I did it because even
v_showKbd() inscludes some HTML generated on the fly so slower
computers and/or slower Internet connections could reveal that delay.
And yes, after it's over, I am removing that "Wait..." message.
But may be I'l do a separate message as you suggested -
"popup" DIV - to have it more visible, it would be better...

True/false flag to prevent load function excute multiple times if user
keeps clicking is also already there -
though I did it for diferrentl reason (did not think aboiut such user's actions -
thanks for pointing to this):
load has to be done only once so next normal button click should not
invoke it - so I made that true/false flag
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,766
Messages
2,569,569
Members
45,045
Latest member
DRCM

Latest Threads

Top