如何将参数传递给脚本标签?


89

我读了教程DIY小部件-如何将您的网站嵌入另一个由Nic博士制作的XSS小部件网站

我正在寻找一种将参数传递给脚本标签的方法。例如,要进行以下工作:

<script src="http://path/to/widget.js?param_a=1&amp;param_b=3"></script>

有没有办法做到这一点?


两个有趣的链接:


Answers:


118

我为回答一个过时的问题表示歉意,但是在花了一个小时的时间解决上述解决方案后,我选择了更简单的方法。

<script src=".." one="1" two="2"></script>

在上面的脚本里面:

document.currentScript.getAttribute('one'); //1
document.currentScript.getAttribute('two'); //2

比jQuery或URL解析容易得多。

您可能需要@Yared Rodriguez针对IE的答案中的doucment.currentScript的polyfil:

document.currentScript = document.currentScript || (function() {
  var scripts = document.getElementsByTagName('script');
  return scripts[scripts.length - 1];
})();

5
请注意,currentScript在IE中不起作用。详细信息
Dehli 2015年

我确实在答案中为IE添加了polyfill。填充胶不起作用吗?
理查德·福克斯

2
polyfill不再起作用,document.currentScript是只读的,如果已经存在,则无法分配。也许像if(!document.currentScript){***
polyfill

2
抱歉,大卫,我总是使回答变得通用,以便其他人可以使用该解决方案,而不会将最初的实现细节添加到问题中。在上面的示例中,您可以看到src="..."这意味着任何src都没关系:)
理查德·福克斯

1
@RichardFox感谢您的回答,但只需要评论“不回答原始问题:不使用path / to / widget.js”,这可能是我整周阅读的最有趣的东西!简直不敢相信你的回答和你做的一样好。
Skintest

63

最好在html5 5数据属性中使用功能

<script src="http://path.to/widget.js" data-width="200" data-height="200">
</script>

在脚本文件http://path.to/widget.js中,您可以通过以下方式获取参数:

<script>
function getSyncScriptParams() {
         var scripts = document.getElementsByTagName('script');
         var lastScript = scripts[scripts.length-1];
         var scriptName = lastScript;
         return {
             width : scriptName.getAttribute('data-width'),
             height : scriptName.getAttribute('data-height')
         };
 }
</script>

如果该ID =“myAwesomeWigretNo1”不是alwas这样的,但myAwesomeWigretNo2,还是myAwesomeWigretNo681??? 如何解决此问题以接受实数变量?
Pathros

9
值得一提的是,还有其他方法可以引用脚本,例如document.currentScript(仅适用于不在自己文件中的脚本),然后id<script>标记上放置一个,然后通过该标记查找它。
Thunderforge

而且,如果您的团队中的其他程序员更改了ID,却又不知道您使用了此ID,该怎么办?
OBender '16

1
如果您异步加载脚本,那么我建议使用ID是唯一可靠的选择。谢谢@Thunderforge ...而且,任何程序员都应该避免重构代码,而没有适当的sprint计划,这是由对正在发生什么事情有线索的人所概述的;)
Luca Borrione

当然,您可以要求开发人员具有强大的道德操守,但从长远来看,它是行不通的...人们会忘记一些东西....在一个好的软件设计中,每个块都应隔离开, awesome-pixels.tumblr.com/post/101930002170 / ...... en.wikipedia.org/wiki/SOLID_(object-oriented_design) 所以,我不认为这是一个好VS坏的解决方案,它只是更复杂相较于未保持:-)是你没有计划,以维持ID的加载脚本异步我认为没有理由使用ID加载
-OBender

17

得到它了。有点hack,但效果很好:

var params = document.body.getElementsByTagName('script');
query = params[0].classList;
var param_a = query[0];
var param_b = query[1];
var param_c = query[2];

我将script标记中的params作为类传递:

<script src="http://path.to/widget.js" class="2 5 4"></script>

这篇文章很有帮助。


1
这篇文章很棒!
Bartek Skwira 2014年

14
应该使用类来设计元素的样式,以不传递参数。
kspacja 2015年

5
@kspacja是的,HTML和HTML应该只包含没有样式的内容,除非我们必须为浮点和列布局精确地排序DIV标签,因为CSS不能真正完成这项工作,因此我们可以做到这一点。我说,别客气。但是,如果您想避免冲突,或者您不愿意为此而入睡,则可以使用“ data-”属性。
杰森C

13

另一种方法是使用元标记。可以将应传递给JavaScript的所有数据分配如下:

<meta name="yourdata" content="whatever" />
<meta name="moredata" content="more of this" />

然后可以像这样从meta标签中提取数据(最好在DOMContentLoaded事件处理程序中完成):

var data1 = document.getElementsByName('yourdata')[0].content;
var data2 = document.getElementsByName('moredata')[0].content;

绝对不需要jQuery之类的麻烦,没有必要的技巧和变通办法,并且可以与支持元标记的任何HTML版本一起使用...


我认为这种方法是迄今为止所有方法中最简单的方法。它就像一种魅力,可以为我提供所需的一切。伟大的问题和奇妙的解决方案!
arios

10

jQuery可以将参数从HTML传递到javascript:

把它放在myhtml.html文件中:

<!-- Import javascript -->
<script src="//code.jquery.com/jquery-1.11.2.min.js"></script>
<!-- Invoke a different javascript file called subscript.js -->
<script id="myscript" src="subscript.js" video_filename="foobar.mp4">/script>

在同一目录中创建一个subscript.js文件,并将其放在此处:

//Use jquery to look up the tag with the id of 'myscript' above.  Get 
//the attribute called video_filename, stuff it into variable filename.
var filename = $('#myscript').attr("video_filename");

//print filename out to screen.
document.write(filename);

分析结果:

加载myhtml.html页面时,会在屏幕上显示“ foobar.mp4”。名为video_filename的变量已从html传递到javascript。Javascript将其打印到屏幕上,并显示为嵌入到父HTML中。

jsfiddle证明以上方法有效:

http://jsfiddle.net/xqr77dLt/


7

如果使用的是jquery,则可能要考虑其数据方法。

我使用了与您在响应中尝试的类似的方法,但是像这样:

<script src="http://path.to/widget.js" param_a = "2" param_b = "5" param_c = "4">
</script>

您还可以创建一个函数,让您直接获取GET参数(这是我经常使用的函数):

function $_GET(q,s) {
    s = s || window.location.search;
    var re = new RegExp('&'+q+'=([^&]*)','i');
    return (s=s.replace(/^\?/,'&').match(re)) ? s=s[1] : s='';
}

// Grab the GET param
var param_a = $_GET('param_a');

4

我知道这是一个非常老的线程,但是如果有人一旦找到解决方案就来到这里,这可能也会有所帮助。

基本上,我使用document.currentScript来获取代码运行所在的元素,然后使用要查找的变量名进行过滤。我使用名为“ get”的方法扩展了currentScript,因此我们可以使用以下方法在该脚本中获取值:

document.currentScript.get('get_variable_name');

这样,我们可以使用标准URI来检索变量,而无需添加特殊属性。

这是最终代码

document.currentScript.get = function(variable) {
    if(variable=(new RegExp('[?&]'+encodeURIComponent(variable)+'=([^&]*)')).exec(this.src))
    return decodeURIComponent(variable[1]);
};

我当时忘记了IE :)没那么容易。。。我没有提到document.currentScript是HTML5属性。尚未将其用于不同版本的IE(我在IE11之前进行了测试,但尚未发布)。为了实现IE兼容性,我将以下部分添加到了代码中:

document.currentScript = document.currentScript || (function() {
  var scripts = document.getElementsByTagName('script');
  return scripts[scripts.length - 1];
})();

我们在这里要做的是为IE定义一些替代代码,该代码返回当前的脚本对象,这是解决方案中从src属性提取参数所必需的。由于存在一些局限性,因此这不是IE的完美解决方案。如果脚本是异步加载的。较新的浏览器应包含“ .currentScript”属性。

希望对您有所帮助。


3

多亏了jQuery,一个简单的HTML5兼容解决方案是创建一个额外的HTML标签(例如div)来存储数据。

HTML

<div id='dataDiv' data-arg1='content1' data-arg2='content2'>
  <button id='clickButton'>Click me</button>
</div>

JavaScript

$(document).ready(function() {
    var fetchData = $("#dataDiv").data('arg1') + 
                    $("#dataDiv").data('arg2') ;

    $('#clickButton').click(function() {
      console.log(fetchData);
    })
});

使用上面的代码进行实时演示:http : //codepen.io/anon/pen/KzzNmQ?editors=1011#0

在现场演示中,您可以看到来自HTML5 data- *属性的数据,这些数据将被连接并打印到日志中。

资料来源:https : //api.jquery.com/data/


1
通过了其他一些解决方案,但这是效果最好的解决方案,而且实施起来也很简单。谢谢!
Erik Kalkoken'2

这应该是公认的解决方案,因为它允许您按ID引用脚本,并且是有效的HTML5。
蒂姆·S

2

将您需要的值放在其他脚本可以检索它们的位置,例如隐藏的输入,然后在初始化新脚本时从它们的容器中提取这些值。您甚至可以将所有参数作为JSON字符串放入一个隐藏字段中。


谢谢回答。这些参数实际上是由用户(将脚本标签嵌入其代码中)输入的。然后怎样呢?
Tomer Lichtash 2011年

如果您无法同时控制两个客户端/服务器脚本,那么我唯一想到的就是获取用户输入并使用它来生成一个特定的.js文件,并在其中嵌入他们的输入,这就是假设您可以控制收集和处理他们的输入。
2011年

没有回答原始问题:没有任何形式可保存“隐藏”字段时,将参数放在哪里?
David Spector '18

2

创建一个包含参数列表的属性,如下所示:

<script src="http://path/to/widget.js" data-params="1, 3"></script>

然后,在您的JavaScript中,以数组形式获取参数:

var script = document.currentScript || 
/*Polyfill*/ Array.prototype.slice.call(document.getElementsByTagName('script')).pop();

var params = (script.getAttribute('data-params') || '').split(/, */);

params[0]; // -> 1
params[1]; // -> 3

这种方法有什么缺点?
Tronathan

@Tronathan这种方法没有真正的缺点,并且其中包含一个polyfill以提供更好的浏览器支持。我在这里看到的唯一缺点是不能在参数中包含逗号,这通常不是问题,您可以通过将分隔符更改为您不打算使用的字符来弥补这一点。
神秘

2

我想要的解决方案要尽可能多地支持旧浏览器。否则,我会说currentScriptdata属性方法将是最时尚的。

这是这里尚未提出的仅有的这些方法。特别是,如果由于某种原因您拥有大量数据,那么最好的选择可能是:

本地存储

/* On the original page, you add an inline JS Script: */
<script>
   localStorage.setItem('data-1', 'I got a lot of data.');
   localStorage.setItem('data-2', 'More of my data.');
   localStorage.setItem('data-3', 'Even more data.');
</script>

/* External target JS Script, where your data is needed: */
var data1 = localStorage.getItem('data-1');
var data2 = localStorage.getItem('data-2');
var data3 = localStorage.getItem('data-3');

localStorage具有完整的现代浏览器支持,并且令人惊讶的是,它对旧版本的浏览器也提供了很好的支持,最早支持IE 8,Firefox 3,5和Safari 4。

如果您没有大量数据,但仍需要广泛的浏览器支持,则最好的选择是:

元标记[由Robidu]

/* HTML: */
<meta name="yourData" content="Your data is here" />

/* JS: */
var data1 = document.getElementsByName('yourData')[0].content;

这样做的缺点是,将meta标记[直到HTML 4]放置在head标记中的正确位置,并且您可能不希望在此处放置这些数据。为避免这种情况,或将meta标签放入正文,您可以使用:

隐藏的段落

/* HTML: */
<p hidden id="yourData">Your data is here</p>

/* JS: */
var yourData = document.getElementById('yourData').innerHTML;

为了获得更多浏览器支持,您可以使用CSS类而不是hidden属性:

/* CSS: */
.hidden {
   display: none;
}

/* HTML: */
<p class="hidden" id="yourData">Your data is here</p>

2

这是jQuery 3.4的解决方案

<script src="./js/util.js" data-m="myParam"></script>
$(document).ready(function () {
    var m = $('script[data-m][data-m!=null]').attr('data-m');
})
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.