etc./StackOverFlow

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

청렴결백한 만능 재주꾼 2022. 1. 14. 12:32
반응형

질문자 :Eli


페이지의 모든 선택 상자를 반복하고 .hover mouse on/off 의 너비로 약간의 비틀기를 수행하는 약간의 코드가 있습니다.

이것은 페이지 준비에서 발생하며 잘 작동합니다.

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

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



jQuery 1.7 부터 선택기 매개변수가 채워진 상태에서 jQuery.fn.on 을 사용해야 합니다.

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

설명:

이를 이벤트 위임이라고 하며 다음과 같이 작동합니다. 이벤트는 처리해야 하는 요소의 정적 부모( staticAncestors 이 jQuery 핸들러는 이벤트가 이 요소 또는 하위 요소 중 하나에서 트리거될 때마다 트리거됩니다. 그런 다음 핸들러는 이벤트를 트리거한 요소가 선택기( dynamicChild )와 일치하는지 확인합니다. 일치하는 항목이 있으면 사용자 지정 처리기 기능이 실행됩니다.


이전에 live() 를 사용하는 것이었습니다.

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

그러나 live() on() 을 위해 1.7에서 더 이상 사용되지 않으며 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>

Community Wiki

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

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

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

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


Ronen Rabinovici

이것은 라이브러리나 플러그인이 없는 순수한 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; }

라이브 데모

크레딧은 Dave와 Sime Vidas에게 돌아갑니다.

최신 JS를 사용하여 hasClass 를 다음과 같이 구현할 수 있습니다.

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

아래에 포함된 동일한 jsfiddle Live 데모:

 function hasClass(elem, className) { return elem.classList.contains(className); } document.addEventListener('click', function(e) { if (hasClass(e.target, 'bu')) { alert('bu'); document.querySelector('.bu').innerHTML = '<div class="bu">Bu<div class="tu">Tu</div></div>'; } else if (hasClass(e.target, 'test')) { alert('test'); } else if (hasClass(e.target, 'tu')) { alert('tu'); } }, false);
 .test, .bu, .tu { border: 1px solid gray; padding: 10px; margin: 10px; }
 <div class="test">Test <div class="bu">Bu</div>test </div>


Ram Patra

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

 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 */ ) ;

nickf

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

 function addCallbacks(eles){ eles.hover(function(){alert("gotcha!")}); } $(document).ready(function(){ addCallbacks($(".myEles")) }); // ... add elements ... addCallbacks($(".myNewElements"))

Greg Borenstein

사용하려고 .live() 대신 .bind() ; .hover .live() 는 Ajax 요청이 실행된 후 .hover를 확인란에 바인딩합니다.


user670265

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

단일 요소:

 $(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를 사용하고 있지만 변경했는지 모르겠습니다.


MadeInDreams

선택기를 사용하는 것을 선호하며 문서에 적용합니다.

이것은 문서에 바인딩되며 페이지 로드 후에 렌더링될 요소에 적용됩니다.

예를 들어:

 $(document).on("click", 'selector', function() { // Your code here });

Vatsal

live() 메서드를 사용하여 요소(새로 생성된 요소 포함)를 onclick 이벤트와 같은 이벤트 및 핸들러에 바인딩할 수 있습니다.

다음은 내가 작성한 샘플 코드입니다. 여기서 live() 메서드가 선택한 요소(새로 생성된 요소 포함)를 이벤트에 바인딩하는 방법을 볼 수 있습니다.

 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> <title>Untitled Document</title> </head> <body> <script src="http://code.jquery.com/jquery-latest.js"></script> <script src="http://ajax.aspnetcdn.com/ajax/jquery.ui/1.8.16/jquery-ui.min.js"></script> <input type="button" id="theButton" value="Click" /> <script type="text/javascript"> $(document).ready(function() { $('.FOO').live("click", function (){alert("It Works!")}); var $dialog = $('<div></div>').html('<div id="container"><input type ="button" id="CUSTOM" value="click"/>This dialog will show every time!</div>').dialog({ autoOpen: false, tite: 'Basic Dialog' }); $('#theButton').click(function() { $dialog.dialog('open'); return('false'); }); $('#CUSTOM').click(function(){ //$('#container').append('<input type="button" value="clickmee" class="FOO" /></br>'); var button = document.createElement("input"); button.setAttribute('class','FOO'); button.setAttribute('type','button'); button.setAttribute('value','CLICKMEE'); $('#container').append(button); }); /* $('#FOO').click(function(){ alert("It Works!"); }); */ }); </script> </body> </html>

Fazi

이것은 이벤트 위임에 의해 수행됩니다 . 이벤트는 래퍼 클래스 요소에 바인딩되지만 선택자 클래스 요소에 위임됩니다. 이것이 작동하는 방식입니다.

 $('.wrapper-class').on("click", '.selector-class', function() { // Your code here });

그리고 HTML

 <div class="wrapper-class"> <button class="selector-class"> Click Me! </button> </div>

#참고: 래퍼 클래스 요소는 무엇이든 될 수 있습니다. 문서, 본문 또는 래퍼. 래퍼가 이미 존재해야 합니다 . 그러나 selector 는 페이지 로드 시 표시될 필요가 없습니다. 나중에 올 수 있으며 이벤트는 실패 없이 selector 바인딩됩니다.


Mustkeem K

또 다른 솔루션은 요소를 생성할 때 리스너를 추가하는 것입니다. 리스너를 본문에 넣는 대신 요소를 만드는 순간 요소에 리스너를 넣습니다.

 var myElement = $('<button/>', { text: 'Go to Google!' }); myElement.bind( 'click', goToGoogle); myElement.append('body'); function goToGoogle(event){ window.location.replace("http://www.google.com"); }

Martin Da Rosa

이런 식으로 시도하십시오 -

 $(document).on( 'click', '.click-activity', function () { ... });

Rohit Suthar

요소가 배치된 "MAIN" 클래스를 기록해 두십시오. 예를 들어,

 <div class="container"> <ul class="select"> <li> First</li> <li>Second</li> </ul> </div>

위의 시나리오에서 jQuery가 감시할 MAIN 개체는 "컨테이너"입니다.

ul , liselect 와 같은 컨테이너 아래에 요소 이름이 있습니다.

 $(document).ready(function(e) { $('.container').on( 'click',".select", function(e) { alert("CLICKED"); }); });

Aslan Kaya

jQuery(html, attributes) 사용하여 동적으로 생성된 요소에 이벤트를 첨부할 수 있습니다.

jQuery 1.8 부터 모든 jQuery 인스턴스 메서드( jQuery.fn 메서드)를 두 번째 매개변수에 전달된 객체의 속성으로 사용할 수 있습니다.

 function handleDynamicElementEvent(event) { console.log(event.type, this.value) } // create and attach event to dynamic element jQuery("<select>", { html: $.map(Array(3), function(_, index) { return new Option(index, index) }), on: { change: handleDynamicElementEvent } }) .appendTo("body");
 <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"> </script>


guest271314

당신은 사용할 수 있습니다

 $('.buttons').on('click', 'button', function(){ // your magic goes here });

또는

 $('.buttons').delegate('button', 'click', function() { // your magic goes here });

이 두 방법은 동일하지만 매개변수의 순서가 다릅니다.

참조: jQuery 대리자 이벤트


Mensur Grišević

동적으로 생성된 요소가 클릭에 응답하지 않는 이유는 다음과 같습니다.

 var body = $("body"); var btns = $("button"); var btnB = $("<button>B</button>"); // `<button>B</button>` is not yet in the document. // Thus, `$("button")` gives `[<button>A</button>]`. // Only `<button>A</button>` gets a click listener. btns.on("click", function () { console.log(this); }); // Too late for `<button>B</button>`... body.append(btnB);
 <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> <button>A</button>

이 문제를 해결하려면 모든 클릭을 수신하고 소스 요소를 확인해야 합니다.

 var body = $("body"); var btnB = $("<button>B</button>"); var btnC = $("<button>C</button>"); // Listen to all clicks and // check if the source element // is a `<button></button>`. body.on("click", function (ev) { if ($(ev.target).is("button")) { console.log(ev.target); } }); // Now you can add any number // of `<button></button>`. body.append(btnB); body.append(btnC);
 <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> <button>A</button>

이것을 "이벤트 위임"이라고 합니다. 좋은 소식입니다. jQuery에 내장된 기능입니다 :-)

 var i = 11; var body = $("body"); body.on("click", "button", function () { var letter = (i++).toString(36).toUpperCase(); body.append($("<button>" + letter + "</button>")); });
 <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> <button>A</button>


leaf

이벤트가 바인딩될 때 존재하는 모든 요소가 없으며 페이지에서 클래스 이름 버튼 으로 요소를 동적으로 생성 하는 경우 이미 존재하는 부모에 이벤트를 바인딩합니다.

 $(document).ready(function(){ //Particular Parent chield click $(".buttons").on("click","button",function(){ alert("Clicked"); }); //Dynamic event bind on button class $(document).on("click",".button",function(){ alert("Dymamic Clicked"); }); $("input").addClass("button"); });
 <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script> <div class="buttons"> <input type="button" value="1"> <button>2</button> <input type="text"> <button>3</button> <input type="button" value="5"> </div> <button>6</button>


Ankit Kathiriya

이벤트를 이미 존재하는 부모에 바인딩합니다.

 $(document).on("click", "selector", function() { // Your code here });

truongnm

요소를 생성하고 이벤트를 바인딩하는 또 다른 유연한 솔루션( 소스 )

 // creating a dynamic element (container div) var $div = $("<div>", {id: 'myid1', class: 'myclass'}); //creating a dynamic button var $btn = $("<button>", { type: 'button', text: 'Click me', class: 'btn' }); // binding the event $btn.click(function () { //for mouseover--> $btn.on('mouseover', function () { console.log('clicked'); }); // append dynamic button to the dynamic container $div.append($btn); // add the dynamically created element(s) to a static element $("#box").append($div);

참고: 이렇게 하면 각 요소에 대한 이벤트 핸들러 인스턴스가 생성 됩니다(루프에서 사용될 때 성능에 영향을 미칠 수 있음)


Prasad De Silva

jQuery http://api.jquery.com/on/ .on() 메서드를 사용하여 이벤트 핸들러를 라이브 요소에 연결합니다.

또한 버전 1.9부터 .live() 메서드가 제거되었습니다.


Kalpesh Patel

document 수준 이벤트 리스너를 스크립팅하는 것보다 모듈식 함수 방식으로 이벤트 리스너를 배포하는 것을 선호합니다. 그래서 저는 아래와 같이 합니다. 동일한 이벤트 리스너로 요소를 초과 구독할 수 없으므로 리스너를 두 번 이상 연결하는 것에 대해 걱정하지 마십시오. 하나만 고정됩니다.

 var iterations = 4; var button; var body = document.querySelector("body"); for (var i = 0; i < iterations; i++) { button = document.createElement("button"); button.classList.add("my-button"); button.appendChild(document.createTextNode(i)); button.addEventListener("click", myButtonWasClicked); body.appendChild(button); } function myButtonWasClicked(e) { console.log(e.target); //access to this specific button }


Ronnie Royston

<html> <head> <title>HTML Document</title> <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/1.12.0/jquery.min.js"></script> </head> <body> <div id="hover-id"> Hello World </div> <script> jQuery(document).ready(function($){ $(document).on('mouseover', '#hover-id', function(){ $(this).css('color','yellowgreen'); }); $(document).on('mouseout', '#hover-id', function(){ $(this).css('color','black'); }); }); </script> </body> </html>

Fakhrul Hasan

동적으로 추가된 요소에서 문제 없이 $.bind$.unbind 작동하도록 하는 솔루션을 찾고 있었습니다.

on() 이 이벤트를 첨부하는 트릭을 만들 때 내가 온 이벤트에 대해 가짜 바인딩 해제를 생성하기 위해 다음을 수행합니다.

 const sendAction = function(e){ ... } // bind the click $('body').on('click', 'button.send', sendAction ); // unbind the click $('body').on('click', 'button.send', function(){} );

Evhz

출처 : http:www.stackoverflow.com/questions/203198/event-binding-on-dynamically-created-elements

반응형