[javascript] 동적으로 생성 된 요소에 대한 이벤트 바인딩?

페이지의 모든 선택 상자를 반복 .hover하고 너비를 사용하여 약간의 돌리기를하기 위해 이벤트를 바인딩하는 코드 가 있습니다 mouse on/off.

이것은 페이지 준비시 발생하며 정상적으로 작동합니다.

내가 가진 문제는 초기 루프 후 Ajax 또는 DOM을 통해 추가 한 선택 상자에 이벤트가 바인딩되지 않는다는 것입니다.

이 플러그인 ( jQuery Live Query Plugin ) 을 찾았 지만 플러그인을 사용하여 페이지에 다른 5k를 추가하기 전에 누군가 jQuery를 사용하거나 다른 옵션으로이를 수행하는 방법을 알고 싶습니다.



답변

jQuery 1.7부터 다음을 사용해야합니다 jQuery.fn.on.

$(staticAncestors).on(eventName, dynamicChild, function() {});

이 전에 권장되는 접근 방식은 다음을 사용하는 것입니다 live().

$(selector).live( eventName, function(){} );

그러나 live()1.7에서는 더 이상 사용되지 않으며 on()1.9에서는 완전히 제거되었습니다. live()서명 :

$(selector).live( eventName, function(){} );

… 다음 on()서명 으로 대체 할 수 있습니다 .

$(document).on( eventName, selector, function(){} );

예를 들어, 페이지에서 클래스 이름으로 요소를 동적으로 생성 하는 경우 이미 존재하는 상위 항목에dosomething 이벤트를 바인딩 합니다 (여기서는 문제의 핵심이므로 바인딩 할 내용이 필요합니다. 동적 콘텐츠)의 경우 가장 쉬운 옵션은 document입니다. 염두에 두는 document것이 가장 효율적인 방법은 아닙니다 .

$(document).on('mouseover mouseout', '.dosomething', function(){
    // what you want to happen when mouseover and mouseout 
    // occurs on elements that match '.dosomething'
});

이벤트가 바인드 될 때 존재하는 모든 상위는 괜찮습니다. 예를 들어

$('.buttons').on('click', 'button', function(){
    // do something here
});

에 적용

<div class="buttons">
    <!-- <button>s that are generated dynamically and added here -->
</div>


답변

의 설명서에 좋은 설명이 jQuery.fn.on있습니다.

한마디로 :

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

따라서 다음 예제 #dataTable tbody tr에서는 코드가 생성되기 전에 존재해야합니다.

$("#dataTable tbody tr").on("click", function(event){
    console.log($(this).text());
});

새 HTML이 페이지에 삽입되는 경우 다음에 설명 된대로 위임 된 이벤트를 사용하여 이벤트 핸들러를 첨부하는 것이 좋습니다.

위임 된 이벤트 는 나중에 문서에 추가 된 하위 요소의 이벤트를 처리 할 수 ​​있다는 이점이 있습니다. 예를 들어, 테이블이 존재하지만 코드를 사용하여 행이 동적으로 추가되면 다음이 처리합니다.

$("#dataTable tbody").on("click", "tr", function(event){
    console.log($(this).text());
});

아직 생성되지 않은 하위 요소의 이벤트를 처리하는 기능 외에도 위임 된 이벤트의 또 다른 장점은 많은 요소를 모니터링해야 할 때 오버 헤드가 훨씬 낮아질 수 있다는 것입니다. 에 1,000 개의 행이있는 데이터 테이블 tbody에서 첫 번째 코드 예제는 1,000 개의 요소에 핸들러를 연결합니다.

위임 된 이벤트 접근 방식 (두 번째 코드 예)은 이벤트 핸들러를 하나의 요소 ()에만 연결하며 이벤트 tbody는 클릭에서에서로 한 수준 만 버블 링하면 tr됩니다 tbody.

참고 : 위임 된 이벤트는 SVG에서 작동하지 않습니다 .


답변

이것은 라이브러리 나 플러그인이없는 순수한 JavaScript 솔루션입니다.

document.addEventListener('click', function (e) {
    if (hasClass(e.target, 'bu')) {
        // .bu clicked
        // Do your thing
    } else if (hasClass(e.target, 'test')) {
        // .test clicked
        // Do your other thing
    }
}, false);

hasClass이다

function hasClass(elem, className) {
    return elem.className.split(' ').indexOf(className) > -1;
}

Live demo

신용은 Dave와 Sime Vidas에게갑니다

보다 현대적인 JS를 사용하여 hasClass다음과 같이 구현할 수 있습니다.

function hasClass(elem, className) {
    return elem.classList.contains(className);
}


답변

객체를 만들 때 객체에 이벤트를 추가 할 수 있습니다. 다른 시간에 여러 객체에 동일한 이벤트를 추가하는 경우 명명 된 함수를 만드는 것이 좋습니다.

var mouseOverHandler = function() {
    // Do stuff
};
var mouseOutHandler = function () {
    // Do stuff
};

$(function() {
    // On the document load, apply to existing elements
    $('select').hover(mouseOverHandler, mouseOutHandler);
});

// This next part would be in the callback from your Ajax call
$("<select></select>")
    .append( /* Your <option>s */ )
    .hover(mouseOverHandler, mouseOutHandler)
    .appendTo( /* Wherever you need the select box */ )
;


답변

이벤트 바인딩 호출을 함수로 래핑 한 다음 문서에서 한 번 준비하고 새 DOM 요소를 추가하는 이벤트 후에 한 번만 두 번 호출 할 수 있습니다. 그렇게하면 기존 요소에 동일한 이벤트를 두 번 바인딩하지 않으려면 기존 이벤트를 바인드 해제하거나 새로 작성된 DOM 요소에만 바인딩해야합니다. 코드는 다음과 같습니다.

function addCallbacks(eles){
    eles.hover(function(){alert("gotcha!")});
}

$(document).ready(function(){
    addCallbacks($(".myEles"))
});

// ... add elements ...
addCallbacks($(".myNewElements"))


답변

; .live()대신에 사용하십시오 .bind(). 는 Ajax 요청이 실행 된 후 체크 박스에 .live()바인딩 .hover됩니다.


답변

동적으로 생성 된 요소에 대한 이벤트 바인딩

단일 요소 :

$(document.body).on('click','.element', function(e) {  });

자식 요소 :

 $(document.body).on('click','.element *', function(e) {  });

추가됨을 확인하십시오 *. 해당 요소의 모든 자식에 대해 이벤트가 트리거됩니다.

나는 그것을 알아 차렸다 :

$(document.body).on('click','.#element_id > element', function(e) {  });

더 이상 작동하지 않지만 이전에는 작동했습니다. Google CDN 에서 jQuery를 사용 하고 있지만 변경했는지는 알 수 없습니다.