Domanda

Sto scrivendo un utente che rileva "spedire a" moduli di indirizzo progettati arbitrariamente e analizza il loro contenuto. Per fare ciò, ho bisogno di trovare forme "righe" (che possono o non possono essere elementi tr) che contengono sia l'etichetta per l'indirizzo (come "nome", "indirizzo1", ecc.) E il corrispondente campo input per quel tag. Ad esempio, nel seguente snippet:

<div>
<label>MaidenName</label>
<table><tbody>
    <tr>
        <td><label>FirstName</label></td>
        <td><input value = "Bob"></td>
    </tr>
    <tr>
        <td><label>LastName</label></td>
        <td><input value = "Smith"></td>
    </tr>
    <tr>
        <td><label>CompanyName</label></td>
        <td><input value = "Ink Inc"></td>
    </tr>
</tbody></table>
</div>
.

Vorrei abbinare tutti gli elementi tr, perché ciascuno contiene un'etichetta "nome" e un campo di input. Tuttavia, non vorrei abbinare il div a causa dell'etichetta "Fidenname", perché ha una portata più ampia delle partite trovate per i campi all'interno del tavolo.

Il mio attuale algoritmo per trovare queste righe (che sono spesso elementi div anziché quelli tr) è quello di:

    .
  • Trova tutti i nodi con etichette "Nome" appropriate
  • Lavorando il DOM per ogni nodo fino a trovare un nodo che è un antenato di un campo di input
  • Quindi rimuovere i bambini che ho attraversato per arrivarci, lasciando solo gli elementi dei genitori del set.

Traduzione dal porto Sto lavorando, il JQuery JavaScript sembrerebbe quanto segue:

// set up my two lists
var labelNodes = getLabelNodes();
var nodesWithAddress = 
    $().find("input[type='text']:visible, select:visible");

var pathToCommonParents = getLabelNodes()
    .parentsUntil(nodesWithAddressChildren.parents()).parent();

// keep the highest-level nodes, so we only have the common paths - 
//not the nodes between it and the labels.
return combinedNodeSet.filter(
    function (index) {return $(this).find(combinedNodeSet).length == 0});
.

Funziona ... ma tutto ciò che attraversa e confrontando il sovraccarico assolutamente i relitti le mie prestazioni (questo può prendere cinque secondi o più.)

Quale sarebbe un modo migliore per attuare questo? Penso che il seguente pseudocodice sia migliore, ma potrei sbagliare, e non so come implementarlo:

var filteredSet = $().find(*).hasAnyOf(labelNodes).hasAnyOf(nodesWithAddress);
return filteredSet.hasNoneOf(filteredSet); 
.

È stato utile?

Soluzione 2

Per generalizzare la risposta di Micha in modo che possa cercare in un modo indipendente dalla pagina (diversi tag e livelli di nidificazione):

var labelNodes = getLabelNodes();
var returnNodes = $();

var regexAncestors = labelNodes.parent();

while (regexAncestors.length){
    regexAncestors = regexAncestors.not("body");
    var commonParentNodes = regexAncestors.has("input[type='text']:visible, select:visible");
    returnNodes.add(commonParentNodes);
    regexAncestors = regexAncestors.not(commonParentNodes).parent();
}
return returnNodes;
.

Altri suggerimenti

Aggiornamento

Ho trovato una soluzione migliore (vedi revisioni) Penso che questo funzioni prefetto per te.

function getMySpeacialElements() {
    var aSpeacialElements = [];
    $("label").each(function() {
        var oParent = $(this).parent(),
            oSpeacial = oParent.parent();
        oSpeacial.children("*").each(function() {
            if ($(this).children("input").length) {
                aSpeacialElements.push(oSpeacial[0]);
            }
        });
    });
    return aSpeacialElements;
}
.

demo live

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top