javascript - jquery 이벤트 바인딩




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

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

단일 요소 :

$(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를 사용하고 있었지만 변경 여부는 알 수 없다.

페이지의 모든 선택 상자를 반복하고 .hover 이벤트를 바인딩하여 mouse on/off 너비를 .hover 위해 약간의 코드가 mouse on/off .

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

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

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


jQuery on().on() 메소드를 사용하여 이벤트 핸들러를 라이브 요소에 첨부하십시오.

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


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

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

내가 선택기를 사용하여 선호하고 문서에 적용됩니다.

이 속성은 문서에 바인딩되며 페이지로드 후에 렌더링 될 요소에 적용될 수 있습니다.

예 :

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

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

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>


동적으로 추가 된 요소에서 $.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(){} );

요소가 배치 된 "MAIN"클래스를 기록해 두십시오 (예 :

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

위의 시나리오에서, jQuery가 볼 MAIN 객체는 "container"입니다.

그러면 기본적으로 컨테이너 아래에 ul , liselect 와 같은 요소 이름이 있습니다.

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

요소를 만들고 이벤트를 바인드하는 보다 유연한 솔루션 ( source )

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

참고 : 이렇게하면 각 요소에 대한 이벤트 처리기 인스턴스가 만들어집니다 (루프에서 사용될 때 성능에 영향을 줄 수 있음)


이 작업은 이벤트 위임을 통해 수행됩니다. 이벤트는 래퍼 클래스 요소에 바인딩되지만 selector-class 요소에 위임됩니다. 이것이 작동하는 방식입니다.

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

노트 :

래퍼 클래스 요소는 이전의 어떤 것도 될 수 있습니다. 문서, 본문 또는 랩퍼. 래퍼는 이미 존재해야합니다.


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

이벤트 바인딩 호출을 함수로 간단하게 래핑 한 다음 두 번 호출 할 수 있습니다. 한 번은 문서 준비가 완료되고 이벤트가 끝나면 새 DOM 요소가 추가됩니다. 그렇게하면 기존 요소에 동일한 이벤트를 두 번 바인딩하지 않으려 고하므로 기존 이벤트의 바인딩을 해제하거나 새로 만든 DOM 요소에만 바인딩하는 것이 좋습니다. 코드는 다음과 같습니다.

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

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

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

이벤트가 바인드 될 때 존재하는 모든 페이지 는 존재하지 않으며 페이지가 클래스 이름 버튼 을 사용하여 동적으로 요소작성 하는 경우 이미 존재하는 상위에 이벤트를 바인드합니다

$(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>


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 작동하지 않습니다.


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

jQuery 1.8 jQuery.fn 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>


jQuery 1.7부터 jQuery.fn.on 을 사용해야한다.

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

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

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

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

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

... 다음 on() 시그니처로 대체 될 수 있습니다.

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

예를 들어, 페이지가 동적으로 클래스 이름 dosomething 을 사용하여 요소를 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>

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




unobtrusive-javascript