如何挂钩jQuery自己的函数,检查一个字符串是否可以被eval'到一个函数?

时间:2011-03-09 01:48:12

标签: javascript jquery events hook handler

我希望能够做到这一点

$('.class').bind({'click':'function(){ ... }'}); // note that the value is a string

以某种方式,检查一个钩住的“绑定”,它确实是一个函数,并且eval()new Function字符串,因此它将被正确地指定为事件。

我想这样做的原因是因为JSON不允许将函数定义为值,只定义字符串/整数。 我想找到一种方法将这个应用于所有jquery函数(如animate(),click(),live()等),它们将处理程序/函数作为参数。我认为这将是一个巨大的麻烦,并且在每个新版本的jQuery发布后都会变得不切实际

还是有更好的方法来实现这个目标吗?检查前8个字符是否为==='function'然后评估它不是一个好主意,因为它可能是一个“合法”文本字符串。 我尝试通过ajax JSON响应传递函数,但$ .parseJSON无声地失败。

2 个答案:

答案 0 :(得分:0)

刚刚找到我自己的答案,WOW,javascript可以非常强大,请查看

var call_cache = [];

str_is_function = function(str){
  if (jQuery.type(str) !== 'string' || ! /^\s*?function/i.test(str) || ! /\}$/m.test(str)) return false;
  return true;
}

String.prototype.apply = function(obj){
  if ( ! str_is_function(this) ) return false;

  var str = this.toString(), cache_len = call_cache.length;
  fn = null;

  for(i = 0; i < cache_len; i++){
    if (call_cache[i].str === str) {
      fn = call_cache[i].fn;
      break;
    }
  }

  if (typeof fn != 'function'){
     $.globalEval('var fn = ' + str);
     call_cache.push({'str': str, 'fn': fn});
     cache_len = call_cache.length;
  }

  args = Array.prototype.slice.call(arguments, 1);

  if (typeof args[0] != 'undefined' && args[0].constructor === Array){
    args = args[0];
  }

  return fn.apply(obj, args);
}

String.prototype.call = function(obj){
  this.apply(obj, Array.prototype.slice.call(arguments, 1));
}

$('.gap').bind({'mouseover':'function(){ alert("gi");}'});

"function(name){ alert(name); }".call(null, "hi");
"function(name){ alert(name); }".apply(null, ["hello"]);
"function(){ alert('teehee'); }".call(null);
"alert".call(null, "hi"); // wont work

无需挂钩任何jQuery特定功能。当它尝试对字符串调用()或apply()时,它将评估代码/函数。问题是这是一个全局性的修改,如果有人发现它,可能会导致一些客户端的破坏。

此解决方案有哪些注意事项?

答案 1 :(得分:0)

这是你在找什么,http://jsbin.com/adewe4/3

功能定义https://gist.github.com/862112

您可以使用parseJSONwithFunctions方法使用$.getJSON解析您收到的JSON数据作为AJAX响应。

parseJSONwithFunctions将函数体作为JSON中的字符串转换为实际的函数对象;所以,不要试图制作jQuery eval字符串,只需将函数引用传递给它。

如果您使用方法,

var my_json_data = {};

$.getJSON('URL_TO_GET_JSON', function (data) {
  my_json_data = parseJSONwithFunctions(data);
});

您可以将处理程序定义为

$('.class').bind('click', my_json_data.clickHandler);