
🔍 JQuery: kuidas leida kindla tekstiga elementi
Arendaja loob WooCommerce tootekaardi paigutust. Kõik läheb plaanipäraselt, kuni adminipaneelist saabub ülesanne: „eemalda Featured märgis ja selle järel olev koma, kuid ainult holder-kategoorias olevate toodete puhul." Käsitsi töötlemine ei tule kõne alla, tooteid on sadu. Vaja on skripti, mis leiab iseseisvalt tekstiga „featured" ploki, liigub ülemtasemeni, haarab naabruses oleva span-i ja eemaldab kogu konstruktsiooni.
Ja siin astub mängu jQuery oma ahelatega: .each() itereerimiseks, .find() otsimiseks, :contains() teksti järgi filtreerimiseks, .closest() ülemtasemele ronimiseks, .next() naabri juurde liikumiseks ja .remove() puhastamiseks. Viis meetodit ja ülesanne on lahendatud nelja reaga. Allpool võtan iga sammu lahti: selektorist kuni lõpliku puhastuseni, selgitades loogikat ja varjatud nüansse.
💡 Kiirülevaade:
- Esmalt leiame contains-selektori abil sihtploki koos tekstiga ja ronime closest-i abil selle ülemtasemeni
- Seejärel liigume next-i abil naaberelemendi juurde ja eemaldame remove abil täpselt mõlemad plokid
- Lõpus silume skripti ja analüüsime tüüpilisi vigu konteksti kadumise ning ahnelt järgmist haarava next-iga
Ülesanne: mida otsime ja mida eemaldame
Algne HTML-struktuur näeb välja umbes selline:
1 <span class="tg-cats-holder"> 2 <a class="product_visibility" href="..."> 3 <span class="tg-item-term">featured</span> 4 </a> 5 <span>, </span> 6 <a class="product_visibility" href="..."> 7 <span class="tg-item-term">sale</span> 8 </a> 9 <span>, </span> 10 </span>
Peamine eesmärk on leida <span class="tg-item-term">, mis sisaldab teksti featured, ronida ülemtasemeni <a class="product_visibility">, seejärel liikuda järgmise <span>-ni (komaga) ja see eemaldada. Pärast seda eemaldada <a class="product_visibility"> koos märgise endaga. Teised sildid (sale jne) jäävad puutumata.
Valmis skript
1 jQuery(document).ready(function($) { 2 $('span.tg-cats-holder').each(function() { 3 $(this) 4 .find('span.tg-item-term:contains("featured")') 5 .closest('a.product_visibility') 6 .next('span:contains(",")') 7 .remove(); 8 9 $(this) 10 .find('span.tg-item-term:contains("featured")') 11 .closest('a.product_visibility') 12 .remove(); 13 }); 14 });
Kood on teadlikult jagatud kaheks ahelaks, mitte surutud ühte. Põhjus on lihtne: pärast elemendi .remove()-i ahel katkeb, edasi pole kuhugi minna. Seega kõigepealt puhastame naabruses oleva span-i komaga (esimene ahel), seejärel eemaldame ploki enda (teine).
Samm-sammuline lahtivõtmine
1. Samm: siseneme igasse holder-isse
1 $('span.tg-cats-holder').each(function() {
Meetod .each() käib läbi kõik kollektsiooni elemendid, meie juhul kõik <span class="tg-cats-holder"> elemendid lehel. Kui holder-eid on mitu (erinevad tootekategooriad), töötab skript igas neist iseseisvalt. Tagasikutse funktsiooni sees viitab this praegusele holder-ile, kogu edasine otsing lähtub sellest.
2. Samm: otsime tekstiga plokki:contains() abil
1 .find('span.tg-item-term:contains("featured")')
Selektor :contains("featured") leiab elemendi, mille sees (kaasa arvatud alamelemendid) leidub alamstring „featured". Kolm olulist nüanssi:
Tõstutundlikkus. Stringid „Featured", „FEATURED" ja „featured" on erinevad. Kui adminipaneelis on märgis kirjutatud teisiti, lisa kontroll
.filter()ja.toLowerCase()abil, näide on KKK jaotises.Otsing läbi kõigi alamelementide.
:contains()kontrollib nii elemendi enda kui ka kõigi selle laste tekstisisu. Kui<span class="tg-item-term">sees on veel mõni<strong>, läheb ka selle sees olev tekst arvesse.See ei ole jõudluse selektor.
:contains()ei ole kiirendatud natiivsequerySelectorAll-iga, jQuery käib läbi kõik kandidaadid ja loeb.textContent-i. Sadade elementidega lehtede puhul on parem kitsendada valikut täiendava klassi või atribuudiga.
Meetod .find() piirab otsingu praeguse holder-i alamelementidega, mitte terve lehega, see annab nii kiirusevõidu kui ka kaitse valepositiivsete vastu.
3. Samm: ronime ülemtasemeni.closest() abil
1 .closest('a.product_visibility')
.closest() liigub leitud elemendist puus ülespoole ja tagastab lähima selektorile vastava eellase. Erinevalt .parent()-ist ei ole see piiratud ühe tasemega, see ronib kuni <html>-ni, kuni leiab vaste või jõuab juureni.
Kui oleksime .parent() asemel kasutanud .closest()-i, läheks skript katki juba väikseima pesitsuse korral: <span class="tg-item-term"> → <strong> → <a class="product_visibility">, .parent() tagastaks <strong>-i, mitte vajaliku lingi. .closest() kindlustab selliste üllatuste vastu.
4. Samm: hüppame naabri juurde.next() abil
1 .next('span:contains(",")')
.next() võtab sama ülemtaseme vahetult järgneva sõsarelemendi. Filter span:contains(",") garanteerib, et võtame täpselt komaga span-i, mitte suvalist järgnevat elementi. Ilma filtrita haaraks .next() esimese kättesaadava sõsarsõlme, näiteks järgmise <a class="product_visibility"> koos järgmise sildiga.
Erinevus .next() ja .nextAll() vahel: esimene võtab täpselt ühe elemendi, teine kõik järgnevad sõsarelemendid. Siin on vaja täpset lööki, seega .next().
5. Samm: eemaldame
1 .remove();
.remove() lõikab elemendi DOM-ist täielikult välja, koos sündmuste töötlejate ja jQuery andmetega. Kui on vaja ainult peita (tagasitoomise perspektiiviga), kasuta .hide() või .detach(). Kuid ülesande „eemalda märgis alatiseks" jaoks sobib ainult .remove().
Järjekord loeb: kõigepealt eemaldame naabruses oleva span-i (esimene ahel), alles seejärel ploki enda (teine). Kui eemaldame ploki enne, kaotab naabruses olev span konteksti, .next() töötab teise elemendi suhtes või tagastab tühja kollektsiooni.
Laiendatud näide: tõstutundetu otsing
Reaalses projektis võib sildi tekst tulla erinevas tõstus: featured, Featured, FEATURED. Tavaline :contains() sellega hakkama ei saa. Lahendus on kohandatud selektor, mis põhineb .filter()-il:
1 $('span.tg-cats-holder').each(function() { 2 $(this).find('span.tg-item-term').filter(function() { 3 return $(this).text().toLowerCase().indexOf('featured') !== -1; 4 }).closest('a.product_visibility').each(function() { 5 $(this).next('span:contains(",")').remove(); 6 $(this).remove(); 7 }); 8 });
Siin kontrollib .filter() koos tagasikutse funktsiooniga iga kandidaadi väiketähelist teksti. Ridu on veidi rohkem, kuid skript ei sõltu sellest, kuidas täpselt tekst adminipaneelis sisestati.
Alternatiiv puhtas JavaScriptis
Kui projektis ei kasutata jQuery-t üldse, kirjutatakse sama loogika vanilla JS-is:
1 document.querySelectorAll('span.tg-cats-holder').forEach(function(holder) { 2 holder.querySelectorAll('span.tg-item-term').forEach(function(term) { 3 if (term.textContent.includes('featured')) { 4 const link = term.closest('a.product_visibility'); 5 const nextSpan = link.nextElementSibling; 6 if (nextSpan && nextSpan.matches('span') && nextSpan.textContent.includes(',')) { 7 nextSpan.remove(); 8 } 9 link.remove(); 10 } 11 }); 12 });
Sama algoritm: holder-ite itereerimine → teksti järgi otsing .textContent.includes() abil → ülemtasemele ronimine natiivse .closest() abil → naabri kontrollimine ja eemaldamine → ploki eemaldamine. Natiivne teostus on pikem, kuid ei too kaasa jQuery sõltuvust.
Lühivideo teemal, :contains() ja navigatsiooniahelate lahtivõtmine jQuery-s:
⁉️🤔 Korduma kippuvad küsimused
Miks :contains() ei leia teksti, mida ma lehel näen?
Suure tõenäosusega on probleem tõstus või tühikutes.
:contains("Featured")ei leia „featured", see on tõstutundlik selektor. Lisaks võib brauser normaliseerida tühikuid HTML-i sees teisiti, kui ootad. Kontrolli täpset sisu käsugaconsole.log($('selector').text())ja kopeeri string üks-ühele:contains()sisse.
*Kas saab ilma *.closest()ta ja kasutada fikseeritud ahelat .parent().parent()?
Tehniliselt jah. Praktiliselt ei ole soovitatav. Jäik ahel
.parent().parent()läheb katki iga pesitsuse muutuse korral: lisati ümbris, mindi üle teisele teemale, skript lakkas töötamast..closest('a.product_visibility')on paindlikum: see otsib lähimat sobivat elementi ükskõik millisel tasemel ülespoole. Kirjutatud üks kord, töötab sõltumata struktuurist.
Skript eemaldab vale span-i. Kuidas siluda?
Esimene samm, lisa
console.log()enne iga.remove()käsku ja kontrolli, mis täpselt valikusse satub. Teiseks, täpsusta.next()selektorit. Ilma filtrita võtab.next()ükskõik millise järgneva elemendi samal tasemel, isegi kui see on teine<a>või<div>. Lisaspan:contains(",")või täpsem klass ning veendu, et naaber on tõepoolest õige.
Kas skript tuleb mässida jQuery(document).ready() sisse?
Jah, kui skript on
<head>-is või ühendub enne DOM-i renderdamist. KonstruktsioonjQuery(document).ready(function($){ ... })garanteerib, et kood käivitub alles pärast DOM-puu täielikku laadimist. Lisaks antakse$tagasikutsele eksplitsiitselt kaasa, see kindlustab konfliktide vastu teiste teekidega, mis võivad samuti$-ile pretendeerida. Kui skript on jaluses pärast kõiki elemente, ei ole.ready()formaalselt nõutav, kuid distsipliin „alati mässida" säästab refaktoreerimisel raskesti tabatavatest vigadest.
Mis on kiirem: jQuery või vanilla JS sellise ülesande jaoks?
Natiivne JavaScript võidab külmkäivituses: pole vaja laadida, parsida ja kompileerida jQuery-t ning see säästab kümneid kilobaiti liiklust ja mitu millisekundit parsimist. DOM-operatsioonide puhul on vahe tagasihoidlikum, jutt käib millisekundi murdosadest ühe väljakutse kohta. Tüüpilise WordPressi saidi puhul, kus jQuery on juba teema või pluginatega ühendatud, on erinevus märkamatu, sinu neljarealine skript ei muutu pudelikaelaks. Kui jQuery on projektis juba olemas, kirjuta jQuery-s, kood on kompaktsem ja loetavam. Kui ei ole, võta vanilla JS, ära lohista teeki ühe töötleja pärast.
Kas 2026. aastal tasub tekstotsinguks jQuery-t kasutada?
jQuery pole kuhugi kadunud. W3Techsi 2026. aasta juuni statistika kohaselt on see teek paigaldatud 87,3%-le saitidest, millel on teadaolev JavaScripti teek (68,1%-le kõigist saitidest), peamiselt tänu WordPressile, kus jQuery on tuumas ja teemade poolt automaatselt ühendatud. WordPressi arendaja jaoks on jQuery natiivne tööriist, mis on juba laaditud ega tekita lisapäringuid.
Otsesed alternatiivid nagu Alpine.js või HTMX lahendavad teisi ülesandeid (reaktiivsus, osalised uuendused) ja on ühekordse DOM-skripti jaoks üleliigsed. Natiivne querySelectorAll + closest() + remove() on toimiv variant ilma sõltuvusteta, kuid väljakutseahelad muutuvad pikemaks. Valik taandub lihtsale reeglile: jQuery on projektis juba olemas, võta jQuery; projekt ilma jQuery-ta, võta vanilla JS.
Peamine on see, et nüüd tead täpset mehaanikat kombinatsioonist :contains() + .closest() + .next() + .remove() ning millises dialektis seda kirjutada, otsustab konkreetne projekt.



