Bypass-koppeling van JavaScript-acties aan objecten

Ik heb een script dat acties toevoegt aan sommige objecten in mijn HTML-code. Zeg, een tekstgebied met een klasse met teller die het aantal karakters dat erop wordt getypt, bijwerkt; een lijst die luistert wanneer een mouseover plaatsvindt; een link die wordt ajaxified; enzovoorts.

bijv .:

$("textarea.with-counter").keydown(function(){
   var text_len = $(this).val().length;
   //manipulate the span/etc that has the counter
});
$("a.ajax_link").click(function(){
   var loc = $(this).attr("href");
   //load the value of href via $.ajax to some div
   //yadda yadda
});

Het beginscenario is dit: Een relatief kleine hoeveelheid HTML wordt uit de database geladen en er worden acties aan gekoppeld (het bovenstaande codefragment implementeren). Nu heb ik dit script dat nog een brok van hetzelfde formaat HTML laadt. De nieuw geladen HTML zou dezelfde acties moeten ontvangen.

De onderste regel van het probleem is: ik wil deze acties niet koppelen aan de objecten/elementen waaraan ik deze acties eerder heb gekoppeld. Naarmate nieuwere brokken HTML's worden geladen, duurt het toevoegen van acties langzamer. De acties worden gekoppeld aan de eerder geladen HTML (onthoud dat ze deze acties hebben) wanneer ik wil dat de acties alleen aan de nieuw geladen HTML-chunks moeten worden gekoppeld. Er zijn tijden dat FF vastloopt en zal vragen of ik door wil gaan met het scriptproces.

Ergo, de vraag: is er een manier waarop ik ervoor kan kiezen om acties te koppelen aan de elementen waaraan ik eerder acties heb gekoppeld?

* Een miljoen bedankt, iedereen.

1

2 antwoord

Ja, herwerk je actie-bindende code in een functie die een context inneemt - een selector of element waarbinnen gezocht kan worden. Wijzig vervolgens al uw selectors om in de context als een tweede parameter door te geven aan de functie jQuery $.

U kunt deze functie dan voor een bepaald nieuw containerelement aanroepen.

Bijv.

function bindActions(context) {
    context = context || $('body');//use whole page if no context specified
$("textarea.with-counter", context).keydown(function(){
   var text_len = $(this).val().length;
   //manipulate the span/etc that has the counter
});
$("a.ajax_link", context).click(function(){
   var loc = $(this).attr("href");
   //load the value of href via $.ajax to some div
   //yadda yadda
});
}

// add new content to a div with id of "new3", for example, then:
bindActions('#new3');
1
toegevoegd
Ik denk dat dit is waar ik precies naar op zoek ben. :)
toegevoegd de auteur threepoint1416, de bron

Simply use live events, e.g. $(...).live('eventname', function() { ... })

Ze zijn niet gehecht aan de elementen zelf, maar aan het document, dus dankzij het borrelen van gebeurtenissen werken ze voor alle overeenkomende gebeurtenissen, inclusief gebeurtenissen die niet bestonden ten tijde van de aanroep .live() .

0
toegevoegd
De uitvoering zou goed moeten zijn. Gebeurtenissen blazen sowieso naar de bovenkant van het document, dus het enige echte verschil is dat u preventDefault() of stopPropagation() niet kunt gebruiken omdat de gebeurtenis al is opgeblazen (deze wordt afgehandeld) wanneer het het rootelement van het document bereikt). je kunt ook delegate() gebruiken in plaats van live evenementen. In dit geval geeft u het wortelelement op dat u wilt gebruiken.
toegevoegd de auteur ThiefMaster, de bron
Ik vraag me af hoe de prestaties van live-evenementen afwegen tegen het gebruik van de contextbenadering die ik noemde, vooral voor grote pagina's. Zou goed zijn om een ​​ jsperf.com test te doen. :-)
toegevoegd de auteur GregL, de bron
Gebaseerd op de naam van de methode, voegt dit continu acties toe aan de elementen terwijl het tabblad open is? Bedankt.
toegevoegd de auteur threepoint1416, de bron
Anyways, ik heb deze methode feitelijk geïmplementeerd voor wat ik aan het bouwen ben. Maar als de behoefte zich voordoet, zal ik op weg zijn naar uw antwoord @GregL. Hartelijk bedankt
toegevoegd de auteur threepoint1416, de bron