繁体   English   中英

如何将参数传递给匿名Javascript函数?

[英]How do I pass argument to anonymous Javascript function?

我正在编写一个简单的计数器,并且我想使用户的安装非常简单。 我见过的最简单的计数器代码(针对安装它的用户)之一是Google Analytics(分析)代码

因此,我想将主要代码存储在文件中,要安装我的计数器的用户只需设置如下的websiteID:

<html><head><title></title></head><body>
<script type="text/javascript" src="http://counterhost.lan/tm.js">
var websiteId = 'XXXXX';
</script>
</body></html>

这是我的代码:

<script type="text/javascript" src="http://counterhost.lan/tm.js">
var page = _gat.init('new');
</script>

这是我的JS文件:

(function() {
    var z = '_gat';
    var aa = function init(data) { alert(data); alert(z);};

    function na() {
        return new z.aa();
    }
    na();
})();

我试图了解Google Analytics(分析)的javascript代码,但未能做到这一点。 谁能建议我如何指定标签之间的变量,然后以javascript文件中的匿名函数读取它? 谢谢。

在您的示例中, websiteId是全局变量。 因此它可以在任何地方访问,包括匿名函数,除非有一个同名的局部变量

<script> var websiteId = "something"; </script>

稍后在页面或包含的js文件中...

(function() {
    alert(websiteId); //this should work
})();

谁能建议我如何指定标签之间的变量,然后读取它[...]

如果您的标签同时具有SRC属性和JS内容,则不会。

<script type="text/javascript" src="http:/x.com/x.js"></script>

..与...不同,

<script type="text/javascript">
    var x = 1;
</script>

Dojo是一个可以向JSRIPT标签添加JS变量的框架。 因此,如果您使用的是Dojo,则可以通过编写以下代码将变量添加到全局djConfig哈希中:

<script type="text/javascript" src="mxclientsystem/dojo/dojo.js"
    djConfig="
    usePlainJson: true,
    parseOnLoad: true
">
</script>

Dojo通过运行SCRIPT标记并评估自定义djConfig属性来完成此操作。

但是,这不能解决您的问题。

您确实需要两个SCRIPT标签。 有一句话,

<script type="text/javascript">
    var websiteId = '123456';
</script>

这将设置一个全局变量websiteId和另一个,

<script type="text/javascript" src="http:/x.com/myreporter.js"></script>

可以从任何地方加载并读取websiteId变量,我假设将其报告回来。

您可以像这样将变量传递给匿名函数:

(function(arg1, arg2, arg3) {
    alert(arg1);
    alert(arg2);
    alert(arg3);
})("let's", "go", "redsox");

// will alert "let's", then "go", then "redsox" :)

我不清楚您要问什么,但是...

您可以使用id属性标记任何HTML元素,然后使用
document.getEntityById()以检索该特定元素。

您还可以给HTML元素用户定义的属性具有自己选择的名称,然后在Javascript中为该元素获取并设置它们。

我认为您对JS对象的调用方式有些困惑。

z是字符串'_gat' 您不能在其上调用aa() ,因为字符串没有名为aa成员。 aa是存储在局部变量中的独立函数。 即使您确实调用了aa() ,它也不会返回任何内容,因此对结果使用new运算符是没有意义的。 new只能在构造函数上调用。

我猜你的意思是这样的:

var _gat= function() {

    // Private variable
    //
    var data= null;

    // Object to put in window._gat
    //
    return {

        // Set the private variable 
        //
        init: function(d) {
            data= d;
        }
    };
}();

然后像第二个示例中那样调用_gat.init('foo')会将变量设置为网站_gat.init('foo') 'foo' 之所以_gat是因为_gat对象是在匿名函数内定义的return {init: function() {...}}对象,并在隐藏的data变量上保留了引用(“ closure”)。

如果您将src属性指定为script元素的一部分,则script元素标签本身内的任何代码都不会执行。 但是,您可以使用以下代码添加此功能。 我从Crockford(我相信是他)那里获得了这项技术,他在演讲中谈到了无关的主题,即渲染性能,并为此目的将脚本异步加载到页面中。

JavaScript:

(function() {
    // Using inner class example from bobince's answer
 var _gat = (function() {
     var data= null;

     return {
         init: function(d) {
          console.info("Configuration data: ", d);
             data = d;
         }
     }
 })();

 // Method 1: Extract configuration by ID (SEE FOOT NOTE)
 var config = document.getElementById("my-counter-apps-unique-and-long-to-avoid-collision-id").innerHTML;

 // Method 2: search all script tags for the script with the expected name
 var scripts = document.getElementsByTagName("script");

 for ( var i=0, l=scripts.length; i<l; ++i ) {
  if ( scripts[i].src = "some-script.js" ) {
   config = scripts[i].innerHTML;
   break;
  }
 }

 _gat.init( eval("(" +config+ ")") );
})();

HTML:

<script type="text/javascript" src="some-script.js" id="my-counter-apps-unique-and-long-to-avoid-collision-id">
 {some: "foo", config: "bar", settings: 123}
</script>

两种方法都有其缺点:

  1. 使用唯一且不会冲突的ID将使确定正确的脚本元素更加准确和快捷; 但是,这不是有效的HTML4 / XHTML标记。 在HTML5中,您可以定义任意属性,因此在那时不会有问题

  2. 此方法是有效的HTML标记; 但是,如果您的网址可能更改(例如:http vs https),那么我展示的简单比较可能会很容易中断,并且可能需要一种更强大的比较方法

关于eval的注释

两种方法都使用eval 关于此功能的典型口头禅是“评估是邪恶的”。 然而,去与说使用eval 不知道的危险eval是邪恶的。

在这种情况下, script标记中包含的数据AFAIK不会受到注入攻击,因为在将HTML解析为DOM时,一旦到达该评估脚本(显示的代码),该脚本便立即执行。 先前可能已定义的脚本无法访问计数器的script标记中包含的数据,因为该节点在执行时就不在DOM树中。

可能的情况是,从先前包含的脚本执行的适时的setTimeout可能能够在计数器script的包含与评估时间之间的时间运行; 但是,情况可能会也可能并非如此,并且如果可能,取决于CPU负载等,情况可能会不一致。

如果您担心这个故事的寓意,请添加一个非eval的JSON解析器,然后改用它。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM