getting <script> node from inside JS

G

GRotfl

Hi!

This question might be easy, but I am not even sure how to find the answer
on the Internet... I would appreciate some help.

I have this scenario:
....
<div>
<script type="text/javascript" src="test.js" /></script>
</div>
....

I would like the code in test.js to manipulate the node that it is called
from (for instance, set its background color to red).

Caveats:
- I can't use getElementById or similar because I don't control anything but
JS code (in other words, the code could be included from anywhere)
- test.js could be included in many places on the same page - each js should
manipulate only its parent and not parents of other JS includes.

So, I would need sth. like this:
var el=getThisNode.parentNode(); // not working of course

As said, I would appreciate some help, I'm really stuck here. Even "it can't
be done" would help, though I'm hoping of a different answer.

Kind regards!
 
M

Martin Honnen

GRotfl said:
I have this scenario:
...
<div>
<script type="text/javascript" src="test.js" /></script>
</div>
...

I would like the code in test.js to manipulate the node that it is called
from (for instance, set its background color to red).

Caveats:
- I can't use getElementById or similar because I don't control anything but
JS code (in other words, the code could be included from anywhere)
- test.js could be included in many places on the same page - each js should
manipulate only its parent and not parents of other JS includes.

So, I would need sth. like this:
var el=getThisNode.parentNode(); // not working of course

Does test.js at least contain code that is executed during page load? If
so you could try e.g.
var scripts = document.getElementsByTagName('script');
// during page load the current script element should
// be last in scripts
var lastScript = scripts[scripts.length - 1];
lastScript.parentNode.style.backgroundColor = 'red';
 
L

Lasse Reichstein Nielsen

GRotfl said:
I have this scenario:
...
<div>
<script type="text/javascript" src="test.js" /></script>

Generally you shouldn't use /> in HTML. It makes no difference (i.e.,
it's unnecessary), and if you don't know why you have added it, it
leads to errors like this one (in XHTML the above would be invalid,
since you try to end the script element twice).
So, generally don't use />, and on elements with an end tag, *never*
use it.
</div>
...

I would like the code in test.js to manipulate the node that it is called
from (for instance, set its background color to red).

What do you mean by "called from"? Code is executed by the browser, not by
particular elements.
Do you mean the div element that the script is contained in?
Caveats:
- I can't use getElementById or similar because I don't control anything but
JS code (in other words, the code could be included from anywhere)
- test.js could be included in many places on the same page - each js should
manipulate only its parent and not parents of other JS includes.
So, I would need sth. like this:
var el=getThisNode.parentNode(); // not working of course

As said, I would appreciate some help, I'm really stuck here. Even "it can't
be done" would help, though I'm hoping of a different answer.

Try:
function getThisNode() {
var scripts = document.getElementsByTagName("script");
return scripts[scripts.length - 1];
}

I haven't tested it in all browsers (just Firefox and Chrome), and you
should remember that the parent node has not been closed at the time
you access it.

/L
 
T

Thomas 'PointedEars' Lahn

Lasse said:
Generally you shouldn't use /> in HTML. It makes no difference (i.e.,
it's unnecessary),

It does make a difference.

<script ... /></script>

means

<script ...>&gt;</script>

in HTML which would be an ECMAScript syntax error; but apparently only a few
parsers honor that.


PointedEars
 
G

GRotfl

First of all, thank you for the answer, Martin!
Does test.js at least contain code that is executed during page load?

Yes, I can write anything I want in test.js. Even more, I can change the way
the test.js is called:

1. <div>
2. <script type="text/javascript" src="test.js" /></script>
3. </div>

Lines 1 and 3 are out of my control, but I can write anything in line 2, for
instance:
2a. <script>
2b. document.write('<scr'+'ipt type="text/javascript" src="test.js">' +
2c. '</script>');
If so you could try e.g.
var scripts = document.getElementsByTagName('script');
// during page load the current script element should
// be last in scripts
var lastScript = scripts[scripts.length - 1];
lastScript.parentNode.style.backgroundColor = 'red';

Is this cross-browser or could there be some race conditions? In other
words, is there a case when script loading is deferred?

I would expect browsers to load other elements even if the script is not
loaded yet, and in that case some other scripts might load before ours. But
I guess the scripts would be added in DOM tree right before they are
executed?


One idea I got in the mean time was this:
2a. var scr = document.createElement("script");
2b. scr.type="text/javascript";
2c. scr.src = "test.js";
2d. document.body.appendChild(scr);

And then in test.js:
scr.parentNode.style.backgroundColor='#ff0000';
(uses global variable scr)

Would this work? Is it cross-browser?

Thank you again, appreciate it! :)
 
G

GRotfl

Generally you shouldn't use /> in HTML. It makes no difference (i.e.,
...

Sorry, typo... Of course, I meant:
What do you mean by "called from"? Code is executed by the browser, not by
particular elements.
Do you mean the div element that the script is contained in?

Exactly. Not necessarily div, could be span, td, even body... I just need to
get a hold of it, then I'll work from there.
Try:
function getThisNode() {
var scripts = document.getElementsByTagName("script");
return scripts[scripts.length - 1];
}

I have had some doubts about this (in my answer to Martin) about
concurrency, but I think it is just my misunderstanding of how and when
scripts are called.

I'll try it, thanks!
I haven't tested it in all browsers (just Firefox and Chrome), and you
should remember that the parent node has not been closed at the time
you access it.

Hmmm... Thank you for this remark, I am not sure I would have thought of it.

Ok, I'll give it a try!

Again, thank you all, really appreciate it! :)
 
M

Martin Honnen

GRotfl said:
If so you could try e.g.
var scripts = document.getElementsByTagName('script');
// during page load the current script element should
// be last in scripts
var lastScript = scripts[scripts.length - 1];
lastScript.parentNode.style.backgroundColor = 'red';

Is this cross-browser or could there be some race conditions? In other
words, is there a case when script loading is deferred?

Unless you use <script defer type="text/javascript"
src="test.js"></script> and IE I don't see why the script loading should
be deferred. As for that approach being cross-browser you will need to
test, I looked into that some years ago to have a way in
application/xhtml+xml to replace document.write. For comparison I also
tested the approach in text/html and all browsers tested (Mozilla, IE,
Opera) behaved the same in text/html at that time. I did however not
test comlicated settings like one script element creating a new one.

One idea I got in the mean time was this:
2a. var scr = document.createElement("script");
2b. scr.type="text/javascript";
2c. scr.src = "test.js";
2d. document.body.appendChild(scr);

And then in test.js:
scr.parentNode.style.backgroundColor='#ff0000';
(uses global variable scr)

Would this work? Is it cross-browser?

If you do document.body.appendChild(scr) then that scr element ends up
as a child the body element so I don't see what that would gain you, in
that case scr.parentNode === document.body holds but what would you gain
that way?
 
G

GRotfl

var lastScript = scripts[scripts.length - 1];

Is this cross-browser or could there be some race conditions? In other
words, is there a case when script loading is deferred?

Unless you use <script defer type="text/javascript"
src="test.js"></script> and IE I don't see why the script loading should
be deferred. As for that approach being cross-browser you will need to

Thanks, I will implement it and I guess I'll see soon enough if there are
problems. :)
If you do document.body.appendChild(scr) then that scr element ends up
as a child the body element so I don't see what that would gain you, in
that case scr.parentNode === document.body holds but what would you gain
that way?

Ah, of course, stupid of me... :)

Ok, I'll use getElementsByTagName('script') approach then.

Thank you again for your help!!!
 

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

No members online now.

Forum statistics

Threads
473,756
Messages
2,569,540
Members
45,024
Latest member
ARDU_PROgrammER

Latest Threads

Top