getting <script> node from inside JS

Discussion in 'Javascript' started by GRotfl, Jul 18, 2009.

  1. GRotfl

    GRotfl Guest

    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!
     
    GRotfl, Jul 18, 2009
    #1
    1. Advertising

  2. GRotfl wrote:

    > 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';


    --

    Martin Honnen
    http://msmvps.com/blogs/martin_honnen/
     
    Martin Honnen, Jul 18, 2009
    #2
    1. Advertising

  3. GRotfl <> writes:

    > 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
    --
    Lasse Reichstein Holst Nielsen
    'Javascript frameworks is a disruptive technology'
     
    Lasse Reichstein Nielsen, Jul 18, 2009
    #3
  4. Lasse Reichstein Nielsen wrote:
    > GRotfl <> writes:
    >> 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),


    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
    --
    Prototype.js was written by people who don't know javascript for people
    who don't know javascript. People who don't know javascript are not
    the best source of advice on designing systems that use javascript.
    -- Richard Cornford, cljs, <f806at$ail$1$>
     
    Thomas 'PointedEars' Lahn, Jul 18, 2009
    #4
  5. GRotfl

    GRotfl Guest

    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>');
    2d. </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! :)
     
    GRotfl, Jul 18, 2009
    #5
  6. GRotfl

    GRotfl Guest

    >> <script type="text/javascript" src="test.js" /></script>
    >
    > Generally you shouldn't use /> in HTML. It makes no difference (i.e.,
    > ...


    Sorry, typo... Of course, I meant:
    <script type="text/javascript" src="test.js"></script>
    In my code it is correct. Good catch though! :)

    >> 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?


    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! :)
     
    GRotfl, Jul 18, 2009
    #6
  7. GRotfl wrote:

    >> 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?

    --

    Martin Honnen
    http://msmvps.com/blogs/martin_honnen/
     
    Martin Honnen, Jul 18, 2009
    #7
  8. GRotfl

    GRotfl Guest


    >>> 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. :)

    >> 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);

    >
    > 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!!!
     
    GRotfl, Jul 18, 2009
    #8
    1. Advertising

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

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. wolf
    Replies:
    0
    Views:
    578
  2. Replies:
    0
    Views:
    1,670
  3. Tjerk Wolterink
    Replies:
    2
    Views:
    1,521
    Dimitre Novatchev
    Aug 24, 2006
  4. Geagleeye

    how to creating new node inside a xml node

    Geagleeye, Aug 2, 2006, in forum: ASP General
    Replies:
    2
    Views:
    219
    Geagleeye
    Aug 3, 2006
  5. J M
    Replies:
    2
    Views:
    124
    Tad McClellan
    Nov 6, 2004
Loading...

Share This Page