동적 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- 이 답변을 참조하십시오 . mouseentermouseleave이벤트에 등록하고 트리거 된 핸들러 내에서 테스트 할 수 있습니다 . 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.