I'm hesitant to answer my own question in this case because I don't have an answer that works 100% of the time, but I've ironed out the bugs enough to have a stable solution.
@Shef's answer is halfway to what I wanted/needed.
Generic JS Version:
function getActiveScript()
{
var s;
s=document.getElementsByTagName('script');
return s[s.length - 1];
}
The issue with the above code is that it will select the last script on the page no matter when it was executed. This is a major issue if the calling script was included after page load.
As I can't directly select the script
element (unless another solution presents itself), I'd rather not select anything if the script is being added after page load.
Pure JS Answer:
function getActiveScript()
{
var r,s;
r = document.readyState;
if ( r && r != 'complete' )
{
s = document.getElementsByTagName('script');
return s.length ? s[s.length - 1] : null;
}
return;
}
In the new version, document.readyState
is checked to make sure that the document hasn't finished loading. Additionally on browsers where document.readyState
isn't used, it will fail out (I can't think of any browsers that don't use document.readyState
these days).
One caveat to this solution is that it may be possible to dynamically insert a script
element into an earlier part of the document, which then gets executed before document.readyState
is 'complete'
. If the script were to use this code, it could possibly be referencing the wrong script
. I haven't checked this issue yet. Typically I add new script tags with document.body.appendChild
(or equivalent in a library), so it's not that big an issue to me.
Another possible loophole is if a new script has been appended to document.body
before getActiveScript
has been called. Again, I haven't tested it, but it may mean that the last selected script evaluates to on that's different than the one being executed.
Actual Usage:
The question was asked of why I wanted to select the currently evaluating script element. Although "Because I can" would probably be understood, I did have a legitimate reason to want to use this feature/functionality/dirty-nasty-hack.
I created a (couple) jQuery plugin(s) to do what I originally wanted.
jQuery Plugin: jquery.activescript.js
(function($){
"use strict";
$.activeScript = function(){
var r;
r=document.readyState;
return r && r != 'complete' ? $('script:last') : $();
};
})(jQuery);
jQuery Plugin: jquery.activescript.plugin.js
by default works for jQuery UI
(function($){
"use strict";
var plugins,d,p,$p;
d = $.activeScript().data();
plugins = d.plugins || 'draggable droppable resizable selectable sortable accordion autocomplete button datepicker dialog progressbar slider tabs';
plugins=plugins.split(' ');
$(function(){
while(p=plugins.pop())
{
$p=$(d[p+'Selector']);
if ($p[p])$p[p]();
}
});
})(jQuery);
The way you'd use jquery.activescript.plugin.js
is as follows:
<script type="text/javascript" src="jquery.activescript.plugin.js"
data-draggable-selector=".draggable.default"
data-droppable-selector=".droppable.default"
data-resizable-selector=".resizable.default"
data-selectable-selector=".selectable.default"
data-sortable-selector=".sortable.default"
data-accordion-selector=".accordion.default"
data-autocomplete-selector=".autocomplete.default"
data-button-selector=".button.default"
data-datepicker-selector=".datepicker.default"
data-dialog-selector=".dialog.default"
data-progressbar-selector=".progressbar.default"
data-slider-selector=".slider.default"
data-tabs-selector=".tabs.default"></script>
This would allow you to semantically tie in your default plugins to your page without having to muck about in a JS file. If non-defaults are needed, you should muck about in a JS file, so I haven't added any mechanism for specifying options (although a few plugins could really use it).
This same basic activescript
mechanism could be used by standalone plugins to have an easier way of overriding defaults.