3

I'm trying to create a script that will make it easier for users to use a custom button and I have something like

<script src="http://host.com/file.js?id=12345"></script>

What I wonder is how can I, in the file.js get that id parameter.

if I use document, it will get the original html page that has the script line and what I need is that id.

is there any way i can get that id successfully? What should be the scope?


added

the idea is that I can have several buttons in the page for example to have a small and simply list:

<ul>
    <li><script src="http://host.com/file.js?id=12345"></script></li>
    <li><script src="http://host.com/file.js?id=23456"></script></li>
    <li><script src="http://host.com/file.js?id=34567"></script></li>
</ul>

this will ultimately translate to

<ul>
    <li><a class="view40btn" href="#" data-id="12345"><strong>V40</strong> Watch the video</a></li>
    <li><a class="view40btn" href="#" data-id="23456"><strong>V40</strong> Watch the video</a></li>
    <li><a class="view40btn" href="#" data-id="34567"><strong>V40</strong> Watch the video</a></li>
</ul>

the list above will look like this in HTML:

enter image description here

My only issue is that I can't assign the correct id to the data-id attribute as this is generated in the file.js.


result

from Paulpro answer I got it working with his idea and knowing that the client will have much more scripts loaded and several with id's I changed it a bit for the final and working version:

var id = (function(){
    var scripts = document.getElementsByTagName('script');
    for(var i = 0, result = {}; i < scripts.length; i++)
        if(scripts[i].hasAttribute('data-viewfileid'))
            result['id'] = decodeURIComponent(scripts[i].getAttribute('data-viewfileid'));
    return result['id'];
})();

var html = '<a class="view40btn" href="#" data-id="' + id + '"><strong>V40</strong> Watch the video</a>';
document.write(html);

the script for the user would only be:

<script data-viewfileid="4444" src="file.js" type="text/javascript"></script>
Community
  • 1
  • 1
balexandre
  • 73,608
  • 45
  • 233
  • 342
  • 2
    Why would you put `script` tags inside of an unordered list? That is not semantically correct HTML. Are you looking to render templates on the client-side? – acconrad Jun 24 '13 at 18:41
  • it's an example... for example I can have a nice page talking about two videos and the developer wants to put two buttons in order the user see them, but they will have different id's... - This is a simple "easy to add button" script. – balexandre Jun 24 '13 at 18:46
  • 1
    Don't use HTML, create buttons dynamically from JS. That's how Facebook works - it creates the whole content dynamically. – Ivan Kuckir Jun 24 '13 at 18:48
  • But that example is flawed - you shouldn't be putting script tags inside of unordered lists. That's not what script tags were meant to do - you don't transform script tags into anchor tags, you have to create those buttons dynamically and load the script tags at the bottom of your page, see my answer for details. – acconrad Jun 24 '13 at 18:50

6 Answers6

1

You can put an ID on anything, including a script tag. So you can do something like this:

HTML:

<script id="myScript" src="http://host.com/file.js?id=12345"></script>

JS:

document.getElementById('myScript').src.split('=')[1]; to get the ID from that particular example string.

If that query string represents a timestamp (in which case you need the latest version) you can modify the JavaScript code to fetch the latest <script> tag like so:

var scripts = document.getElementsByTag('script');
var latestScriptId = scripts[scripts.length-1].src.split('=')[1];

EDIT: In the context of your new edit, you would then take latestScriptId and assign it to the data.id attribute corresponding to the button you would like to create...though again, semantically, it would just make more sense to use HTML's given id attribute, and additionally, since you are not using the href property for the anchor <a> tag, you're better off using a <button> element. So something like this would suffice:

var myButton = document.createElement('button');
myButton.className += 'view40btn';
myButton.id = latestScriptId;
acconrad
  • 3,201
  • 1
  • 22
  • 31
1

JavaScript doesn't know anything about the script tag that loaded it. However, there are a few workarounds.

If the file is being preprocessed on the server, you could make the server render the value in the response:

(function() {
  var id = <%= params.id %>;
  //other stuff here
}());

Or you could give the script tag an id, and make your code find it and pull out the URL.

HTML:

<script src="http://host.com/file.js?id=12345" id="myscript"></script>

JS:

var id = document.getElementById('myscript').split('id=')[1];

Or in modern browsers you could perhaps do something like this to find script tags that match where you know the script is.

var scriptTag = document.querySelector('script[src^="http://host.com/file.js"]');
var id = scriptTag.src.split('id=')[1];
Alex Wayne
  • 178,991
  • 47
  • 309
  • 337
  • I'm commenting same as in [acconrad](http://stackoverflow.com/users/535467/acconrad) answer: hat way I can't never have 2 buttons in the same page: question updated. – balexandre Jun 24 '13 at 18:38
  • @balexandre The first option here would work perfectly for multiple buttons, assuming you're using a server-side language (which I'm guessing you do, since you're using query parameters to fetch your scripts). – apsillers Jun 24 '13 at 18:40
  • @balexandre Then you are doing this wrong... Instead include one script, and have some placeholder nodes: `
    – Alex Wayne Jun 24 '13 at 18:52
  • @balexandre See my alternate answer which describes what you want to be doing, but does not answer the specific question you asked... – Alex Wayne Jun 24 '13 at 19:00
1

You can get the last script element on the page (which will always be the currently executing one):

var scripts = document.getElementsByTagName('script');
var s = scripts[scripts.length - 1];

Then modify one of the query string parsers from this question to work with that scripts src property:

var url = s.src;
var qs = url.substring(url.indexOf('?') + 1).split('&');
for(var i = 0, result = {}; i < qs.length; i++){
    qs[i] = qs[i].split('=');
    result[qs[i][0]] = decodeURIComponent(qs[i][2]);
}

That will give you an object containing all the query string properties on the current script. You can just access the properties like:

result['id']; // '12345'

In summary

To get the id parameter from within file.js, add the following code to the top of file.js:

var id = (function(){

    var scripts = document.getElementsByTagName('script');
    var s = scripts[scripts.length - 1];
    var qs = s.src.substring(s.src.indexOf('?') + 1).split('&');
    for(var i = 0, result = {}; i < qs.length; i++){
        qs[i] = qs[i].split('=');
        result[qs[i][0]] = decodeURIComponent(qs[i][3]);
    }

    return result['id'];
})();

Make sure it is not in any callback functions like a DOMReady callback.

Edit:

You can probably reduce your script to:

var scripts = document.getElementsByTagName('script');
var id = scripts[scripts.length - 1].getAttribute('data-viewfileid');

var html = '<a class="view40btn" href="#" data-id="' + id + '"><strong>V40</strong> Watch the video</a>';
document.write(html); 
Community
  • 1
  • 1
Paul
  • 139,544
  • 27
  • 275
  • 264
  • `(which will always be the currently executing one)` Won't this not be true if you have a function call to another JS file? – Colin DeClue Jun 24 '13 at 18:40
  • @ColinDeClue It has to be in the file `file.js` and outside of any functions. I added a note to the end of my answer. – Paul Jun 24 '13 at 18:42
  • I have modified the script as the developer html probably has much more scripts and some with `id` 's, but your idea is really good, I'll update my answer with the final script for future reference. Thank you! – balexandre Jun 24 '13 at 19:09
  • @balexandre You're welcome, please note that I updated my answer with a shortened script that I believe you can use, instead of the loop. – Paul Jun 24 '13 at 22:48
1

One more solution is to parse .js files with php interpreter. For example in apache configuration:

AddType application/x-httpd-php .js

And in JS:

alert('<?=$_GET["id"]?>');
drull
  • 481
  • 1
  • 3
  • 9
1

According to your clarifications, what you asking how to do is not what you want to do.

Instead, include one script, and have multiple placeholder nodes.

HTML:

<ul>
  <li class="mybutton" data-id="12345"></li>
  <li class="mybutton" data-id="23456"></li>
  <li class="mybutton" data-id="34567"></li>
</ul>
<script src="myscript.js"></script>

JS:

// myscript.js
var buttons = document.getElementsByClassName('mybutton');
for (var i = 0; i < buttons.length; i++) {
  var button = buttons[i];
  button.innerHTML = "my button html template here with id: "+ button.dataset.id;
}

See it work here: http://jsfiddle.net/zAdnB/

Alex Wayne
  • 178,991
  • 47
  • 309
  • 337
0

Javascript code does not "realise", that it is a part of some file. JS file is not "executable", there is no main method, which should be run after loading the file. You can not pass GET parameters to it - it is not clear how they should be interpreted.

In your HTML page, you should listen to "onload" method and then call the function from your file with your parameter.

Ivan Kuckir
  • 2,327
  • 3
  • 27
  • 46