3

我正在尝试使用单击事件处理程序实现jQCloud词云。它需要我在 JSON 中传递一个 javascript 函数。

在 C# 中,我制作了动态 JSON 文本

foreach (var r in result)
{
    sbChart.Append("{\"text\": \"" + r.Key + "\", \"weight\": " + r.Count().ToString() + ", ");
    sbChart.Append("\"handlers\": { \"click\": \"function() { alert('You clicked " + r.Key + "');}\"}}, ");
}
if (sbChart.Length != 0)
{
    returnString = "[" + sbChart.ToString().Substring(0, sbChart.Length - 2) + "]";
}

我通过 web 方法将此返回到我的代码所在的 javascript

var words = JSON.parse(strJSON);
$('#div').jQCloud(words);

生成的 JSON 是

[
  {"text": "the", "weight": 111, "handlers": { "click": "function() { alert('You clicked the');}"}}, 
  {"text": "in", "weight": 66, "handlers": { "click": "function() { alert('You clicked in');}"}}
]

但是,由于我的函数是一个字符串,它不会作为对象执行。如果我在函数语句之前和之后删除双引号,它会Invalid Character在解析期间给我错误。

请任何人都可以帮助我如何使此警报起作用?

4

3 回答 3

3

如果您绝对必须以这种方式将函数传递给您的页面(请参阅下面的“但是”),您可以使用eval它,因为您是提供您将要使用的文本的人,eval它没有安全问题(并且速度问题不是问题,并且已经存在多年)。我不确定你想用这个函数做什么,但是例如:

$(".foo").on("click", eval(words[0].handlers.click));

...将评估函数并将结果分配为与.foo选择器匹配的元素上的单击处理程序。

但是,几乎可以肯定有一种更好的方式来构建事物。除了在 JSON 中传回函数,您可能在 JavaScript 中已经在某种映射中拥有这些函数:

var clickHandlers = {
    "the": function() { alert("You clicked the"); },
    "in": function() { alert("You clicked the"); }
};

...然后只需在您的 JSON 中给出密钥 ( "the", )。"in"

或者,假设它们与单击的内容相同,请从单击的元素中找出单击的内容(“the”或“in”)。

或者其他十几种东西中的任何一种,但它们的共同点是这些函数是在您的 JavaScript 代码中定义的,而不是通过 JSON 发回的,然后您通过 JSON 中的信息而不是 JSON中的实际函数来链接这些函数.

于 2015-04-18T08:16:11.357 回答
1

函数并不意味着作为 JSON 传递,执行数据调用传递的任意逻辑是一个相当大的安全问题。话虽如此,eval用来解决这个问题。

就像是

var action = eval(response[0].handlers.click); // evaluates the string as javascript, and returns the value, in this case a function.

action();
于 2015-04-18T08:15:54.700 回答
1

非常感谢大家以上的建议。但我最终使用了如何在 JQCloud 中提供点击处理程序的答案

我根据我的要求对其进行了一些修改,并且有效

var tag_list = new Array();
    var obj = GetCustomJsonObj(strJSON);
    for (var i = 0; i < obj.length; i++) {
        tag_list.push({
            text: obj[i].text,
            weight: obj[i].weight,
            //link: obj[i].link,
            handlers: {
                click: function () {
                    var zz = obj[i];
                    return function () {
                        alert("you have clicked " + zz.text);
                    }
                }()
            }
        });
    }
于 2015-04-20T05:39:10.450 回答