5 Stimmen

Wie würde ich traverse Elemente zwischen zwei bekannten Elemente in der Dom mit Jquery?

Ich möchte dem Benutzer die Möglichkeit geben, auf einen Startpunkt und dann auf einen Endpunkt zu klicken und verschiedene Formularelemente zwischen den beiden ausgewählten Punkten zu manipulieren.

Die Seite ist eine Tabelle mit zahlreichen Zeilen, und jede Zeile enthält die relevanten Informationen, um eine Antwort auf die Frage in dieser Zeile zu bearbeiten/zu speichern. Jede Zeile hat eine verborgene Eingabe für den Wert sowie Ja/Nein-Radiobuttons, hauptsächlich für unerfahrene Benutzer. In der TD-Zelle mit der Frage kann der Benutzer klicken oder zwischen Ja, Nein und Leer umschalten. Ich habe also die Optionsfelder auf der Seite belassen, um Ja/Nein anzuzeigen, und ein verborgenes Feld verwendet, um einen Wert von (1,0,-1) zu speichern.

Dies verwende ich, um die Antwort festzulegen, wenn die Fragezelle angeklickt wird.

    $(".question").bind("click dblclick", function(e) {

        var newClassName = "AnswerUnknown";

        var hiddenAnswerId = $(this).attr('id').replace("question", "answer");

        var answer = parseInt($("#" + hiddenAnswerId).val());

        var newValue;

        switch (answer) {
            case -1:
                newClassName = "AnswerCorrect";
                newValue = 1;
                $("#" + $(this).attr('id').replace("answer", "radioYes")).attr('checked', 'checked');
                $("#" + $(this).attr('id').replace("answer", "radioNo")).attr('checked', '');
                break;
            case 1:
                newClassName = "AnswerWrong";
                newValue = 0;
                $("#" + $(this).attr('id').replace("answer", "radioYes")).attr('checked', '');
                $("#" + $(this).attr('id').replace("answer", "radioNo")).attr('checked', 'checked');
                break;
            default:
                newClassName = "AnswerEmpty";
                newValue = -1;
                $("#" + $(this).attr('id').replace("answer", "radioYes")).attr('checked', '');
                $("#" + $(this).attr('id').replace("answer", "radioNo")).attr('checked', '');
        }
        $("#" + hiddenAnswerId).val(newValue);
        $(this).removeClass().addClass(newClassName);
    });

Jetzt möchte ich dem Benutzer ermöglichen, auf einen Startpunkt zu klicken, und diese Antwort soll alle folgenden Fragen bis zu dem Punkt ausfüllen, an dem er auf das zweite Element geklickt hat. Das können 10 Fragen oder 20 Fragen sein, das ist eine unbekannte Variable. Es kann eine Seite mit 130 Fragen geben, und 20 Fragen in einer Reihe können "Ja" lauten. Wie oben erwähnt, hat jede Zeile eine Zelle "Frage" und die Zelle davor ist die Elementzelle.

Ich weiß, wie man das Startelement und das Endelement auf der Grundlage eines Jquery-Selektors/einer Funktion festlegt, der/die an ein unten aufgeführtes Click/Dblclick-Ereignis gebunden ist.

Ich bin mir nicht sicher, wie ich das Dom durchlaufen oder alle Elemente auswählen kann, die ich zwischen den beiden ausgewählten Punkten auf der Seite bearbeiten muss.

    var StartItem;
    var EndItem;

    $(".item").bind("click dblclick", function(e) {

        var StartClassName = "AnswerUnknown";
        var EndClassName = "AnswerUnknown";
        var StartAnswerId;
        var EndAnswerId;
        var StartAnswer;

        if (StartItem === undefined) {
            StartItem = this;
            StartAnswerId = $(this).attr('id').replace("item", "rs");
            StartAnswer = parseInt($("#" + StartAnswerId).val());
        }
        else {
            if (EndItem === undefined) {
                EndItem = this;
                EndAnswerId = $(this).attr('id').replace("item", "rs");
                EndAnswer = parseInt($("#" + EndAnswerId).val());
            }
        }

        if (StartItem == this) {
            $(this).removeClass().addClass(StartClassName);
        }

        if (EndItem == this) {
            $(this).removeClass().addClass(EndClassName);
        }
    });

2voto

Matt Punkte 78

Am besten ist es IMHO, so etwas wie unten zu machen. Sie können eine Schleife über die Sammlung von Elementen mit dem Klassennamen "item" laufen lassen, und wenn Sie Ihr Startelement gefunden haben, können Sie die von Ihnen beschriebene Verarbeitung vornehmen. Da Sie "this" haben, können Sie diese ID nehmen und tun, was Sie in Ihrer question.click-Funktion getan haben.

        var counter = 0;

    // This will loop over each element with classname "item", so make sure you take that into account
            $('.item').each(function(i) {
        // function returns this, but you can see what index your on with 'i'
                if (this == StartItem) {
                    // You can start processing rows
                    counter = 1;
                }
                else {
                    if (counter > 0) {
                        // Process rows/items after the first item above
                        counter = counter + 1;
                    }
                }
                if (this == EndItem) {
                    counter = 0
                    // Finish up processing if any
                    //Break out of each;
                }

            });

0voto

Russ Cam Punkte 120837

Am einfachsten wäre es wohl, dem Startelement eine Startklasse und dem Endelement eine Endklasse hinzuzufügen. Beim Durchlaufen der Elemente zwischen Start und Ende können Sie dann nach dem Namen der Start- oder Endklasse suchen und entsprechende Aktionen durchführen/verhindern.

EDITAR:

So etwas wie dieses Plugin wird es tun. Das Plugin geht davon aus, dass beide Elemente, die die Grenzen des Bereichs definieren, denselben Elternteil haben und vom selben Elementtyp sind ( nodeName ). Sie können Ihre eigenen Start- und Endklassennamen verwenden oder einfach die Standardwerte "Start" und "Ende" übernehmen.

(function($) {

  $.fn.rangeSelector = function(options) {   

    var settings = $.extend({ startClass : 'start', endClass: 'end'},options||{}); 
    var name = this[0].nodeName.split(':'); 
    name = name[name.length -1];
    var startIndex = $(name + '.' + settings.startClass).prevAll().length;
    var endIndex = $(name + '.' + settings.endClass).prevAll().length + 1;
    return this.slice(startIndex,endIndex);
  }

})(jQuery);

und dann können Sie wie folgt verwenden

/*
 * will get all textboxes between textboxes 
 * with className start and end, inclusive
 */
$('input:text').rangeSelector();

Hier ist ein Arbeits-Demo . Wenn Sie den Code anzeigen möchten, fügen Sie /Bearbeiten an das Ende der URL. Ich dachte an ein Dienstprogramm zu schreiben, um ein jQuery-Objekt basierend auf startClass, endClass und Element-Typ-Parameter einschließen zurückzukehren, aber das wäre Overkill für was Sie benötigen.

EDIT 2:

In Anbetracht Ihres Kommentars kann ich es Ihnen erläutern

  1. ein jQuery-Objekt erhalten, das die fraglichen Elemente enthält, die in Ihrem Fall, wie ich glaube, Texteingaben sind, also wäre es etwas wie $('parent > input:text') wobei parent das übergeordnete Element ist (die Übergabe von input:text selbst wird nicht korrekt funktionieren, wenn Sie andere Texteingaben auf der Seite außerhalb des übergeordneten Elements haben, da das Plugin auf Indizes angewiesen ist).

  2. Sie können ein options-Objekt an rangeSelector mit unterschiedlichen Start- und Endklassennamen übergeben, wenn Sie möchten (wie .rangeSelector({ start: "myStartClass", end: "myEndClass"}) oder verwenden Sie einfach den Standard start y end in diesem Fall brauchen Sie kein Objekt zu übergeben.

  3. Die Einstellungsvariable verbindet die Standardwerte (die als Eigenschaften eines Objekts definiert sind) mit den Eigenschaften des übergebenen Optionsobjekts (oder einem Objekt ohne Eigenschaften, wenn kein Optionsobjekt definiert ist).

  4. die Art der Elemente, mit denen wir es im jQuery-Objekt zu tun haben, berechnen und in name variabel. Dies geschieht durch Aufteilung der nodeName String des ersten Elements im jQuery-Objekt in ein Array und weist name dem Wert des letzten String-Elements im Array zu.

  5. Berechnen Sie die Start- und Endindizes für die Elemente, die mit dem Symbol start y end Klassennamen. Index bezieht sich in diesem Fall auf die 0-basierte Position des Elements innerhalb seines übergeordneten Elements.

  6. gibt nur die Elemente im jQuery-Objekt zwischen dem Start- und dem Endindex (einschließlich) als jQuery-Objekt zurück (so dass weitere jQuery-Befehle angehängt werden können). Dies verwendet die slice() Befehl, der für ein jQuery-Objekt die gleichen Funktionen hat wie Array.slice() für Arrays.

0voto

Lasse Espeholt Punkte 17372

Die Frage ist schon etwas älter, aber hier ist die Lösung, die ich für meine Projekte verwende:

jQuery-Selektor

(function ($) {
    $.fn.between = function (elm0, elm1) {
        var index0 = $(this).index(elm0);
        var index1 = $(this).index(elm1);

        if (index0 <= index1)
            return this.slice(index0, index1 + 1);
        else
            return this.slice(index1, index0 + 1);
    }
})(jQuery);

Verwendung

$('body').between($('#someid'), $('#someid2')).each(function () {
    // Do what you want.
});

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X