Ottenere gli elementi "più profondi" che soddisfano due diversi criteri di selezione discendente
-
12-12-2019 - |
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);
. 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;
}
.