2012-03-31 13 views
0

Ich habe eine PHP-Seite mit einer ungeordneten Liste. Ich habe ein paar jQuery-Code, der für wartet ein Benutzer auf eines der Elemente in der Liste klicken:

$(function() { 
$('li.large_box').css('cursor', 'pointer') 
.click(function() { 
    $('#db_sections').empty(); 
    var show_id = this.id; 
    $.post('get_section_dates.php', { show_id: show_id }, function(sections) { 
    $('#section_dates_feedback').html(sections); 
    }); 
}); 
}); 

Wenn ein Benutzer klickt auf eines dieser Elemente die jQuery-Code ist es id an ein PHP-Skript sendet, macht eine Datenbankabfrage und baut eine Dropdown-Liste mit den Ergebnissen:

if (isset($_POST['show_id'])) { 
    $show_id = $_POST['show_id']; 
    $result = mysql_query("SELECT `id`,`air_date` FROM `daily_show` WHERE show_id = '".$show_id."'"); 

     echo"<div id='dates_select'>"; 
     echo "<select id='date_select'>"; 
     echo "<option value='0'>Choose a date</option>";   
    while ($query = mysql_fetch_assoc($result)) 
    { 
     $id = $query['id']; 
     $air_date = strtotime($query['air_date']); 
     $date = date("M-d-Y \(D\)",$air_date); 
     echo "<option value='$id'>$date</option>";  
    } 
echo "</select>"; 
echo "</div>"; 
} 

das erste Mal, dass ich auf einem der Listeneinträge alles klicken ordnungsgemäß funktioniert schnell und die Drop-Down-Box kommt. Das Problem ist, wenn ich auf das nächste Listenelement klicke, dauert der Code ein paar Sekunden länger, um die neue Dropdown-Liste anstelle der alten zu erstellen. Jeder neue Klick auf ein anderes Listenelement verlängert die Zeit, die zum Erstellen der Dropdown-Liste benötigt wird, bis jedes Mal mehr als eine Minute benötigt wird.

Die Datenbanktabelle, die abgefragt wird, ist nur 12 Datensätze lang und gibt im Allgemeinen nur 1 oder 2 Zeilen zurück.

Ich bin neu bei PHP/jQuery und habe mich gefragt, ob irgendetwas offensichtlich in meinem Code diesen Prozess verlangsamt hat.

Danke für einen Blick auf mein Problem!

Antwort

0

Klingt wie ein Problem mit mehreren Bindings für mich. Nur eine Vermutung, aber vielleicht fügen Sie die Click-Funktion zu dem anklickbaren Element jedes Mal, wenn der POST zurückkehrt. Wenn Sie also das nächste Mal klicken, wird der POST zweimal ausgeführt. Dann dreimal. Das fügt jedes Mal eine neue Anforderung hinzu und fügt jedes Mal redundante DOM-Manipulationen hinzu.

Der Code, wie er im Beispiel aussieht, zeigt jedoch keine offensichtlichen Anzeichen dafür, dass der Klick erneut gebunden wurde. Also, obwohl ich einen Vorschlag habe, ist es eine Art Schuß im Dunkeln.

(Randbemerkung:. Es kein Grund ist die CSS über jQuery hier hinzufügen in Ihr Stylesheet setzen Sie einfach diese Regel, die ich es aus der Probe entfernt haben!)

Nun, ich weiß nicht, Ihren Markup , also werde ich sicher spielen und document als mein vorgeschlagener Zuhörer verwenden, um Mehrfachbindung zu vermeiden. Grundsätzlich ist der erste Selektor hier idealerweise ein tatsächlicher Knoten, der niemals als Teil des Ajax-Aufrufs zerstört wird. Es wird beim Laden der ersten Seite gerendert und dann nie wieder gerendert. Sie könnten zum Beispiel $('#someContainer').on(/* ... */) verwenden. Ich benutze nur ein Dokument.

$(function() { 
    $(document).on('click', '.large_box', function() { 
    /* all the stuff that should happen on click */ 
    }); 
}); 

Jetzt ist hier die wirklich wichtige Sache, die Sie in Ihrer Probe scheinen zu tun, kann aber nicht sein. Diese Dokumentbereitschaftsfunktion muss nur einmal ausgelöst werden, wenn die Seite zuerst geladen wird. Eine echte Dokument-bereit-Funktion, so wie sie sein sollte. Stellen Sie es nicht in irgendwelche Funktionen, die gefeuert werden könnten.

Schnelle Möglichkeit zu sagen, ob es mehrfach gebunden ist, ist das Öffnen von Firebug oder Webkit Developer Tools ... Sie sehen die POST HTTP-Anfragen. Wenn mehrere für einen Klick gefeuert werden, finde einfach heraus, warum es wieder gebunden wird.

+0

Vielen Dank für Ihre Anregung ich es in Firebug sah und ich denke, mein Hauptproblem ist, dass nach dem PHP-Code, den ich in meiner Frage gestellt, ich zwei Linien links, wo ich etwas echo wie dieses Echo "" was eine JavaScript-Datei ist, die einige Funktionen enthält, die ich brauche, nachdem das Dropdown-Feld ausgefüllt wurde. Es ist diese Datei, die eine Vielzahl von Malen geladen wird und die Verlangsamung verursacht. Diese js-Datei muss nicht jedes Mal geladen werden, wenn jemand auf ein Listenelement klickt, aber wenn ich das Echo aus der Skriptdatei kommentiere, bricht meine Seite zusammen. – JackBurton

1

sollten Sie überlegen, ob Sie Ihre Transportmethode und Ihren JS, mit dem sie arbeitet, optimieren sollten.

Zunächst einmal erstellen Ihre Skripts jeden Klick "fett". Das heißt, es gibt übermäßige jQuery-Aufrufe.Sie können es in diese optimieren:

$(function() { 

    //put into reference static elements 
    $db_sections = $('#db_sections'); 
    $section_dates_feedback = $('#section_dates_feedback'); 

    //delegate event to parent handler using .on() 
    $('the_containing_ul').on('click', 'li.large_box', function() { 
     $db_sections.empty(); 
     $.post('get_section_dates.php', { 
      show_id: this.id 
     }, function(data) { 
      //callback 
     }); 
    }); 
}); 

wie für Ihre PHP-Antwort, Sie zumindest Verwendung JSON für den Transport sollte und nicht HTML es leicht zu machen. Sie können json_encode verwenden, um ein PHP-Array in einen JSON-String für den Transport umzuwandeln.

if (isset($_POST['show_id'])) { 

    $show_id = $_POST['show_id']; 
    $result = mysql_query(query_here); 
    $resultArray = mysql_fetch_assoc($result) 

    //do a little formatting before we send over 
    while ($resultArray){ 
     $resultArray['air_date'] = date("M-d-Y \(D\)",strtotime($resultArray['air_date'])); 
    } 

    echo json_encode($resultArray); 
} 

dies den folgenden JSON-String drucken, die besser als das Drucken HTML ist:

[ 
    {"id":"1","air_date":"January 1, 12"}, 
    {"id":"2","air_date":"January 2, 12"}, 
    {"id":"3","air_date":"January 3, 12"}, 
    ... and so on 
] 

jetzt, in der POST-Anfrage, jQuery wandelt intuitiv in ein JSON-Objekt, das wir analysieren können . Sie können es jetzt verwenden, um Ihre Auswahlbox zu generieren. dies wird der Rückruf sein:

function(data) { 

    //create a select and div, and append it to a div 
    $div = $('<div id="dates_select" />'); 
    $select = $('<select id="date_select" />').appendTo($div); 

    //create options based on data and append to select 
    $.each(data,function(index,row){ 
     $('<option />') 
      .attr('value',row.id) 
      .text(row.air_date) 
      .appendTo($select); 
    } 

    //put div into the feedback 
    $section_dates_feedback.html($div); 

}