Recommended search method for current script?

I am writing a script that should add DOM elements to the page where the script is located (a similar widget approach). What is the best way to do this?

Here are the methods I'm considering:

  • Include an element with id = "Locator" right above the script. Questions:
    • I don't like the extra markup
    • If I reuse the widget on the page, multiple elements will have the same Locator identifier. I was thinking of adding a line to the script to remove the identifier once used, but still ...
  • Add the id to the script. Questions:
    • although it works, id attribute is not valid for script element
    • same problem as above, multiple elements will have the same id if I reuse the script on the page.
  • Use getElementsByTagName ("script") and select the last item. This has worked for me so far, it just seems a little heavy, and I'm not sure if it is reliable (thinking about pending scripts).
  • document.write: not elegant, but seems to do the job.

  • [Edit] Based on the answer from idealmachine, I think of another option:

    • Include an attribute in the script tag, for example goal = "tabify".
    • Use getElementsByTagName ("script") to get all scripts.
    • Scroll through the scripts and check the goal = "tabify" attribute to find my script.
    • Remove the goal attribute in case there is another widget on the page.
  • [Edit] Another idea, also inspired by the answers:

    • Use getElementsByTagName ("script") to get all scripts.
    • Scroll through the scripts and check innerHTML to find my script.
    • At the end of the script, remove the script tag if there is another widget on this page.
+7
javascript dom document.write getelementsbytagname
source share
8 answers

I just found another method that seems to answer my question:

How to access parent iframe from javascript

Embedding a script in an iframe allows you to find it at any time, since the script always refers to its own window.

I believe this is the best approach, as it will always work no matter how many times you add a script to the page (think of widgets). You can comment.

What prompted me to consider iframes, first of all, it was an experiment that I did to create a Google gadget.

0
source share

This works with multiple copies of the same code on the page, as well as with dynamically inserted code:

<script type="text/javascript" class="to-run"> (function(self){ if (self == window) { var script = document.querySelector('script.to-run'); script.className = ''; Function(script.innerHTML).call(script); } else { // Do real stuff here. self refers to current script element. console.log(1, self); } })(this); </script> 
+4
source share

Out of the box: document.currentScript (not supported by IE)

+3
source share

I worked on OnlyWire , which provides a widget as the main service for posting on your site.

We use the trick var scripts = document.getElementsByTagName("script"); var thisScript = scripts[scripts.length - 1]; var scripts = document.getElementsByTagName("script"); var thisScript = scripts[scripts.length - 1]; , and it seems to work very well. Then we use thisScript.parentNode.insertBefore(ga, thisScript); to insert everything we want before it in the DOM tree.

I'm not sure I understand why you think this is a โ€œdifficultโ€ solution ... it does not include iteration, it is a purely cross-browser solution that integrates perfectly.

+1
source share

If you enter the <script> or <div class="mywidget"> , you will add something to the markup. Personally, I prefer the latter, since the script itself is added only once. Too many scripts in the page body can slow down the page load time.

But if you need to add a script tag where the widget will be, I donโ€™t see what is wrong with document.write() place the div.

+1
source share

Either document.write or selecting the last script element will work for synchronously loaded scripts on most web pages. However, there are some options that I can think of that you did not consider the ability to download async:

  • Adding a div with class="Locator" before the script. HTML classes have the advantage that duplicates are not invalid. Of course, to handle the multiple case of the widget, you will want to change the class name of the element when adding HTML elements so that you do not add them twice. (Note that an element can also be a member of several classes, this is a list separated by spaces.)

  • Checking the src each element in the script can ensure that the tracking code (for example, the tracking code for legacy Google Analytics code) and other scripts loaded at the very end of the page do not interfere with your script working correctly when using asynchronous loading. Again, in order to handle several cases of the widget, you may need to remove the script elements when they are with them (i.e. when the desired code is added to the page).


One final comment I will make (although you may already know about this) is that when coding the widget you need to declare all your variables with var and wrap all your code inside: (JSLint can help verify this)

 (function(){ ... })(); 

This is called a "self-executing function" and ensures that the variables used in your script will not interfere with the rest of the web page.

+1
source share

In many cases, this works well (hud.js is the name of the script):

 var jsscript = document.getElementsByTagName("script"); for (var i = 0; i < jsscript.length; i++) { var pattern = /hud.js/i; if ( pattern.test( jsscript[i].getAttribute("src") ) ) { var parser = document.createElement('a'); parser.href = jsscript[i].getAttribute("src"); host = parser.host; } } 
0
source share

You can also add an individual script name to them.

  • either inside some js-script

      dataset['my_prefix_name'] = 'someScriptName' 
  • or inside HTML - in the <script> tag

      data-my_prefix_name='someScriptName' 

and the following search is appropriate by going through the document.scripts array:

  ... function(){ for (var i = 0, n = document.scripts.length; i < n; i++) { var prefix = document.scripts[i].dataset['my_prefix_name'] if (prefix == 'whatYouNeed') return prefix } } 
0
source share

All Articles