동적 HTML을로드 한 후 클릭 이벤트를 추가하기위한 jQuery .live () 및 .on () 메소드


217

.live () 메서드가 더 이상 사용되지 않는 jQuery v.1.7.1을 사용하고 있습니다.

내가 겪고있는 문제는 다음을 사용하여 html을 요소에 동적으로로드 할 때입니다.

$('#parent').load("http://..."); 

클릭 이벤트를 나중에 추가하려고 시도하면 다음 방법 중 하나를 사용하여 이벤트를 등록하지 않습니다.

$('#parent').click(function() ...); 

또는

// according to documentation this should be used instead of .live()
$('#child').on('click', function() ...); 

이 기능을 수행하는 올바른 방법은 무엇입니까? 그것은 나를 위해 .live ()에서만 작동하는 것 같지만 그 방법을 사용해서는 안됩니다. #child는 동적으로로드 된 요소입니다.

감사.


25
"추천되지 않는" 이유는 무엇 입니까? 문서를 믿지 않습니까?

6
그것은 아니에요 가정으로 사용되지 않는 : 그것은 한다 추천하지 않습니다. jQuery doco를.live() 살펴보면 .live()사용 목적 .delegate()또는 .on()버전 1.7 이상인지 여부에 따라 기존 용도를 다시 쓰는 방법을 알려줍니다 . .click()언급 한대로 "나중에" 처리기를 추가하면 ( 예 : 요소를 동적으로로드 한 후) 작동해야합니다 . 요소 .click() 를 동적으로로드 하기 전에 할당해야하는 유일한 문제가 있습니다.
— nnnnnn

기본적으로 의미하는 바이므로 '명백하게'로 표현을 변경했습니다. 어쨌든, .load () 이벤트가 비동기이므로 #child 요소는 성공 처리기에서만 안정적으로 인식 될 수 있다는 것을 이해합니다.
— Sean Thoman

답변:


606

클릭 핸들러가 동적으로로드되는 요소에 대해 작동하도록하려면 동적으로로드되지 않는 상위 오브젝트에 이벤트 핸들러를 설정하고 다음과 같이 동적 오브젝트와 일치하는 선택기를 제공하십시오.

$('#parent').on("click", "#child", function() {});

이벤트 핸들러는 #parent객체에 첨부되며 click 이벤트가 시작된 객체로 버블 링 #child될 때마다 클릭 핸들러가 시작됩니다. 이것을 위임 된 이벤트 처리라고합니다 (이벤트 처리는 부모 개체에 위임됩니다).

당신이에 이벤트를 첨부 할 수 있기 때문에이 방법을 끝낼 #parent짝수 때 개체 #child개체가 아직 존재하지 않지만, 나중에 존재하고 클릭 도착 때까지 클릭 이벤트 의지 거품까지 #parent개체가, 그것에서 유래 것을 볼 수 #child와 클릭 한 번으로 이벤트를 처리하는 이벤트 핸들러가 #child있습니다.


23
좋은 설명! 내가 전에 주위에 내 머리를 정리 적이 없습니다 live()대 on()하지만 오늘 밤 난 아직 다시 시도하기로 결정하고 설명 즉시 내가 모든 함께 실종되었던 것을 밝혔다. 감사!
— MikeSchinkel

6
백만 업 . 동적으로 생성 된 어린이를 위해 jQuery에서 이것이 가능하다는 것을 깨닫기 전에 녹아웃을 사용하기 시작했습니다. 대단히 감사합니다.
— 브록 헨슬리

9
작은 책은« on () » 에 대한 jQuery 문서의 전체 페이지보다 도움이되었습니다 . 고마워요!
— 콜레스테롤

@ jfriend00 호버가 아닌 호버링 상황에 동일한 프로세스를 적용하는 방법을 알고 있습니까? 이것에 대해 이야기하는 출처가 있습니까?
— klewis

@blackhawk- 이 답변을 참조하십시오 . mouseenter및 mouseleave이벤트에 등록하고 트리거 된 핸들러 내에서 테스트 할 수 있습니다 . jQuery의 의사 "호버"이벤트는 위임과 함께 사용할 수 없습니다.
— jfriend00

33

이 시도:

$('#parent').on('click', '#child', function() {
    // Code
});

로부터 $.on()문서 :

이벤트 핸들러는 현재 선택된 요소에만 바인딩됩니다. 코드가 호출 할 때 페이지에 존재해야합니다 .on().

귀하의 #child전화 할 때 요소는 존재하지 않는 $.on()이벤트가 (달리 구속되지 않도록, 그것에 $.live()). #parent그러나 이벤트 가 존재하므로 이벤트를 바인딩하는 것이 좋습니다.

위 코드에서 두 번째 인수는 이벤트가 #parentfrom에서 버블 링 된 경우에만 트리거하는 '필터'역할을합니다 #child.


$ .load () 메소드 다음에 $ .on () 메소드를 호출하면 그 시점에 #child 요소가없는 이유는 무엇입니까?
— Sean Thoman

6
@SeanThoman- .load()메소드 뒤의 코드가 아닌 메소드 의 성공 핸들러에서 호출해야 합니다 .load(). #child성공 핸들러가 실제로 실행되고 이전이 아닌 경우에만로드되는 것으로 알려져 있습니다.
— jfriend00

심지어 DOM에 다시 가져온 데이터를 삽입하는 데 걸리는 시간도 연결되지 않을 수 있음을 의미합니다. 최근에 많은 단일 페이지 앱 작업을 해왔으며 표준은 var $ body = $ ( 'body')입니다. $ body.on ( "event", ".element / # class", function (e) {}); 모두를위한. 선택기 1 개. 로드되거나로드되지 않은 것에 대해 걱정할 필요가 없습니다.
— lupos

21

$(document).on('click', '.selector', function() { /* do stuff */ });

편집 : 나는 이것이 작동하는 방법에 대해 조금 더 많은 정보를 제공하고 있습니다. 왜냐하면 단어 때문입니다. 이 예제에서는 전체 문서에 리스너를 배치합니다.

이 때 click어떤 요소 (들) 일치에 .selector, 이벤트가 주 문서까지 거품 - 너무 오래 다른 청취자가 없습니다로 그 호출 event.stopPropagation()방법 - 부모 요소에 이벤트의 버블 맨 것이다.

특정 요소 또는 요소 집합에 바인딩하는 대신 지정된 선택기와 일치하는 요소에서 오는 이벤트를 수신하고 있습니다. 즉, 현재 존재하는 요소와 동적으로 추가 된 요소를 자동으로 일치시키는 리스너를 한 번에 하나씩 만들 수 있습니다.

성능 및 메모리 사용률 (대규모 응용 프로그램)을 포함하여 몇 가지 이유로 현명합니다.

편집하다:

분명히, 당신 이들을 수있는 가장 가까운 부모 요소가 더 좋으며, document이벤트를 모니터링하려는 자식이 부모 요소 내에 있는 한 다른 요소를 대신 사용할 수 있습니다 ...하지만 실제로 할 일이 없습니다. 질문으로.


23
그는 시도했다 $(element).on(...). 이것은입니다 $(document).on(...,element,...). 다른 짐승.
— cHao

@ArnoldRoa 예, 더 나은 성능. 여러 하위에 리스너가없고 DOM이 수정 될 때마다 리스너를 다시 적용 할 필요가 없으며 기본적으로 이벤트가 DOM을 통해 버블 링됩니다. 한 번 실행하면 선택기와 일치하는 모든 하위 항목을 클릭하면 지정된 기능이 트리거됩니다.
— L422Y

@ L422Y의 의견은 매우 오해의 소지가 있습니다. 성능에 미치는 영향에 대해 궁금하다면, 한 번 봐 걸릴 @ jfriend00의 의견 에 제라드의 대답 @
— 돌풍 밴 드 월마트

@GustvandeWal 어떻게 오해의 소지가 있습니까? 부모 요소에서 한 번만 이벤트를 수신하는 것에 비해 백 $ (this) .on (...)을 발행하면 성능이 훨씬 뛰어납니다.
— L422Y

이벤트 첨부에 대해서만 이야기하고 있습니다. 실제 성능 병목 현상은 이벤트를 첨부해야하는 많은 양의 요소가 아니라 너무 많은 리스너가 발생합니다 (위임하는 것과 같은).
— Gust van de Wal

12

1.7의 .live ()는 다음과 같습니다.

$(document).on('click', '#child', function() ...); 

기본적으로 클릭 이벤트에 대한 문서를보고 #child에 대해 필터링하십시오.


그것이 이벤트 핸들러가 문서에 첨부되는 방식이기 때문 .live()입니다.
— cHao

17
.live()더 이상 사용되지 않는 한 가지 이유 는 모든 라이브 이벤트 핸들러를 문서 오브젝트에 배치하는 것이 좋지 않기 때문입니다. 상황이 정말 느려질 수 있습니다. 이벤트가 문서까지 버블 링되어야 할뿐만 아니라 문서 객체를 살펴 보는 이벤트 핸들러가 많이있을 수 있습니다. 가장 큰 장점은 .on()실제 객체에 훨씬 가까운 부모 객체에 부착하여 성능을 크게 향상시킬 수 있다는 것입니다. 따라서 ... .on()문서 객체와 함께 사용하지 않는 것이 좋습니다 . 더 가까운 부모 객체를 선택하는 것이 훨씬 좋습니다.
— jfriend00

설명해 주셔서 감사합니다. 이벤트의 성능에 대한 가치는 on ()으로 훨씬 향상되었으므로 예전보다 문제가 적어야합니다. 부모에게 첨부하는 경우 부모가 문서에 존재하는 부모이거나 비슷한 문제가 발생한다고 가정합니다.
— Jared

최악의 경우, 이것은 않습니다 비추천 에뮬레이션 .live()방식을; 그러나 위임을 제어하는 ​​능력은 확실히 유리합니다.
— Dan Lugg

9

답이 늦다는 것을 알고 있지만 .live () 메서드에 대한 polyfill을 만들었습니다. jQuery 1.11에서 테스트했으며 꽤 잘 작동하는 것 같습니다. 가능한 한 .on () 메서드를 구현해야하지만 모든 프로젝트에서 모든 .live () 호출을 동등한 .on () 호출로 변환 할 수없는 큰 프로젝트에서는 다음과 같은 경우가 있습니다. 작업:

if(jQuery && !jQuery.fn.live) {
    jQuery.fn.live = function(evt, func) {
        $('body').on(evt, this.selector, func);
    }
}

jQuery를로드 한 후 live ()를 호출하기 전에이를 포함하십시오.


5

.on ()은 jQuery 버전 1.7 이상입니다. 이전 버전이있는 경우 다음을 사용하십시오.

$("#SomeId").live("click",function(){
    //do stuff;
});

8
OP는 "jQuery v.1.7.1을 사용하고 있습니다"라고 말합니다
— Selvakumar Arumugam

1
@ jfriend-- 내를 downvoting하는 대신 자신의 답변을 게시하지 않으시겠습니까? 1.6보다 작은 모든 버전에서 매일 live ()를 사용하며 정상적으로 작동합니다. 나는 당신이 문서를 잘 읽는 것을 볼 수 있지만 때로는 누군가를 위해 무언가를 실천하는 것이 더 도움이됩니다. .live () 작동합니다. 기간.
— Matt Cashatt

5
@ MatatwPatrickCashatt-나는 내 자신의 답변을 게시하고 당신의 의견을 내리지 않았습니다-그런 맹목적인 가정을하지 마십시오. 1.7 이전 에는 jQuery 문서가 권장하고 더 이상 사용하지 않는 .delegate()것보다 성능이 훨씬 뛰어납니다 . 예, 여전히 작동하지만 SO에 대한 답변은 더 나은 방법을 권장해야합니다. 나는 여기서 20 번 이것을 보았습니다. SO 로 여기에 코드를 게시하면 코드가 다운 투표됩니다 (심하게 다른 문제가 없으면 일반적으로 나에 의해 아닙니다). .live().live().live().live()
— jfriend00

1
나는 downvote하지 못했지만, 비록은 .live()확실히 심지어 버전을 여전히 사용한다 1.7에서 작동 .delegate()또는 .on()때문에 .live()좋은 이유를 위해 사용됩니다. 두 가지 새로운 기능에 대한 구문 변경이 주목되는 한 제대로 작동합니다.
— nnnnnn

1
@ jfriend00- 당신은 절대적으로 맞습니다. 긴 하루. 사과드립니다.
— Matt Cashatt

3

내 프로젝트에서 'live'를 사용했지만 친구 중 한 명이 라이브 대신 'on'을 사용해야한다고 제안했습니다. 그리고 내가 그것을 사용하려고했을 때 나는 당신처럼 문제가 발생했습니다.

내 페이지에서 버튼 테이블 행과 많은 DOM 항목을 동적으로 만듭니다. 하지만 마법을 사용할 때 사라졌습니다.

어린 아이처럼 사용하는 것과 같은 다른 솔루션은 매번 클릭 할 때마다 함수를 호출합니다. 그러나 나는 다시 일어날 수있는 방법을 찾고 여기에 해결책이 있습니다.

다음과 같이 코드를 작성하십시오.

function caller(){
    $('.ObjectYouWntToCall').on("click", function() {...magic...});
}

발신자 호출 (); 이처럼 페이지에서 객체를 만든 후

$('<dom class="ObjectYouWntToCall">bla... bla...<dom>').appendTo("#whereeveryouwant");
caller();

이렇게하면 페이지를 클릭 할 때마다 함수가 호출되지 않습니다.

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