jQuery / Método / .parent() - Seleccionar elementos padre directos
En jQuery, .parent() devuelve un nuevo objeto jQuery con el padre directo de cada elemento seleccionado, subiendo un solo nivel. .parent(".card") incluye ese padre únicamente si coincide con .card; no sigue buscando más arriba. Si varios elementos comparten padre, el resultado elimina duplicados.
Elegir entre parent, parents y closest
En la API de .parent(), padre significa el nodo inmediatamente superior en el modelo de objetos del documento (DOM). Una caja que rodea visualmente algo o una referencia CSS no tiene por qué ser ese padre. Puede encadenar $(".pick").parent().addClass("picked") para trabajar sobre los resultados. La búsqueda no mueve ni elimina los botones originales.
| Método | Recorrido | Con selector |
|---|---|---|
| .parent(".card") | Un nivel superior | Padres directos que coinciden |
| .parents(".card") | Padre y antecesores superiores | Antecesores que coinciden |
| .closest(".card") | El propio elemento y después hacia arriba | Primera coincidencia por elemento inicial |
Use .parents() para todos los antecesores coincidentes y .closest() para la tarjeta más cercana aunque haya un contenedor intermedio. closest comprueba también el elemento inicial: sobre una tarjeta puede devolver la misma tarjeta. parent acepta una cadena de selector opcional, no una función ni una cantidad de niveles.
Ejemplo completo con tarjetas anidadas
Guarde todo el código en UTF-8 como parent-demo.html y ábralo en el navegador. Se necesita Internet para cargar el archivo oficial de jQuery 4.0.0 desde la red de distribución de contenido (CDN), sin instalación. La selección inicial, el contenedor adicional, la tarjeta nueva, el reinicio y ambos ejemplos de consola se ejecutaron con 3.7.1 y 4.0.0.
Los dos botones de Alpha comparten alpha-body como padre directo. El botón de Beta está directamente dentro de beta. Los contornos turquesa indican resultados. buttons cuenta los botones iniciales, parents los resultados y DOM buttons los botones que siguen en el documento.
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Select immediate parents</title>
<script src="https://code.jquery.com/jquery-4.0.0.min.js"></script>
<style>
body { font: 16px/1.6 sans-serif; max-width: 760px; margin: 24px auto; padding: 16px; }
button, select { font: inherit; margin: 4px; max-width: 100%; }
#board, .card, .body { padding: 12px; border: 1px solid #aab; margin: 10px 0; }
.picked { outline: 3px solid teal; outline-offset: -3px; }
pre { white-space: pre-wrap; overflow-wrap: anywhere; }
</style>
</head>
<body>
<h1>Select one parent level</h1>
<label for="mode">Traversal:</label>
<select id="mode">
<option value="parent">parent()</option>
<option value="filtered">parent('.card')</option>
<option value="closest">closest('.card')</option>
<option value="ancestors">parents('section')</option>
</select>
<button type="button" id="wrap">Wrap Beta button</button>
<button type="button" id="add">Add Gamma</button>
<button type="button" id="reset">Reset</button>
<section id="board">
<article id="alpha" class="card">
Alpha card
<div id="alpha-body" class="body">
<button type="button" id="alpha-one" class="pick"><span>Alpha one</span></button>
<button type="button" id="alpha-two" class="pick">Alpha two</button>
</div>
</article>
<article id="beta" class="card">
Beta card
<button type="button" id="beta-one" class="pick">Beta one</button>
</article>
</section>
<pre id="result" aria-live="polite"></pre>
<script>
$(function () {
const initial = $("#board").html();
function report() {
const $buttons = $("#board .pick");
let $result;
switch ($("#mode").val()) {
case "filtered": $result = $buttons.parent(".card"); break;
case "closest": $result = $buttons.closest(".card"); break;
case "ancestors": $result = $buttons.parents("section"); break;
default: $result = $buttons.parent();
}
$("#board, #board *").removeClass("picked");
$result.addClass("picked");
const ids = $result.map(function () { return this.id; }).get();
$("#result").text(`buttons=${$buttons.length}\nparents=${$result.length}: ${ids.join(", ") || "(none)"}\nDOM buttons=${$("#board .pick").length}`);
}
$("#mode").on("change", report);
$("#wrap").on("click", function () {
if (!$("#beta-body").length) $("#beta-one").wrap('<div id="beta-body" class="body"></div>');
report();
});
$("#add").on("click", function () {
if (!$("#gamma").length) $("#board").append('<article id="gamma" class="card">Gamma card <button type="button" id="gamma-one" class="pick">Gamma one</button></article>');
report();
});
$("#reset").on("click", function () { $("#board").html(initial); $("#mode").val("parent"); report(); });
report();
});
</script>
</body>
</html>
Al principio, tres botones producen dos padres distintos porque el padre compartido aparece una sola vez.
buttons=3
parents=2: alpha-body, beta
DOM buttons=3
- Seleccione parent('.card'): solo coincide beta. El padre directo de Alpha es .body y la búsqueda no continúa hasta alpha.
- closest('.card') encuentra alpha y beta, pasando por el .body intermedio de Alpha.
- parents('section') devuelve una vez el antecesor compartido board.
- Pulse Wrap Beta button y vuelva a parent(): aparecen alpha-body y beta-body. parent('.card') queda vacío. Los botones permanecen; solo cambia la relación directa.
- Add Gamma añade un botón directamente en una tarjeta nueva. parent('.card') devuelve solo gamma y closest('.card') tres tarjetas. Repetir las operaciones no crea duplicados.
- Reset restaura el HTML original y el modo parent(). Cambie una condición y reinicie para comparar.
report() vuelve a seleccionar los botones en cada llamada. Guardar const $parents = $(".pick").parent() no actualiza el resultado automáticamente cuando cambia el DOM. Repita el recorrido tras envolver o mover nodos si necesita relaciones actuales.
Duplicados, resultados vacíos y origen de eventos
Tras Reset, ejecute este código en la consola de las herramientas de desarrollo. parent sobre una selección vacía devuelve un objeto jQuery de longitud cero: compruebe .length antes de acceder al nodo. El padre de html puede ser document en vez de un elemento normal, por lo que no todos los resultados tendrán propiedades de elemento como tagName.
const $buttons = $("#board .pick");
console.log(`buttons=${$buttons.length}; unique parents=${$buttons.parent().length}`);
console.log(`Alpha parent(.card)=${$("#alpha-one").parent(".card").length}`);
console.log(`Alpha closest(.card)=${$("#alpha-one").closest(".card").attr("id")}`);
console.log(`card closest itself=${$("#alpha").closest(".card").attr("id")}`);
console.log(`empty parent count=${$().parent().length}`);
console.log(`html parent is document=${$("html").parent().get(0) === document}`);
buttons=3; unique parents=2
Alpha parent(.card)=0
Alpha closest(.card)=alpha
card closest itself=alpha
empty parent count=0
html parent is document=true
Al pulsar un span dentro de un botón, event.target es ese span. En un controlador delegado con una función normal, this permite partir del botón coincidente. Ejecute lo siguiente en la consola de la misma página: genera el clic en span y después quita únicamente su propio controlador mediante el espacio de nombres.
$("#board").on("click.parentExample", ".pick", function (event) {
console.log(`parent=${$(this).parent().attr("id")}; target=${event.target.tagName.toLowerCase()}`);
});
$("#alpha-one span").trigger("click");
$("#board").off(".parentExample");
parent=alpha-body; target=span
La referencia target es span, pero el padre indicado es alpha-body, el del botón. $(event.target).parent() devolvería el botón. Una función flecha no recibe aquí el botón como this; use una función normal. Para obtener la tarjeta, aplique .closest(".card") al botón.
Resolver un padre inesperado
Inspeccione el DOM real en el panel Elements de las herramientas de desarrollo. Un plugin que inserta un div intermedio puede dejar vacío .parent(".card"). Decida si necesita el padre directo o el antecesor coincidente más cercano antes de añadir cadenas arbitrarias de .parent().parent().
Un selector inicial demasiado amplio puede modificar padres sin relación. Limítelo, por ejemplo, a #board .pick y compruebe longitud e identificadores antes de cambiar estilos. Si no hay resultados, confirme primero que los elementos iniciales existan al ejecutarse el código. La función de preparación del DOM se ejecuta tras analizar el HTML inicial; volver a llamar a report() incorpora botones posteriores.




