2012-10-30 5 views
27

대부분의 jQuery 플러그인은 처음 초기화 할 때 DOM 노드에 연결되거나 바인딩됩니다.jQuery 플러그인이 이미 DOM 노드에 바인딩되어 있는지 확인하는 방법은 무엇입니까?

$('#foo').bar({options: ...}); 
당신이 플러그인이나 객체가 현재 #foo 같은 DOM 노드에 바인딩 된 것을 확인할 수 있습니다 방법

? 예를 들어

if($('#foo').bar) 
if($.inArray('bar', $('#foo').eq(0))) 
if($('#foo').eq(0).indexOf('bar')) 
if($('#foo').hasOwnProperty('bar')) 

, 그것은 플러그인 자체가에 일하고 요소 (들)을 변경하는 몇 가지 방법을 정의되지 않는 한이

console.log($('#foo').data('events')); 
+2

반드시이 답을 알고 싶으세요 (예를 들어, 확장 된 위젯의 기본 메소드를 호출)의 이름을 알고 당신이 그나마 위젯의 메소드를 호출하는 것이 유용하다. 그것은 디버깅에 도움이 될 것입니다. –

+0

DOM 노드에 _bound를 정확히 정의 하시겠습니까? [jquery-ui.js] (http://code.jquery.com/ui/1.9.1/jquery-ui.js)를 페이지에 추가하면 모든 요소는'.dialog()','.autocomplete)'등이 자동으로 추가됩니다. 그들은 _every_ 노드에 바인딩됩니다. –

+0

@SalmanA, 나는 플러그인이 적극적으로 DOM 요소를 모니터링하거나 영향을 미치고 있음을 의미합니다. – Xeoncross

답변

8

같은 개체에 바인딩 이벤트를 얻을 수, 그것은 불가능 해요 . 예를 들어 :

여기
$.fn.extend({ 
    foo: function() { console.log("I am foo!"); } 
}); 

$('#bar').foo(); 

나는 심지어 호출 요소와 상호 작용하지 않는 완전한 (잘, 더 - 오 - 이하) jQuery 플러그인을 정의했다.

jQuery.fn = jQuery.prototype = { ... } 
: 당신이 원하는대로 그럼에도 불구하고, 당신은 ( jquery.js에서) 때문에이 라인의 프로토 타입에서이 방법을 가지고 요소의 jQuery를 감싸 컬렉션으로, 요소의 jQuery를 감싸 컬렉션, 사용할 수 있습니다

... $.fn.extend이 플러그인을 호출하기 위해 호출 된 후 아무런 의도도 없습니다.

하지만 내 플러그인과 같이, 어떤 방법으로 그 호출 요소를 변경하는 데 필요한 경우에도 :

$.fn.extend({ 
    bar: function() { this.html('I am all bar now!'); } 
}); 
$('#bar').bar(); 

... 난 아직도, 기본적으로 일부 외부 이벤트와이를 처리해야합니다 (DOM 돌연변이 내부 jQuery 로깅에 의존하는 것이 아닙니다.

+1

이것은 사실이며 (아마도 답변 일 수도 있지만) 대부분의 플러그인은 요소를 변경하거나 플러그인 객체에서 인스턴스를 다시 기록합니다. 추적 할 수있는 일종의 일반 재산을 남겨 두어야합니다. 아마도 이벤트, 클래스, ID,'.data' 또는 다른 것입니다. – Xeoncross

+0

@Xeoncross 왜 jQuery가 플러그인 동작에 대한 제한이없는 경우 _generic_ 속성이어야합니까? – raina77ow

+0

아마 재산에 대한 "일반적인 장소"라고 말하는 것이 좋습니다. 여하튼, 상황을 감지하여이를 감지 할 수있는 패턴이 종종 있습니다. 예를 들어, 많은 플러그인은'.data()'에 뭔가를 추가합니다. – Xeoncross

3

제 경우에는 감지하려고하는 플러그인이 어떤 데이터를 $(element).data() 저장소에 추가하는 경우가 발생합니다. 나는 또한 플러그인이 클래스 나 ID의 이름을 추가하거나 클래스의 이름을 변경 한 것을 본 적이있다.

아래는 현재이 문제를 해결하기 위해 노력하고있는 코드입니다. 아마도 대부분의 플러그인에서 작동하지 않을 수 있습니다.

$.fn.extend({ 
    isPluginBound: function(pluginName) 
    { 
     if(jQuery().pluginName) 
     { 
      var name = pluginName.toLowerCase(); 

      return this.data(pluginName) || this.data(name) 
       || this.attr('class').toLowerCase().indexOf(name) !== -1 // vs hasClass() 
       || this.attr('id').toLowerCase().indexOf(name) !== -1; 
     } 
    } 
}); 

는 그냥 지금까지 내가 모든 jQuery를 위젯들이 DOM 노드에 자신의 인스턴스를 추가 알고 $('#foo').isPluginBound('bar');

+1

아마도'if (jQuery(). pluginName)'를'if ($ .fn [pluginName]) '로 대체 하겠지만, 이것은 단지 부언입니다. 사실, jQuery UI 플러그인은 영향을받는 요소의'data'에 이름을 저장하기 때문에 접근법이 _probably_ 유효합니다. 아직도, 그것은 내부에 의존합니다. – raina77ow

+0

또 다른 사이드 노트로, 어쨌든'isPluginBound'에서 부울을 반환하는 것이 좋을 것입니다 (예를 들어,'!!'- 그 검사 표현식을 래핑하는 것). – raina77ow

+0

항상 .data()를 확인해 볼만한 가치가 있습니다. – iamkeir

1

전화를 사용합니다. 내 프로젝트에서 다음 확장명을 사용 중입니다.

// returns first found widget instance of the first element or calls method on first widget instance of all elements 
$.fn.widget = function (method , option, value) { 
    var wi; 
    // iterate all elements 
    this.each(function() { 
    var wii; 
    // iterate all attached data elements, look for widget instances 
    $.each($(this).data(), function(key, data){ 
     if ("widgetName" in data){ wii = data; return false } 
    }) 
    // if there is a widget instance but no method specified 
    if (wii && !method) { 
     wi = wii; 
     return false 
    } 
    // if there is a widget and there is an object found with the method as the key 
    else if (wii && (method in wii)) { 
     // if it is truly a method of that instance, call that instance 
     if ($.isFunction(wii[method])) { 
     wi = wii[method].call(wii, option, value) 
     } 
     // else, it is maybe a value stored in the instance you seek? 
     else { 
     wi = wii[method] 
     } 
    } 
    }) 
    return (wi === undefined) ? this : wi ; 
} 
관련 문제