如何挂钩 jQuery 自己的函数,以检查字符串是否可以评估为函数?

发布于 2024-10-21 05:29:01 字数 568 浏览 0 评论 0原文

我希望能够做到这一点

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

,并以某种方式检查挂钩的“bind”内部,它确实是一个函数,以及 eval()new Function 字符串,所以它将被正确分配为事件。

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

或者有没有更好的方法来完成这个? 检查前 8 个字符是否 === 'function' 然后 eval 这不是一个好主意,因为它可以是“合法”文本字符串。 我尝试传递一个函数作为 ajax JSON 响应的结果,但 $.parseJSON 默默地失败了。

I want to be able to do this

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

and somehow, checking inside a hooked "bind", that it's indeed a function, and eval() or new Function the string, so it will be correctly assigned as an event.

The reason I want to do this is because JSON doesn't allow functions to be defined as values, only strings/ints.
I would want to find a way to apply this for all jquery functions (like animate(), click(), live(), etc) that take a handler/function as parameter. it would be a huge hassle and I think, and would become impractical after each new version of jQuery released

Or is there any better way to accomplish this? checking for the first 8 characters if they are === 'function' and then eval it is not a good idea, since it can be a "legitimate" text string.
I tried passing a function as a result from a ajax JSON response, but $.parseJSON failed silently.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

星光不落少年眉 2024-10-28 05:29:01

这就是您要找的http://jsbin.com/adewe4/3

函数定义https://gist.github.com/862112

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

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);

Is this what you are looking for, http://jsbin.com/adewe4/3

function definition https://gist.github.com/862112

You can use the parseJSONwithFunctions method to parse the JSON data that you receive as the AJAX response using $.getJSON.

parseJSONwithFunctions converts the function body as strings in the JSON into actual function objects; so rather than trying to make jQuery eval strings, you can just pass the function reference to it.

If you use the method as,

var my_json_data = {};

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

and the you can define handlers as,

$('.class').bind('click', my_json_data.clickHandler);
や三分注定 2024-10-28 05:29:01

刚刚找到我自己的答案,哇,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 特定功能。当它尝试对字符串调用 call() 或 apply() 时,它将评估为代码/函数。问题是,这是一个全局修改,如果有人发现它,可能会导致一些客户端破坏,呵呵。

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

Just found my own answer, WOW, javascript can be quite powerful, check this out

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

No need to hook any jQuery specific function. When it tries to call() or apply() on a string, it will eval to code/function. the problem is that this is a global modification, and could lead to some client-side havoc if someones find out about it hehe.

what are the caveats in this solution?

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文