Как подключить собственные функции jQuery, чтобы проверить, может ли строка быть оценена в функции? - PullRequest
0 голосов
/ 09 марта 2011

Я хочу иметь возможность сделать это

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

и каким-то образом, проверяя внутри перехваченного «связывания», что это действительно функция, и eval() или new Function строка, так чтобудет правильно назначен как событие.

Причина, по которой я хочу это сделать, заключается в том, что JSON не позволяет определять функции как значения, только строки / целые.Я хотел бы найти способ применить это для всех функций jquery (таких как animate (), click (), live () и т. Д.), Которые принимают обработчик / функцию в качестве параметра.я думаю, это было бы очень хлопотно и стало бы непрактичным после каждой новой версии jQuery

Или есть ли лучший способ сделать это? проверка первых 8 символов, еслиони === 'function' и затем eval, это не очень хорошая идея, так как это может быть "легитимной" текстовой строкой.Я попытался передать функцию в результате ответа JSON ajax, но $ .parseJSON потерпел неудачу молча.

Ответы [ 2 ]

0 голосов
/ 09 марта 2011

Это то, что вы ищете, http://jsbin.com/adewe4/3

определение функции https://gist.github.com/862112

Вы можете использовать метод parseJSONwithFunctions для анализа данных JSON, которые вы получаете как AJAXответ с использованием $.getJSON.

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);
0 голосов
/ 09 марта 2011

Только что нашел свой ответ, ВАУ, 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 () для строки, он будет преобразован в код / ​​функцию. проблема в том, что это глобальная модификация, которая может привести к хаосу на стороне клиента, если кто-то узнает об этом, хе-хе

Каковы предостережения в этом решении?

...