2013-02-28 23 views
5

Ich habe eine Menge von jQuery-Code so gesehen, unnötig zu sagen, ich mag es nicht:jQuery Ereignisbindung und Handhabung

<div id="myDiv"> 
    <a class="clickable" href="#">Click Me</a> 
    <a class="clickable" href="#">Click Me</a> 
    <a class="clickable" href="#">Click Me</a> 
    <a class="clickable" href="#">Click Me</a> 
</div> 

<script> 
    $(document).ready(function(){ 
     $('clickable').click(function(){ 
      // Do some stuff... 
     }); 
    }); 
</script> 

Ich weiß, die Menschen dies tun, weil die obige Ereignisbindung und Handhabung erfordert, dass die HTML-Struktur auf der Seite verfügbar ist, aber es führt dazu, die Präsentation, die Logik und die Konfiguration in den Ansichten der Website zu mischen. Außerdem ist es sehr schwierig, die Logik mit fast jedem Debugger zu debuggen.

Also, ich habe Codierung wie diese begann, auf eine separate Js (fiddle here) Datei:

// BEGIN: Event Handlers 
    var onLoad = function(){ 
     $('.clickable').data('clicked', false); 
    }; 
    var onMyDivClick = function(){ 
     var clicked = $(this).data('clicked'); 
     if (clicked) { 
      $(this).trigger('myCustomEvent'); 
     } else { 
      alert('you clicked me'); 
      $(this).data('clicked', true); 
     } 
    }; 
    var onMyCustomEvent = function(){ 
     $(this).css('color', 'dimGray'); 
     alert('please don\'t click me again'); 
    }; 
// END: Event Handlers 

// BEGIN: Event Binding 
    $(window).on('load', onLoad); 
    $(document).on('click', '.clickable', onMyDivClick); 
    $(document).on('myCustomEvent', '.clickable', onMyCustomEvent); 
// END: Event Binding 

Nun, ich weiß nicht über die Struktur, die auf Seite kümmern müssen. Ich muss nicht alles einpacken Und ich muss nicht darauf achten, ob die Struktur mit Ajax geladen wird oder nicht.

Frage 1 Gibt es irgendwelche Nachteile bei der Annäherung? Bisher habe ich keine gefunden. Bevor wir jedoch den Großteil des Codes auf unseren Websites umgestalten, würde ich gerne über die möglichen Vorbehalte sprechen.

Frage 2 Wie könnte dieser Ansatz mit den neuesten jQuery-Funktionen noch weiter verfolgt werden?

Antwort

1

Es gibt einen Nachteil, den ich kenne mit diesem Ansatz. Es ist in der Event-Performance Abschnitt in .on() geschrieben.

Wenn Sie viele delegierte Event-Handler am oberen Rand des Dokumentbaums anhängen, kann dies die Leistung beeinträchtigen. Jedes Mal, wenn das Ereignis auftritt, muss jQuery alle Selektoren aller angehängten Ereignisse dieses Typs mit allen Elementen im Pfad vom Ereignisziel bis zum Anfang des Dokuments vergleichen. Um eine optimale Leistung zu erzielen, hängen Sie delegierte Ereignisse an einem Dokumentstandort so nah wie möglich an den Zielelementen an. Vermeiden Sie übermäßige Verwendung von Dokument oder document.body für delegierte Ereignisse auf großen Dokumenten.

So, nachdem Sie alle Ereignisse document Bindung, wäre es noch schlimmer führen.

Und in Zusätzliche Hinweise, gibt es etwas, was nicht mit diesem Ansatz, wie load, scroll und error arbeiten können.

+0

Also, abgesehen von onLoad, den Rest der Ereignisbehandlung innerhalb von onLoad verschieben und sie so nah wie möglich an das Ziel anhängen: http://jsfiddle.net/codepic/8pE6z/2/ Dies jedoch effektiv zerstört die Ereignisbehandlung auf Steuerelementen, die mit AJAX geladen sind. Vielleicht muss ich ein benutzerdefiniertes Ereignis auslösen, wenn ein "Steuerelement" geladen wird. Wie so: http://jsfiddle.net/codepic/8pE6z/3/ Auf diese Art würde es nur einen Ereignishandler auf dem Dokumentelement geben, der nach .control sucht und den Rest der Ereignisbindung näher an das Ziel bindet. –

0

Schauen Sie sich die Rahmen an, sie haben die Kesselplatte für Sie erledigt. Ich habe bisher nur Knockout benutzt, aber ich werde zu einigen anderen verlinken.

"Hallo Welt" in Knockout:

http://knockoutjs.com/examples/helloWorld.html

<p>First name: <input data-bind="value: firstName" /></p> 
<p>Last name: <input data-bind="value: lastName" /></p> 
<h2>Hello, <span data-bind="text: fullName"> </span>!</h2> 

// Here's my data model 
var ViewModel = function(first, last) { 
    this.firstName = ko.observable(first); 
    this.lastName = ko.observable(last); 
    this.fullName = ko.computed(function() { 
     // Knockout tracks dependencies automatically. It knows that fullName depends on firstName and lastName, because these get called when evaluating fullName. 
     return this.firstName() + " " + this.lastName(); 
    }, this); 
}; 

ko.applyBindings(new ViewModel("Planet", "Earth")); // This makes Knockout get to work 
+1

Danke für die Links. Ich habe mich zumindest mit Knockout beschäftigt und plane, eines der oben genannten Frameworks zu implementieren. Aber zuerst muss ich die benutzerdefinierte UI-Logik auf der aktuellen Plattform aufräumen und die UI-Leute anweisen, von dort mit dem bestmöglichen reinen jQuery-Approval fortzufahren. Weißt du, sie sind alle an jQuery gewöhnt, also werfen sie ein neues Framework auf sie, während sie das aktuelle Framework noch verbessern müssen. Das würde nur das Chaos mit einem anderen Framework wiederherstellen. Aber ja, die genannten Lösungen passen perfekt zur Datenbindung und zur Erstellung gut strukturierter Ajax-Kontrollen. –

+0

Gut ausgewogener Ansatz. Bearbeiten - es sei denn, die "Menge des Codes" ist erheblich. Wenn ja, warum zwei große Änderungen? –

+0

OH OH! Wenn Sie ein Tutorial für KO für Ihre Benutzeroberfläche wünschen, Freebie bei http://learn.knockoutjs.com/. –

0

Das schreit über Technik für mich. Um Code in document.ready zu vermeiden und View-Logik in der Ansicht zu vermeiden, führen Sie noch mehr Komplexität ein.

Ihr Ansatz bindet direkt an das Dokument und überprüft dann das dom für das, was geklickt wurde. Dann feuern Sie ein zweites Ereignis für das, was geklickt wurde, wo Ihre Logik lebt.

Das ist gut für ein oder zwei Elemente. Das ist nicht deine typische App. Was passiert, wenn Sie 5 Elemente haben, die alle etwas anderes machen müssen? Wie wäre es mit 10? Vielleicht 15?

Ihr "einfacher" Event-Handler wird ein netter großer Schalter (oder schlimmer, wenns und verschachtelte ifs). Plötzlich ist das Hinzufügen eines neuen Handlers nicht so einfach. Es wird auch kein vorhandenes Ereignis geändert.

Sie würden viel besser in ein Framework schauen, das Ihnen die Trennung bietet, die Sie suchen. Der Versuch, so etwas zu beschleifen, um deinen Code zu "organisieren", wird zurückkommen, um dich zu beißen. Die meiste Komplexität im Code wird von einem Ingenieur geboren, der es "einfach", "besser" und "zukunftssicher" macht.

Dies ist nicht zu schlagen Sie oder Ihre Gedanken. Sie haben die richtige Idee: Trennung von Verantwortung ist eine gute Sache. Ich glaube nicht, dass dein Ansatz der Beste ist.

Wie ein anderer geschrieben beantwortet, Winkel und Backbone und Glut (und viele mehr) bieten die Mittel, um das zu erreichen, was Sie wollen. Außerdem müssen Sie nicht die Bibliothek bearbeiten, die Sie ausgewählt haben :)

Verwandte Themen