/    Sign up×
Community /Pin to ProfileBookmark

Finding a script’s parent element

Is there a way to determine the parent element that a script is in?

For example, if I had:

[CODE]<span><script type=”text/javascript” src=”script.js”></span>[/CODE]

could I identify the surrounding span and add some text within it (without giving the span an id)?

Thanks,

Pete

to post a comment
JavaScript

11 Comments(s)

Copy linkTweet thisAlerts:
@toicontienNov 19.2007 — As far as I know, there is no way to determine this. When SCRIPTs are run, they start out being run in reference to the window object, not the HTML tag the actual script is contained in, however you can do it via a roundabout way:

function getSCRIPTParent(src) {
var parent = null;
var scripts;
var i = 0;
var end = 0;
if (getSCRIPTParent.isSupported) {
scripts = document.getElementsByTagName('script');
for (i, end = scripts.length; i &lt; end; i++) {
if (scripts[i].src.indexOf(src) &gt; -1) {
parent = scripts[i].parentNode;
}
}
}
return parent;
}
getSCRIPTParent.isSupported = document.getElementsByTagName ? true : false;

This gets the parent node of a SCRIPT tag by passing getSCRIPTParent() the source of the SCRIPT tag (no JavaScript source code, but the value of the src attribute). You can pass a file name, or the full file path, and it will return a node reference to the SCRIPT tag's parent node for the first SCRIPT tag the function encounters with the passed source in the src attribute of the SCRIPT tag.

[code=html]<span><script type="text/javascript" src="function_lib.js"></script></span>[/code]
var scriptParent = getSCRIPTParent("function_lib.js");

alert(scriptParent);
Copy linkTweet thisAlerts:
@petewilliamsauthorNov 19.2007 — Thanks toicontien, that looks like a pretty handy workaround! Am I right in thinking that it will only work if there is just one instance of the script on the page? So if I placed the a second copy of the script further down the page, it would identify the first span rather than the second?

Pete
Copy linkTweet thisAlerts:
@toicontienNov 20.2007 — Actually looking at my code, it would identify the last instance. Let me modify that function:
function getSCRIPTParent(src) {
var parent = null;
var scripts;
var i = 0;
var end = 0;
if (getSCRIPTParent.isSupported) {
scripts = document.getElementsByTagName('script');
for (i, end = scripts.length; i &lt; end; i++) {
if (scripts[i].src.indexOf(src) &gt; -1) {
parent = scripts[i].parentNode;
i = end;
}
}
}
return parent;
}
getSCRIPTParent.isSupported = document.getElementsByTagName ? true : false;

Now it returns the first instance. Do you need a script that returns every instance? That would be plenty doable too.
Copy linkTweet thisAlerts:
@petewilliamsauthorNov 20.2007 — Ideally what I'd like is a script that can identify the span that the script is being called from within. So let's say I've got two copies of the same code on the page - the first time it is called it will identify the first span, and the second time it will identify the second span. I hope that makes sense!

Pete
Copy linkTweet thisAlerts:
@toicontienNov 20.2007 — It makes sense, but that's just not how JavaScript is set up. When a script first starts executing, it's executed within the scope of the window object, and may change scope as it executes. Events are executed within the scope of the DOM element in which the event originated. You cannot find the SCRIPT tag in which JavaScript code is being executed. That would be directly relating JavaScript with HTML, and they are separate. They are two different beasts.
Copy linkTweet thisAlerts:
@petewilliamsauthorNov 20.2007 — Ah ok fair enough, guess I'll have to come up with some sort of a workaround then! Thanks for your help anyway.

Pete
Copy linkTweet thisAlerts:
@toicontienNov 20.2007 — Can you post the script you're dealing with? We might be able to come up with a workaround.
Copy linkTweet thisAlerts:
@petewilliamsauthorNov 20.2007 — Hi toicontien, I've been having a play with it and I think I've come up with a workaround.

Basically what I've done is set up the spans with a title, then at the end of the body I call a script which pulls out all of the document's spans using getElementsByTagName, and then just edits the ones that have the correct title. For example:

[CODE]<html>
<body>

<p><span title="alterthisspan">This content will be altered</span>
<span>This content will remain the same</span></p>

<script type="text/javascript" src="script.js">
</body>
</html>[/CODE]


Then in the script.js file I have:

[CODE]var spans = document.getElementsByTagName('span');

for(var i=0; i<spans.length; i++)
{
if (spans[i].title == "alterthisspan")
{
spans[i].innerHTML = "This text has been changed";
}
}[/CODE]


That seems to do exactly what I want, and I can even pass parameters to the script by giving the span a title like "alterthisspan-123", and then extracting the "123" from the end in my script.

Pete

EDIT: The only downside I've just spotted is that when you hover over the span it displays the span's nonsense title... I suppose I could use the class attribute instead of title...
Copy linkTweet thisAlerts:
@toicontienNov 20.2007 — Why not use the class attribute? You can apply multiple classes to one HTML tag too.
&lt;span class="__alter __alter-123"&gt;&lt;/span&gt;
When using class names for scripting purposes, I always prepend them with two underscores. Class names that I use for styling don't ever start with the underscore character, and provides a handy way to keep my styling classes separate from the classes I use as flags in JavaScripts.
Copy linkTweet thisAlerts:
@petewilliamsauthorNov 20.2007 — Yeah I thought that might be a better idea (see edit above), but hadn't thought of putting underscores in front of the class name, which is definitely a clever way of making sure it doesn't conflict with anything else, thanks for the suggestion.

Pete
Copy linkTweet thisAlerts:
@UltimaterDec 10.2007 — Does this method look safe to use?

<i>
</i>&lt;body&gt;
&lt;span&gt;&lt;script type="text/javascript"&gt;
document.write("&lt;span&gt;&lt;/span&gt;");
var els=document.getElementsByTagName("span");
var e=els[els.length-1];
var thisScript=e.previousSibling;
e.parentNode.removeChild(e);//junk span dummy
alert(thisScript.nodeName);
&lt;/script&gt;&lt;/span&gt;
&lt;/body&gt;


Edit:

Eh forget it, might as well just test for the last SCRIPT tag.
<i>
</i>&lt;body&gt;
&lt;span&gt;&lt;script type="text/javascript"&gt;
e=document.getElementsByTagName("script");
alert(e[e.length-1])
&lt;/script&gt;&lt;/span&gt;
&lt;/body&gt;
×

Success!

Help @petewilliams spread the word by sharing this article on Twitter...

Tweet This
Sign in
Forgot password?
Sign in with TwitchSign in with GithubCreate Account
about: ({
version: 0.1.9 BETA 4.18,
whats_new: community page,
up_next: more Davinci•003 tasks,
coming_soon: events calendar,
social: @webDeveloperHQ
});

legal: ({
terms: of use,
privacy: policy
});
changelog: (
version: 0.1.9,
notes: added community page

version: 0.1.8,
notes: added Davinci•003

version: 0.1.7,
notes: upvote answers to bounties

version: 0.1.6,
notes: article editor refresh
)...
recent_tips: (
tipper: @Yussuf4331,
tipped: article
amount: 1000 SATS,

tipper: @darkwebsites540,
tipped: article
amount: 10 SATS,

tipper: @Samric24,
tipped: article
amount: 1000 SATS,
)...