jQuery $ (документ) .ready и UpdatePanels? - PullRequest
466 голосов
/ 02 ноября 2008

Я использую jQuery для подключения некоторых эффектов наведения мыши на элементах внутри UpdatePanel. События связаны в $(document).ready. Например:

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

Конечно, это работает нормально при первой загрузке страницы, но когда UpdatePanel выполняет частичное обновление страницы, он не запускается, и эффекты наведения мыши больше не работают внутри UpdatePanel.

Каков рекомендуемый подход для подключения компонентов в jQuery не только при первой загрузке страницы, но и каждый раз, когда UpdatePanel запускает частичное обновление страницы? Должен ли я использовать жизненный цикл ASP.NET ajax вместо $(document).ready?

Ответы [ 19 ]

532 голосов
/ 02 ноября 2008

UpdatePanel полностью заменяет содержимое панели обновления при обновлении. Это означает, что те события, на которые вы подписались, больше не подписываются, поскольку в этой панели обновлений есть новые элементы.

Что я сделал, чтобы обойти это, так это переподписался на события, которые мне нужны после каждого обновления. Я использую $(document).ready() для начальной загрузки, затем использую Microsoft PageRequestManager (доступно, если на вашей странице есть панель обновлений), чтобы переподписывать каждое обновление.

$(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
});

PageRequestManager - это объект javascript, который автоматически доступен, если на странице находится панель обновления. Вам не нужно ничего делать, кроме приведенного выше кода, чтобы использовать его, пока панель обновления находится на странице.

Если вам нужен более подробный контроль, это событие передает аргументы, аналогичные тому, как события .NET передаются аргументам (sender, eventArgs), чтобы вы могли видеть, что вызвало событие, и только при необходимости повторно связывать.

Вот последняя версия документации от Microsoft: msdn.microsoft.com /.../ bb383810.aspx


Лучшим вариантом, в зависимости от ваших потребностей, является использование .on() в jQuery. Эти методы более эффективны, чем повторная подписка на элементы DOM при каждом обновлении. Однако, прежде чем использовать этот подход, прочитайте всю документацию, поскольку она может соответствовать или не соответствовать вашим потребностям. Существует множество плагинов jQuery, которые было бы нецелесообразно использовать для рефакторинга .delegate() или .on(), поэтому в этих случаях вам лучше переподписаться.

158 голосов
/ 14 января 2009
<script type="text/javascript">

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

Область, которая будет обновлена.

<asp:UpdatePanel...
<ContentTemplate
     <script type="text/javascript">
                    Sys.Application.add_load(BindEvents);
     </script>
 *// Staff*
</ContentTemplate>
    </asp:UpdatePanel>
62 голосов
/ 26 мая 2010

Пользовательский элемент управления с jQuery внутри UpdatePanel

Это не прямой ответ на вопрос, но я собрал это решение, прочитав ответы, которые нашел здесь, и подумал, что кто-то может найти его полезным.

Я пытался использовать ограничитель текстовой области jQuery внутри пользовательского элемента управления. Это было сложно, потому что пользовательский элемент управления работает внутри UpdatePanel, и он терял свои привязки при обратном вызове.

Если бы это была просто страница, ответы здесь были бы применены напрямую. Однако пользовательские элементы управления не имеют прямого доступа к тегу head и не имеют прямого доступа к UpdatePanel, как предполагают некоторые ответы.

Я закончил тем, что поместил этот блок сценария прямо в разметку моего пользовательского элемента управления. Для начального связывания он использует $ (document) .ready, а затем использует 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>

Итак ... Просто подумал, что кому-то может быть интересно узнать, что это работает.

33 голосов
/ 06 февраля 2009

Обновите до jQuery 1.3 и используйте:

$(function() {

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

});

Примечание: live работает с большинством событий, но не со всеми. Полный список документации .

.
20 голосов
/ 31 декабря 2010

Вы также можете попробовать:

<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>

, поскольку pageLoad () является ajax-событием ASP.NET, которое выполняется каждый раз, когда страница загружается на стороне клиента.

16 голосов
/ 28 февраля 2011

Мой ответ?

function pageLoad() {

  $(document).ready(function(){

и т.д.

Работал как шарм, где ряд других решений с треском провалился.

7 голосов
/ 26 июня 2013

Это сработало для меня:

$(document).ready(function() {

    // Do something exciting

    var prm = Sys.WebForms.PageRequestManager.getInstance();

    prm.add_endRequest(function() {
        // re-bind your jQuery events here
    });

});
7 голосов
/ 02 ноября 2008

Я бы использовал один из следующих подходов:

  1. Инкапсулируйте привязку события в функцию и запускайте ее каждый раз, когда вы обновляете страницу. Вы всегда можете содержать привязку события к определенным элементам, чтобы не связывать события несколько раз с одними и теми же элементами.

  2. Используйте плагин livequery , который в основном выполняет первый способ для вас автоматически. Ваше предпочтение может варьироваться в зависимости от степени контроля, который вы хотите иметь для привязки события.

6 голосов
/ 16 июля 2015

Когда $(document).ready(function (){...}) не работает после пост-страницы, используйте функцию JavaScript pageLoad в Asp.page следующим образом:

<script type="text/javascript" language="javascript">
function pageLoad() {
// Initialization code here, meant to run once. 
}
</script>
6 голосов
/ 17 июня 2011

Функция pageLoad () очень опасна для использования в этой ситуации. Вы можете сделать события проводными несколько раз. Я бы также держался подальше от .live (), так как он присоединяется к элементу документа и должен пересекать всю страницу (медленно и дрянно).

Лучшее решение, которое я видел до сих пор, - это использовать функцию jQuery .delegate () на оболочке за пределами панели обновления и использовать всплывающее окно. Кроме того, вы всегда можете подключить обработчики, используя библиотеку Microsoft Ajax, которая была разработана для работы с UpdatePanels.

...