2011-02-07 45 views
0

我有想製作一個小的jQuery插件的想法,但有些東西我不知道如何去做,而不必依賴eval如何向Javascript函數發送條件測試,而不僅僅是結果?

下面的代碼:

  var testMe = 1; 

      $.extend({ 
       once : function(condition, duration, callback) { 
        window[ "once" ] = window.setTimeout(function() { 
         if (condition) 
         { 
          callback.apply(); 

          window.clearTimeout(window[ "once" ]); 
         } else { 
          window[ "once" ] = window.setTimeout(arguments.callee, duration * 1000); 
         } 
        }, duration * 1000); 
       } 
      }); 

      $.once(testMe == 2, 5, function() { 
       alert("Match!"); 
      }); 

它看起來像當$.once()被調用,第一個參數,然後進行評估,只有它在這個時間值被送到條件參數。我發現的唯一方法是將其發送作爲一個字符串:

$.once("testMe == 2" ...和使用if (eval(condition))

有另一種方式withing使用eval

謝謝。

編輯:這裏是一個插件的最終版本:

  var testOne = 1, 
       testTwo = 1; 

      $.extend({ 
       once : function(name, conditionFn, duration, callback) { 
        if (typeof duration == "function") 
        { 
         callback = duration; 
         duration = 5; 
        } 

        window[ "once" + name ] = window.setInterval(function() { 
         if (conditionFn()) 
         { 
          callback(); 

          window.clearInterval(window[ "once" + name ]); 
         } 
        }, duration * 1000); 
       } 
      }); 


      //Examples 
      $.once("testOne", function() { 
       return testOne == 2 
      }, 2, function() { 
       alert("testOne == 1"); 
      }); 

      $.once("testTwo", function() { 
       return testTwo == 2 
      }, 2, function() { 
       alert("testTwo == 1"); 
      }); 

回答

2

你是正確的;參數被評估並通過。除非你真的知道自己在做什麼,否則我不會推薦使用eval,並且有充分的理由這樣做。

而是將謂詞(返回布爾值的函數)傳遞給您的插件。每次你想檢查時,調用函數:

var testMe = 1;

$.extend({ 
    once : function(predicate, duration, callback) { 
     window.once = window.setInterval(function() { 
      if (predicate()) { 
       window.clearInterval(window.once); 
       callback(); 
      } 
     }, duration * 1000); 
    } 
}); 

$.once(function() { return testMe == 2; }, 5, function() { 
    alert("Match!"); 
}); 

N.B.我用自取消setInterval()替換了您的重複setTimeout來電。另外,您正在調用callbackcallback.apply(),但沒有理由這樣做。你可以直接用()來調用它,就像上面的代碼一樣。

1

發送返回的比較結果的函數:

var testMe = 1; 

$.extend({ 
        // receive the function 
    once : function(conditionFn, duration, callback) { 
     window[ "once" ] = window.setTimeout(function() { 

       // execute the function 
      if (conditionFn()) 
      { 
       callback.apply(); 

       window.clearTimeout(window[ "once" ]); 
      } else { 
       window[ "once" ] = window.setTimeout(arguments.callee, duration * 1000); 
      } 
     }, duration * 1000); 
    } 
}); 
     // send a function 
$.once(function(){return testMe == 2;}, 5, function() { 
    alert("Match!"); 
}); 
+0

難道你不是指「if(condition())」嗎? – Medo42 2011-02-07 20:16:10

+0

是的,我忘記了首先更新參數名稱。 – RightSaidFred 2011-02-07 20:17:55

相關問題