2010-12-22 16 views
3

Ich habe ein Ereignis onClick-Ereignis an ein Tag angefügt. Beim Klicken wollte ich ein Attribut aufnehmen - sagen wir, fn; und ich möchte die Funktion als Attributwert aufrufen.JQuery: Eine Funktion dynamisch aufrufen

Der folgende Code funktioniert Meine Fragen sind, ist nicht

<html> 
<head> 
    <script type="text/javascript" src="http://code.jquery.com/jquery-1.4.4.min.js"></script> 
    <script language="JavaScript"> 
     var Test = Test? Test : new Object(); 
     $(document).ready(function(){ 
      Test.main(); 
     }) 
     Test.sub = function(){ 
      alert('called'); 
     } 
     Test.main = function(){ 
      $('.caller').click(function(e){ 
       e.preventDefault(); 
       var fn = $(this).attr('fn'); 
       alert('calling: '+fn); 
       return fn(); 
      }); 
     } 
    </script> 
</head> 
<body> 
    <a class="caller" fn="Test.sub" href="#">test call</a> 
</body> 
</html> 

  • es möglich?
  • Was mache ich falsch?
  • Was könnte der richtige Ansatz sein, um dieses Problem zu lösen?

Dank
Nishant

Antwort

14

Ist es möglich?

Ja. Wenn Sie Ihren Link ändern, um nur sub haben:

<a class="caller" fn="sub" href="#">test call</a> 

Dann funktioniert das:

$('.caller').click(function(e){ 
    e.preventDefault(); 
    var fn = $(this).attr('fn'); 
    alert('calling: '+fn); 
    return Test[fn](); 
}); 

Der Wert, den Sie abrufen eine Zeichenfolge ist. Sie können Index in die Eigenschaften eines Objekts eine Zeichenfolge verwenden, wenn Sie Notation ([]) klammert wie mit, so dass alle von ihnen sind äquivalent:

Test.sub(); 
Test['sub'](); 
var fn = 'sub'; 
Test[fn](); 

Was mache ich falsch?

Sie waren fast da. Sie hatten "Test" in einer Zeichenfolge, aber da es eine Zeichenfolge war, keine Funktion, konnten Sie sie nicht aufrufen. Es würde so sein:

"Test.sub"(); 

.... was offensichtlich nicht ganz tun, was Sie wollen. :-)

Was könnte der richtige Ansatz sein, um dieses Problem zu lösen?

In technischer Hinsicht löst das Obige das Problem. Ein Teil von mir Sorgen um die tatsächlichen Funktionsnamen in einem Attribute und will sagen „eine Lookup-Tabelle stattdessen hat“, aber Ihr Test Objekt im Grunde ist die Lookup-Tabelle, so ...

Side Hinweis: In diesem Situation, können Sie sehen, Menschen mit eval. Das liegt normalerweise daran, dass sie nicht erkannt haben, dass Sie in ein Objekt mit Klammern-Notation einordnen können. eval wird am besten vermieden.


Off-topiC# 1: Ihr Attribut, fn, ist ungültig (invalid = wird nicht validate).In HTML4 und früher waren alle benutzerdefinierte Attribute ungültig, obwohl jeder Desktop-Browser, den ich je gesehen habe, sie erlaubt (Browser lassen uns mit vielen Dingen davonkommen). Ab HTML5 war die Nachfrage nach dieser Funktion zu hören, und wir können gültige benutzerdefinierte Attribute haben, aber sie müssen mit data- beginnen, damit der Validator weiß, dass sie benutzerdefiniert sind. Wenn also die Validierung Teil Ihres Workflows ist (und das ist normalerweise eine gute Idee), sollten Sie statt fn="sub" mit data-fn="sub" gehen. More here.


Off-topiC# 2: Wenn Sie einige Tipparbeit zu sparen, verwenden {} statt new Object(). ZB:

var Test = Test? Test : {}; 

Und wenn Sie sogar noch mehr sparen möchten, verwenden Sie the curiously-powerful || operator:

var Test = Test || {}; 
+0

Hinweis auf „Off Abschnitt "topic": Obwohl HTML4 * keine benutzerdefinierten Attribute zulässt, glaube ich dass * jeder (ooh!) major [Desktop] -Browser * (historisch und aktuell) sie stillschweigend in das zugängliche DOM aufgenommen hat, zumindest seit der Zeit, in der JS Zugriff auf das DOM hatte. –

+0

@pst: In der Tat haben sie. Normalerweise erwähne ich das, aber ich habe es anscheinend oben weggelassen. –

+0

Ich würde immer noch entweder 'eval' oder eine etwas ausgeklügeltere Logik verwenden, bevor ich die Methode aufruft, um mich von diesem Attribut zu lösen, um die Eigenschaft der' Test' Klasse zu benennen. Im wirklichen Leben scheint es beispielsweise so zu sein, dass eine benutzerdefinierte "Fenster" -Funktion mit oder ohne "Fenster" vor ihrem Namen benannt wird, und Ihre Vorgehensweise wird dann nicht funktionieren. Bei 'eval' interessiert es Sie nicht, welche Objektfunktion Sie aufrufen. So 'eval (Fn +"() ");' ist meine Wahl. Wickeln Sie es einfach in "versuchen ... fangen", vielleicht. –

-1

try this:

<a class="caller" fn="Test.sub()" href="#">test call</a> 

und:

$('.caller').click(function(e){ 
    e.preventDefault(); 
    var fn = eval($(this).attr('fn')); 
    fn; 
}); 
Verwandte Themen