2012-02-28 3 views
17

jQuery를 사용하여 전체 DOM 트리를 통해 변경 사항을 수신하려면 어떻게해야합니까?jQuery : DOM 변경 사항을 수신 대기하는 방법?

내 특정 문제 : 모든 html 요소에서 hover을 수행 할 때 세련된 방식으로 title 속성의 내용을 표시하는 '툴팁'기능이 있습니다. 그러나 마우스를 올리면 표준 브라우저가 title을 자체 상자에 렌더링합니다. 나는 그것을 억누르고 싶다. 그래서 내가 처음 생각한 것은 title 속성의 내용을 처음으로 페이지가로드 될 때 사용자 정의 (HTML5) data-title 속성으로 이동 한 다음 내 툴팁 기능이 data-title으로 작동합니다.

문제는 나중에 HTML을 동적으로 추가/제거/변경할 수 있으므로 해당 요소를 '다시 바인딩'해야합니다. 제목을 다시 변경해야합니다. 그러한 변경 사항을 듣고 요소를 자동으로 리 바인드 할 이벤트 리스너가 있으면 좋을 것입니다.

+0

가능한 중복 [DOM을가 변경되었을 때 확인하는 방법?] (http://stackoverflow.com/questions/3744706/how-to-identify-when-the -dom-has-been-changed) –

+2

은 DOM의 모든 변경 사항을 청취하려고 할 때처럼 보이고 매번 요소를 검색하면 비용이 많이들 것입니다. – charlietfl

+0

가능한 [jQuery DOM 변경 리스너가 있습니까?] (http://stackoverflow.com/questions/2844565/is-there-a-jquery-dom-change-listener) – APerson

답변

33

내 추측은 당신이 DOM 돌연변이 이벤트를 수신 할 것입니다. 마우스 클릭과 같은 일반적인 자바 스크립트 이벤트와 마찬가지로 DOM 돌연변이 이벤트로이를 수행 할 수 있습니다.

이 참조 : W3 MutationEvent

예 :

$("element-root").bind("DOMSubtreeModified", "CustomHandler"); 
+1

큰 따옴표는 필요하지 않습니다. 처리기에서 함수를 이벤트에 바인드하는 방법 중 하나입니다. – MacMac

+1

이 코드는 짧고보기 흉하게 보일지 모르지만 브라우저에 표시되는로드는 이벤트 위임 솔루션이 존재할 때이 사용 사례에서는 유용하지 않습니다. – charlietfl

+0

내 실수 ... 나는 서둘러 인용문을 추가했습니다. – nightf0x

2

따라서, 추가 코드없이, 이것은 블라인드 샷의 비트가 [회원 토니의 연구에 대한 응답으로 편집] ,하지만 여기에는 두 가지가 있습니다. 1. 기본 브라우저 툴팁 동작. 2. 잠재적으로 업데이트되는 DOM 및 사용자 정의 툴팁이 계속 작동 할 수있는 기능.

# 1 : 사용자 지정 이벤트를 요소에 바인딩하면 event.preventDefault()을 사용하여 도구 설명이 나타나지 않도록 할 수 있습니다. 이것은 제대로 작동하지 않습니다. 따라서 "title"속성을 계속 사용하는 것은 데이터 객체 ($.data() 함수)에 값을 넣은 다음 빈 문자열 (removeAttr이 일치하지 않음)로 제목을 null로 만드는 것입니다. 그런 다음 mouseleave에서 데이터 객체의 값을 가져 와서 제목으로 다시 푸시합니다. 이 아이디어는 여기에서 오는 것입니다 : How to disable tooltip in the browser with jQuery?

# 2 : DOM 변경시 다시 바인딩하는 대신 파괴 될 것으로 예상되지 않는 수신기 요소에 한 번 바인딩하면됩니다. 보통 이것은 일종의 컨테이너 요소이지만 실제로는 모든 컨테이너를 필요로하는 경우 document (근사치는 .live()입니다. 현재는 사용되지 않습니다) 일 수 있습니다.

<div class="section"> 
    <a href="#" title="foo">Hover this foo!</a> 
    <div id="notatooltip"></div> 
</div> 

그리고 바이올린은 여기에 있습니다 : : (그냥 예를 들어)

var container = $('.section'); 

container.on('mouseenter', 'a', function() { 
    var $this = $(this); 
    var theTitle = $this.attr('title'); 
    $this.attr('title', ''); 
    $('#notatooltip').html(theTitle); 
    $.data(this, 'title', theTitle); 
}); 

container.on('mouseleave', 'a', function() { 
    $('#notatooltip').html(''); 
    var $this = $(this); 
    var storedTitle = $.data(this, 'title'); 
    $this.attr('title', storedTitle); 
}); 

내 비현실적 마크 업 여기에 있습니다 : 여기에 내 자신의 고안의 일부 가짜 마크 업을 사용하는 샘플입니다 http://jsfiddle.net/GVDqn/ 또는 일부 건전성 검사 : http://jsfiddle.net/GVDqn/1/

아마도이 방법을 사용하는 것이 더 좋습니다 (솔직히 하나의 선택기로 두 개의 개별 이벤트에 대해 두 개의 개별 기능을 바인딩 할 수있는 경우 연구하지 않았습니다).

DOM 변경을 기반으로 다시 바인딩 할 필요는 없습니다. 위임 된 수신기는 자동으로 처리합니다. 그리고 그것을 막음으로써 기본 툴팁 기능을 막을 수 있어야합니다.

+0

가장 현명한 접근법입니다! ... 그렇다면 마우스 센터 내에서 제목이 $ (this) .data ('title')로 이동했는지 테스트 할 수 있습니다. 그렇지 않은 경우 – charlietfl

+0

이 가장 훌륭한 해결책 이었지만 'preventDefault'가'mouseover' (적어도 Chrome에서는)에 제목을 표시하지 못하게하는 것 같습니다 - http://code.google.com/p/chromium/issues/detail?id=42549 –

+0

@Tony Good find; 나는 Fx에서도 실패했다고 생각합니다. 새로운 코드로 업데이트했습니다. –

0

Greg Pettit이 지적한대로 요소에서 on() 함수를 사용해야합니다.

선택기를 이벤트에 바인드 할 수 있습니다. 그러면 선택기에서 리턴 한 오브젝트를 사용할 수있을 때 jQuery가이 이벤트 핸들러를 추가합니다.

당신은 이벤트를 통해 마우스를 발사하는 기능을 원하고 당신은의 클래스와 모든 요소를에 발사하고 싶었다면 * FIELD_TITLE 당신은이 작업을 수행 할 것 * :

$('.field_title').bind('mouseenter', function() { doSomething(); }); 

이 트리거됩니다 클래스가 * field_title * 인 모든 객체에 대한 마우스 오버 이벤트 및 doSomething() 함수를 실행하십시오. 수

희망 의미 :

+1

오타가있어'.bind ('mouseenter')'not'. ('mouseenter')'이어야합니다. – MacMac

관련 문제