jQuery $(document).ready en UpdatePanels?

Ik gebruik jQuery om wat mouseover-effecten op elementen in een UpdatePanel aan te brengen. De gebeurtenissen zijn gebonden in $(document).ready. Bijvoorbeeld:

$(function() {    
    $('div._Foo').bind("mouseover", function(e) {
        // Do something exciting
    });    
});

Natuurlijk werkt dit prima de eerste keer dat de pagina wordt geladen, maar wanneer het UpdatePanel een gedeeltelijke pagina-update uitvoert, wordt het niet uitgevoerd en werken de mouseover-effecten niet meer in het UpdatePanel.

Wat is de aanbevolen aanpak om dingen in jQuery te bedraden, niet alleen bij het laden van de eerste pagina, maar elke keer dat een UpdatePanel een gedeeltelijke pagina-update uitvoert? Moet ik de ASP.NET ajax-levenscyclus gebruiken in plaats van $(document).ready?


Antwoord 1, autoriteit 100%

Een UpdatePanel vervangt de inhoud van het updatepaneel volledig bij een update. Dit betekent dat de evenementen waarop u zich hebt geabonneerd, niet langer zijn geabonneerd omdat er nieuwe elementen in dat updatepaneel zijn.

Wat ik heb gedaan om dit te omzeilen, is me na elke update opnieuw abonneren op de evenementen die ik nodig heb. Ik gebruik $(document).ready()voor de eerste keer laden en gebruik vervolgens PageRequestManager(beschikbaar als je een updatepaneel op je pagina hebt) om je opnieuw te abonneren op elke update.

$(document).ready(function() {
    // bind your jQuery events here initially
});
var prm = Sys.WebForms.PageRequestManager.getInstance();
prm.add_endRequest(function() {
    // re-bind your jQuery events here
});

De PageRequestManageris een javascript-object dat automatisch beschikbaar is als er een updatepaneel op de pagina staat. U hoeft niets anders te doen dan de bovenstaande code om deze te gebruiken zolang het UpdatePanel op de pagina staat.

Als je meer gedetailleerde controle nodig hebt, geeft deze gebeurtenis argumenten door die vergelijkbaar zijn met hoe .NET-gebeurtenissen worden doorgegeven, argumenten (sender, eventArgs)zodat je kunt zien wat de gebeurtenis heeft veroorzaakt en alleen opnieuw bindt als dat nodig is .

Hier is de nieuwste versie van de documentatie van Microsoft: msdn.microsoft.com /…/bb383810.aspx


Een betere optie die je misschien hebt, afhankelijk van je behoeften, is het gebruik van jQuery’s .on(). Deze methode is efficiënter dan u bij elke update opnieuw te abonneren op DOM-elementen. Lees echter alle documentatie voordat u deze aanpak gebruikt, aangezien deze al dan niet aan uw behoeften voldoet. Er zijn veel jQuery-plug-ins waarvan het onredelijk zou zijn om te refactoren om .delegate()of .on()te gebruiken, dus in die gevallen kunt u beter opnieuw -abonneren.


Antwoord 2, autoriteit 29%

<script type="text/javascript">
        function BindEvents() {
            $(document).ready(function() {
                $(".tr-base").mouseover(function() {
                    $(this).toggleClass("trHover");
                }).mouseout(function() {
                    $(this).removeClass("trHover");
                });
         }
</script>

Het gebied dat wordt bijgewerkt.

<asp:UpdatePanel...
<ContentTemplate
     <script type="text/javascript">
                    Sys.Application.add_load(BindEvents);
     </script>
 *// Staff*
</ContentTemplate>
    </asp:UpdatePanel>

Antwoord 3, autoriteit 11%

Gebruikersbeheer met jQuery in een UpdatePanel

Dit is geen direct antwoord op de vraag, maar ik heb deze oplossing samengesteld door de antwoorden te lezen die ik hier vond, en ik dacht dat iemand het misschien nuttig zou vinden.

Ik probeerde een jQuery-tekstgebiedbegrenzer te gebruiken in een gebruikersbesturing. Dit was lastig, omdat het gebruikersbeheer in een UpdatePanel wordt uitgevoerd en het zijn bindingen verliest bij terugbellen.

Als dit slechts een pagina was, zouden de antwoorden hier direct van toepassing zijn geweest. Gebruikersbedieningen hebben echter geen directe toegang tot de head-tag, noch hebben ze directe toegang tot het UpdatePanel, zoals sommige antwoorden veronderstellen.

Uiteindelijk heb ik dit scriptblok bovenaan in de opmaak van mijn Gebruikersbeheer geplaatst. Voor de eerste binding gebruikt het $(document).ready, en vanaf daar gebruikt het prm.add_endRequest:

<script type="text/javascript">
    function BindControlEvents() {
        //jQuery is wrapped in BindEvents function so it can be re-bound after each callback.
        //Your code would replace the following line:
            $('#<%= TextProtocolDrugInstructions.ClientID %>').limit('100', '#charsLeft_Instructions');            
    }
    //Initial bind
    $(document).ready(function () {
        BindControlEvents();
    });
    //Re-bind for callbacks
    var prm = Sys.WebForms.PageRequestManager.getInstance(); 
    prm.add_endRequest(function() { 
        BindControlEvents();
    }); 
</script>

Dus… Ik dacht dat iemand misschien graag zou willen weten dat dit werkt.


Antwoord 4, autoriteit 6%

Upgrade naar jQuery 1.3 en gebruik:

$(function() {
    $('div._Foo').live("mouseover", function(e) {
        // Do something exciting
    });
});

Opmerking: live werkt met de meeste evenementen, maar niet met alle. Er is een volledige lijst in de documentatie.


Antwoord 5, autoriteit 4%

Je zou ook kunnen proberen:

<asp:UpdatePanel runat="server" ID="myUpdatePanel">
    <ContentTemplate>
        <script type="text/javascript" language="javascript">
        function pageLoad() {
           $('div._Foo').bind("mouseover", function(e) {
               // Do something exciting
           });
        }
        </script>
    </ContentTemplate>
</asp:UpdatePanel>

,sinds pageLoad() een ASP.NET ajax-gebeurtenis is die wordt uitgevoerd telkens wanneer de pagina aan de clientzijde wordt geladen.


Antwoord 6, autoriteit 3%

Mijn antwoord?

function pageLoad() {
  $(document).ready(function(){

enz.

Werkte als een zonnetje, waar een aantal andere oplossingen jammerlijk faalden.


Antwoord 7

Ik zou een van de volgende benaderingen gebruiken:

  1. Verpak de gebeurtenisbinding in een functie en voer deze elke keer uit als u de pagina bijwerkt. U kunt de gebeurtenis altijd binden aan specifieke elementen om gebeurtenissen niet meerdere keren aan dezelfde elementen te binden.

  2. Gebruik de plug-in livequery, die methode één automatisch voor u uitvoert -magisch. Uw voorkeur kan variëren, afhankelijk van de hoeveelheid controle die u wilt hebben over de binding van het evenement.


Antwoord 8

Dit werkte voor mij:

$(document).ready(function() {
    // Do something exciting
    var prm = Sys.WebForms.PageRequestManager.getInstance();
    prm.add_endRequest(function() {
        // re-bind your jQuery events here
    });
});

Antwoord 9

functie pageLoad() is in deze situatie erg gevaarlijk om te gebruiken. Het kan zijn dat evenementen meerdere keren worden bedraad. Ik zou ook wegblijven van .live() omdat het hecht aan het documentelement en de hele pagina moet doorlopen (traag en waardeloos).

De beste oplossing die ik tot nu toe heb gezien, is om jQuery .delegate () -functie op een wrapper buiten het updatepaneel te gebruiken en gebruik te maken van borrelen. Anders, dat zou u altijd de handlers kunnen opleveren met behulp van de Ajax-bibliotheek van Microsoft die is ontworpen om met updatepanels te werken.


10

Ik had een soortgelijk probleem en vond de manier waarop het beste werkte was om te vertrouwen op evenementborrelende en evenementendelegatie om het aan te pakken. Het mooie ding over gebeurtenisdelegatie is dat u eenmaal instelt, u geen gebeurtenissen na een AJAX-update hoeven te herstellen.

Wat ik in mijn code doe, is een afgevaardigde instellen op het ouderelement van het updatepaneel. Dit ouderelement wordt niet vervangen op een update en daarom is de binding van het evenement onaangetast.

Er zijn een aantal goede artikelen en plug-ins om de gebeurtenisdelegatie in jQuery te behandelen en de functie zal waarschijnlijk in de 1,3-release worden gebakken. Het artikel / plug-in dat ik gebruik voor referentie is:

http: //www.danwebb .NET / 2008 / 2/8 / Event-delegatie-Made-Easy-in-jQuery

Als u eenmaal begrijpt wat het gebeurt, denk ik dat u dit een veel elegante oplossing vindt die betrouwbaarder is dan onthouden om gebeurtenissen na elke update opnieuw te binden. Dit heeft ook het extra voordeel van het geven van u een gebeurtenis om los te komen wanneer de pagina wordt gelost.


11

Dit is een geweldige plug-in voor gebruik met updatepanelen:

http://updatePanelplugin.codeplex.com/


12

Update-paneel vervangt altijd uw jQuery met zijn ingebouwde scriptmanager-scripts na elke belasting. Het is beter als u de instantiemethoden van PagerQuestManager zoals deze …

gebruikt

Sys.WebForms.PageRequestManager.getInstance().add_endRequest(onEndRequest)
    function onEndRequest(sender, args) {
       // your jquery code here
      });

het zal goed werken …


Antwoord 13

Gebruik onderstaand script en wijzig de hoofdtekst van het script dienovereenkomstig.

      <script>
        //Re-Create for on page postbacks
        var prm = Sys.WebForms.PageRequestManager.getInstance();
        prm.add_endRequest(function () {
           //your codes here!
        });
    </script>

Antwoord 14

In antwoord op het antwoord van Brian MacKay:

Ik injecteer het JavaScript in mijn pagina via de ScriptManager in plaats van het rechtstreeks in de HTML van de UserControl te plaatsen. In mijn geval moet ik naar een formulier scrollen dat zichtbaar wordt gemaakt nadat het UpdatePanel is voltooid en geretourneerd. Dit komt in de code achter het bestand. In mijn voorbeeld heb ik de variabele prmal gemaakt op de hoofdinhoudspagina.

private void ShowForm(bool pShowForm) {
    //other code here...
    if (pShowForm) {
        FocusOnControl(GetFocusOnFormScript(yourControl.ClientID), yourControl.ClientID);
    }
}
private void FocusOnControl(string pScript, string pControlId) {
    ScriptManager.RegisterStartupScript(this.Page, this.Page.GetType(), "focusControl_" + pControlId, pScript, true);
}
/// <summary>
/// Scrolls to the form that is made visible
/// </summary>
/// <param name="pControlId">The ClientID of the control to focus on after the form is made visible</param>
/// <returns></returns>
private string GetFocusOnFormScript(string pControlId) {
    string script = @"
    function FocusOnForm() {
        var scrollToForm = $('#" + pControlId + @"').offset().top;
        $('html, body').animate({ 
            scrollTop: scrollToForm}, 
            'slow'
        );
        /* This removes the event from the PageRequestManager immediately after the desired functionality is completed so that multiple events are not added */
        prm.remove_endRequest(ScrollFocusToFormCaller);
    }
    prm.add_endRequest(ScrollFocusToFormCaller);
    function ScrollFocusToFormCaller(sender, args) {
        if (args.get_error() == undefined) {
            FocusOnForm();
        }
    }";
    return script;
}

Antwoord 15

Sys.Application.add_load(LoadHandler); //This load handler solved update panel did not bind control after partial postback
function LoadHandler() {
        $(document).ready(function () {
        //rebind any events here for controls under update panel
        });
}

Other episodes