tags:

views:

34

answers:

4

For example

<script>
function foo(){...}
</script>

<div><script>foo();</script></div>
<span><script>foo();</script></span>

and I wanted to have foo return "abc" when called from a div, return "123" when called from a span.

Is this possible?

A: 

No, this is not possible. You would have to manually pass some kind of parameter to identify where it was called from.

casablanca
A: 

There isn't a way to do this, script can be called in many different ways, there just isn't enough need for this to put it in the spec in any way.

I would imagine there's a much simpler way overall to do what you're trying to accomplish, embedding <script> inside individual elements and basing anything off the <script> element's location doesn't' seem like a sound approach.

So...what are you trying to ultimately accomplish here?

Nick Craver
Actually, it is possible.
SLaks
@SLaks - It's not, as the current element isn't closed yet you can't be sure of where you are (depending on the browser), for example `setTimeout(foo, 0);` would return...what?
Nick Craver
The ad manager currently used (baidu's ad manager) require an inline script where you want the ad to be placed. The script calls 'document.write' to place the ad on the page. Their server is quite slow when accessed from overseas and is slowing down the page. I'm hoping to be able to move all their stuff to the bottom of the page after everything else is loaded, but I can't figure out how to get content of the script's document.write into where the inline script was called.
CheapSteaks
@user482053 - Any chance of using an ad manager that *doesn't* rely on `document.write`? There are many issues with this, especially with page blocking, StackOverflow got rid of ads that relied on `document.write()` just a few weeks ago for the same reasons (problems/lag it introduces).
Nick Craver
Yeah, I really should try to get it switched
CheapSteaks
A: 

You can just get the last element currently in the DOM.

The code in an inline <script> block executes as the browser parses the page. Therefore, the last DOM element will be just before the script.

SLaks
Holy crap I can't believe this works. Would it work in IE6?
CheapSteaks
@CheapSteaks: I'm almost certain; try it.
SLaks
+1  A: 

After reading your comment I think you should do something else:

  1. create empty elements where your ads should appear (#ad1_empty, #ad2_empty, ...)
  2. place your ad code at the bottom of the page hidden (#ad1_full, #ad2_full, ...)
  3. when the document is ready, replace all empty elements with the real ones

// code

<div id="ad_empty"><!-- placeholder --></div>
<div id="ad_content" style="display: none;">
    <script src="[ad resource]"></script>
    <script>inline ad script</script>
</div>

<script>
function replace( oldel, newel, show ) {
  if ( typeof newel == "string" ) 
    newel = document.getElementById( newel );
  if ( typeof oldel == "string" ) 
    oldel = document.getElementById( oldel );
  if ( newel && oldel )
    oldel.parentNode.replaceChild( newel, oldel );
  if ( show ) 
    newel.style.display = "";
}

window.onload = function() {
    replace( "ad_empty",  "ad_content",  true );
    replace( "ad_empty2", "ad_content2", true );
};
</script>

It is possible to do what you originally wanted, btw (but it's useless)

function foo() {

  var scripts = document.getElementsByTagName("script");
  var parent = scripts[scripts.length-1].parentNode;
  var tag = parent.nodeName.toUpperCase();

  if (tag == "DIV") {
    alert("called from a <div>");
  } else if (tag == "SPAN") {
    alert("called from a <span>");
  }
}
galambalazs
That's a great idea, I'll probably go with this. Although I can't believe the second one works. How bad of a hack is it? Do you know if it'd work on IE6?
CheapSteaks
http://jsbin.com/igibu4/ it works with the input you've provided, but i wouldn't use it for anything serious. The first solution is widely used to improve page load time.
galambalazs