jQuery $ (문서) .ready 및 UpdatePanels?


475

jQuery를 사용하여 UpdatePanel 내부의 요소에 대한 마우스 오버 효과를 연결합니다. 이벤트가 묶여있다$(document).ready . 예를 들면 다음과 같습니다.

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

물론 이것은 페이지가 처음로드 될 때 제대로 작동하지만 UpdatePanel이 부분 페이지 업데이트를 수행 할 때 실행되지 않고 마우스 오버 효과가 UpdatePanel 내에서 더 이상 작동하지 않습니다.

첫 번째 페이지로드뿐만 아니라 UpdatePanel이 부분 페이지 업데이트를 실행할 때마다 jQuery에서 와이어 링을 권장하는 방법은 무엇입니까? 대신 ASP.NET 아약스 수명주기를 사용해야합니까 $(document).ready?


이것이 당신의 문제를 해결할 것이라고 생각합니다. codeproject.com/Articles/21962/…
Baxterboom

답변:


545

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업데이트 패널이 페이지에있는 경우 자동으로 사용할 수있는 자바 스크립트 객체입니다. UpdatePanel이 페이지에있는 한 코드를 사용하기 위해 위의 코드 이외의 작업을 수행하지 않아도됩니다.

보다 자세한 제어가 필요한 경우이 이벤트는 .NET 이벤트에 인수를 전달하는 방법과 유사한 인수를 전달합니다. (sender, eventArgs) 하므로 이벤트를 발생시킨 원인을 확인하고 필요한 경우에만 리 바인드 할 수 있습니다.

다음은 Microsoft의 최신 버전의 설명서입니다. msdn.microsoft.com/.../bb383810.aspx


필요에 따라 더 나은 옵션은 jQuery를 사용하는 것 .on()입니다. 이 방법은 모든 업데이트에서 DOM 요소를 다시 구독하는 것보다 효율적입니다. 그러나이 방법을 사용하기 전에 모든 설명서를 읽으십시오. 요구 사항을 충족하거나 충족하지 못할 수 있습니다. 사용 리팩토링 불합리한 것이 jQuery를 플러그인이 많이 있습니다 .delegate()또는 .on()그렇게하는 경우는, 당신은 더 나은 다시 구독 길 이죠.


1
설명 할 때 더 정확하십시오. 나는 사용법의 예가 흩어져있는 코드 줄보다 훨씬 낫다는 것을 의미합니다. Brian MacKay 설명을 참조하십시오. 그것은 완벽!
truthseeker

3
@Dan는 jQuery를 1.7 같이, .delegate()에 의해 대체 된.on()
가브리엘 Petrioli

@ GabyakaG.Petrioli 대체 된 것으로 알고 있지만이 답변은 일반적인 문제를 해결하는 것으로 보이므로 아직 업그레이드되지 않은 이전 버전의 jQuery와의 호환성을 최대화하고 싶었습니다. 내 대답은 이전 .live(...)에 1.7에서 공식적으로 사용되지 않아 향후 버전에서 제거 될 수 있다고 권장했습니다. .delegate()jQuery에서 한동안 지원되었으므로 조만간 제거되지 않을 것이므로 의도적으로 선택했습니다 . 그러나 나는 그것을 .on()사용할 수있는 사람들을 위해 언급 할 수 있도록 답변을 업그레이드 할 것입니다.
Dan Herbert

12
Sys가 아직 선언되지 않았을 가능성이 있기 때문에 $ (document) .ready 안에 prm var를 선언하고 연결하는 것이 좋습니다 (스크립트 위치에 따라 다름).
drake7707

1
@AhmedSamy jQuery.delegate()더 이상 사용하지 않는 것이 좋습니다 . jQuery.on()사용하기에 선호하는 API 로 대체되었습니다 . delegate()는의 특정 용도를위한 래퍼 일 뿐이며 on()앞으로 더 이상 사용되지 않을 수 있습니다. 이전에 언급 한 언급 delegate()은 jQuery 1.7 ( on()API 를 도입 한 )이 새로 릴리스 되었을 때 1 년 전에 작성 되었습니다. jQuery 1.9가 이미 출시되었으며 베타 2.0이 릴리스 준비 중이므로 delegate()새로운 코드에서 사용하지 않는 것이 좋습니다 .
Dan Herbert

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

<EditItemTemplate> 내부의 asp : GridView TextBox에 적합
Dan Randolph

이 솔루션의 문제점은 작동하는 동안 UpdatePanel의 비동기 포스트를 다시 종료하여 UpdatePanel을 다시 사용할 수 없게한다는 것입니다. (sigh)
MC9000

63

UpdatePanel 내부에서 jQuery를 사용한 사용자 컨트롤

이것은 질문에 대한 직접적인 대답은 아니지만 여기에서 찾은 답변을 읽음 으로써이 솔루션을 종합했으며 누군가가 유용하다고 생각했습니다.

User Control 내에서 jQuery textarea limiter를 사용하려고했습니다. 사용자 컨트롤이 UpdatePanel 내부에서 실행되기 때문에 까다 로웠으며 콜백에서 바인딩이 손실되었습니다.

이것이 페이지 인 경우 여기에 대한 답변이 직접 적용되었을 것입니다. 그러나 사용자 컨트롤은 헤드 태그에 직접 액세스 할 수 없으며 일부 답변에 따라 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>

그래서 .. 누군가 이것이 이것이 효과가 있다는 것을 알고 싶다고 생각했습니다.


2
나는 이것을 내 인생에서 사용할 수 없었습니다. 그런 다음 머리에서 바닥 글로 옮겼습니다. 긍정적이지 않지만 사용중인 ScriptManager를 따라야한다고 생각합니다.
Adam Youngers

필자의 경우 Sys를 정의하기 전에 스크립트를 추가하는 ScriptManager.RegisterClientScriptBlock을 사용하여 스크립트를 추가 했으므로 대신 RegisterStartupScript를 사용하게되었습니다 ( 여기에서 차이점 참조 )
Firas Assaad

2
멋진 답변! 내 asp.net 웹 앱에서 매력처럼 작동했습니다. + 당신을 위해
Pranesh Janarthanan

33

jQuery 1.3으로 업그레이드하고 다음을 사용하십시오.

$(function() {

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

});

참고 : 라이브는 대부분의 이벤트에서 작동하지만 전부는 아닙니다. 문서 에는 완전한 목록 이 있습니다 .


라이브를 사용하면 업데이트 패널의 문제가 해결됩니다. 뛰어 넘을 필요가 없습니다.
Tim Scarborough

페이지로드에서 발생해야하는 것은 무엇입니까? 예를 들어 얼룩말 스트라이핑 테이블? $ ( 'TABLE TR : nth-child (odd)'). addClass ( 'alt-row');
Adam Youngers

3
jQuery 1.7부터 업데이트하려면 .on ()을 대신 사용하는 것이 좋습니다
George

1
live()IE7 (jQuery 1.5.1 / VS2010 프로젝트)에서 메소드 를 사용하는 동안 심각한 오류가 발생했습니다 . 사용하는 경우 live()에 UpdatePanel 내부 V3.5 ASP.NET 일반 AutoPostback<asp:DropDownList />원인 브라우저에 의해 발행 된 추가 포스트 백 (중단) 컨텐츠가 부족 예상 1. 반대로이 개 부분 포스트 백 (가)의 원인이 Page.IsPostBackfalse내 경계 내부 상태를 죽이고 ( 통제 수단). 범인이 live () 메소드라는 것을 알았습니다. 사양에 따라 UpdatePanel에 의해 첫 번째 포스트 백이 중단되지만 대기열에 다른 포스트 백이없는 경우에만 다시 게시됩니다.
timmi4sa

20

시도해 볼 수도 있습니다.

<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 () 이후 페이지는 클라이언트 측에서로드 될 때마다 실행되는 ASP.NET ajax 이벤트입니다.


pageLoad는 업데이트 패널의 모든 ASync 포스트 백에서 이벤트를 복제합니다.
Zo 님이

17

내 대답은?

function pageLoad() {

  $(document).ready(function(){

기타

다른 많은 솔루션이 비참하게 실패한 매력처럼 작동했습니다.


텍스트 양에 따라 UserControl의 UpdatePanel에있는 Listview의 텍스트 영역 크기를 조정하는 데 적합합니다.
자원

업데이트 패널을 사용하여 포스트 백에서 dom jquery 함수가 올바르게 작동하도록 노력했지만이 솔루션은 효과가 있었고 두 가지 시나리오에서 함수 호출을 복제 할 필요가 없었습니다. 이것은 jquery 함수와 리스너를 사용 가능하게 유지했습니다. 참고 모든 스크립트와 jquery 라이브러리에 페이지 하단의 FORM [end] 태그 바로 앞에 포함되어 있습니다. 감사!!!
moto_geek

7

다음 방법 중 하나를 사용합니다.

  1. 함수에서 이벤트 바인딩을 캡슐화하고 페이지를 업데이트 할 때마다 실행하십시오. 이벤트를 동일한 요소에 여러 번 바인드하지 않도록 항상 특정 요소에 대한 이벤트 바인딩을 포함 할 수 있습니다.

  2. 기본적으로 자동 방법으로 방법 1을 수행 하는 라이브 쿼리 플러그인을 사용하십시오 . 이벤트 바인딩에 대해 원하는 제어량에 따라 선호도가 달라질 수 있습니다.


7

이것은 나를 위해 일했다 :

$(document).ready(function() {

    // Do something exciting

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

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

});

6

이 상황에서 pageLoad () 함수는 사용하기 매우 위험합니다. 이벤트가 여러 번 연결될 수 있습니다. .live ()는 문서 요소에 첨부되어 전체 페이지를 통과해야하므로 느리고 삐걱 거리지 않아야합니다.

지금까지 내가 본 가장 좋은 솔루션은 업데이트 패널 외부의 래퍼에서 jQuery .delegate () 함수를 사용하고 버블 링을 사용하는 것입니다. 그 외에는 UpdatePanel과 작동하도록 설계된 Microsoft의 Ajax 라이브러리를 사용하여 처리기를 항상 연결할 수 있습니다.


6

$(document).ready(function (){...})페이지 게시물 다시 후하지 작업은 다음과 Asp.page에서 자바 스크립트 기능 pageLoad을 사용합니다 :

<script type="text/javascript" language="javascript">
function pageLoad() {
// Initialization code here, meant to run once. 
}
</script>

네,뿐만 아니라 isPartialLoad 확인 : stackoverflow.com/questions/301473/...
스티브 그린

4

나는 비슷한 문제가 있었고 가장 효과가 좋은 방법은 이벤트 버블 링과 이벤트 위임을 사용하여 처리하는 것이 었습니다. 이벤트 위임의 좋은 점은 일단 설정되면 AJAX 업데이트 후에 이벤트를 리 바인드 할 필요가 없다는 것입니다.

내 코드에서 수행하는 작업은 업데이트 패널의 부모 요소에 대리자를 설정하는 것입니다. 이 부모 요소는 업데이트시 대체되지 않으므로 이벤트 바인딩에는 영향을 미치지 않습니다.

jQuery에서 이벤트 위임을 처리하기위한 좋은 기사와 플러그인이 많이 있으며이 기능은 1.3 릴리스에 포함될 것입니다. 참고로 사용하는 기사 / 플러그인은 다음과 같습니다.

http://www.danwebb.net/2008/2/8/event-delegation-made-easy-in-jquery

당신이 무슨 일이 일어나고 있는지 이해하면, 나는 당신이 모든 업데이트 후에 이벤트를 다시 바인딩하는 것을 기억하는 것보다 더 신뢰할 수있는 훨씬 더 우아한 솔루션을 찾을 것이라고 생각합니다. 또한 페이지를 언로드 할 때 하나의 이벤트를 바인드 해제 할 수있는 이점도 있습니다.


4

FWIW, 나는 mootools와 비슷한 문제가 발생했습니다. 내 이벤트를 다시 첨부하는 것이 올바른 이동이지만 요청이 끝날 때 수행해야했습니다.

var prm = Sys.WebForms.PageRequestManager.getInstance();
prm.add_endRequest(function() {... 

beginRequest로 인해 null 참조 JS 예외가 발생하는 경우 명심해야합니다.

건배



3
pageLoad = function () {
    $('#div').unbind();
    //jquery here
}

pageLoad 함수는 초기 페이지로드 및 모든 업데이트 패널 비동기 포스트 백에서 실행되므로이 ​​경우에 적합합니다. jquery가 updatepanel postback에서 작동하도록 unbind 메소드를 추가해야했습니다.

http://encosia.com/document-ready-and-pageload-are-not-the-same/


2

내 대답은 위의 모든 전문가 의견을 기반으로하지만 아래 코드는 누구나 각 포스트 백과 각 비동기 포스트 백에서 JavaScript 코드가 계속 실행되도록하는 데 사용할 수있는 다음 코드입니다.

제 경우에는 페이지 내에서 사용자 정의 컨트롤이있었습니다. 아래 코드를 사용자 정의 컨트롤에 붙여 넣으십시오.

<script type="text/javascript"> 
        var prm = Sys.WebForms.PageRequestManager.getInstance();
    prm.add_endRequest(EndRequestHandler);
    function EndRequestHandler(sender, args) {
        if (args.get_error() == undefined) {
            UPDATEPANELFUNCTION();
        }                   
    }

    function UPDATEPANELFUNCTION() {
        jQuery(document).ready(function ($) {
            /* Insert all your jQuery events and function calls */
        });
    }

    UPDATEPANELFUNCTION(); 

</script>

2

업데이트 패널은 모든로드 후 항상 Jquery를 내장 된 Scriptmanager 스크립트로 바꿉니다. 이와 같은 pageRequestManager의 인스턴스 메소드를 사용하면 더 좋습니다.

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

잘 작동합니다 ...


오래된 게시물이지만 나를 도와주는 게시물입니다. Sys.WebForms.PageRequestManager는 해당 시점에서만 사용할 수 있으므로 add_endRequest 코드의 위치는 UpdatePanel 안에 있어야합니다. 그러나 실제 기능은 해당 위치에있을 필요는 없습니다. 따라서 필자의 경우 바인딩 할 코드가 포함 된 script.js 파일이 있으며 함수에 포함되어 있습니다. 해당 script.js 파일에는 위 함수를 호출하는 document.ready 호출이 있습니다. 그런 다음 UpdatePanel에 add_endRequest 코드가 있으며 위의 함수도 호출합니다.
Kiran Ramaswamy

1

아래 스크립트를 사용하고 그에 따라 스크립트 본문을 변경하십시오.

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

0

Brian MacKay 님의 답변에 답변 :

JavaScript를 UserControl의 HTML에 직접 넣는 대신 ScriptManager를 통해 내 페이지에 JavaScript를 삽입합니다. 필자의 경우 UpdatePanel이 완료되고 반환 된 후 표시되는 양식으로 스크롤해야합니다. 이것은 코드 숨김 파일에 들어갑니다. 샘플에서는 이미 기본 컨텐츠 페이지에 prm 변수를 작성했습니다 .

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

0
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
        });
}
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.