이벤트를 한 번만 바인딩


답변:


190

적용 할 수 있다면 아마도 event.preventDefaultevent.stopPropagation을 살펴 보거나 다음 과 같은 방법 내에서 매번 바인딩 해제 및 바인딩을 원할 것입니다.

function someMethod()
{
  $(obj).off('click').on('click', function(e) {
    // put your logic in here 
  });
}

19
이것은 모든 클릭 이벤트의 바인딩을 해제하고 항상 원하는 동작이 아니기 때문에주의하십시오. 예를 들어, 문서에 무언가를 바인드 할 때 모든 이벤트가 아닌 해당 이벤트 만 바인드 해제하려고합니다.
Mārtiņš Briedis

26
실수로 다른 클릭 이벤트의 바인딩을 해제하지 않으려면 다음을 사용할 수 있습니다. function someMethod() { $(obj).off('click.namespace').on('click.namespace', function {}); }
Manu

@Manu 당신은 이 답변
aexl

89

pna의 답변 외에도 실수로 모든 클릭 이벤트의 바인딩을 해제하지 않도록 이벤트 네임 스페이스에 대해 생각할 수 있습니다.

function someMethod () {
    $ (obj) .unbind ( 'click.namespace'). bind ( 'click.namespace', function () {});
}

https://api.jquery.com/event.namespace/


10
이것은 받아 들여진 대답이어야합니다. 모든 클릭 이벤트의 바인딩을 해제 하면 작업이 쉽게 중단 될 수 있습니다. 특히 많은 jQuery가 진행되는 복잡한 프로젝트 인 경우 더욱 그렇습니다. 감사합니다! 이 간단한 네임 스페이스 솔루션에 대해 몰랐습니다 !!
Simon Steinberger

현재 jQuery를 사용하면 각각 $(obj).off()및 이어야합니다 $(obj).on(). 그렇지 않으면 네임 스페이스가 도움이되었고 작동했습니다. 감사합니다!
aexl

19

이 특정 함수를 이미 바인딩했는지 확인하는 기본 제공 메서드는 없습니다. 여러 클릭 기능을 개체에 바인딩 할 수 있습니다. 예를 들면 :

$('#id').bind('click', function(){
alert('hello');
});


$('#id').bind('click', function(){
alert('goodbuy');
});

개체를 클릭 할 때 위의 작업을 수행하면 안녕, 작별 인사를 경고합니다. 하나의 함수 만 클릭 이벤트에 바인딩되었는지 확인하려면 클릭 이벤트 처리기를 바인딩 해제 한 다음 다음과 같이 원하는 함수를 바인딩합니다.

$(obj).unbind('click').bind('click', function(){... });

12

확실한 해결책은 someMethod()두 번 전화하지 않는 것 입니다. 그것을 고칠 수 없다면 상태 변수를 유지할 수 있으므로 다음과 같이 한 번만 바인딩됩니다.

function someMethod()
{
    if (!someMethod.bound) {
        $(obj).click(function() {});
        someMethod.bound = true;
    }
}

참고 : 이것은 바인딩 여부를 추적하기 위해 전역 변수를 도입하는 대신 함수 자체의 속성을 사용합니다. 객체 자체에 대한 속성을 사용할 수도 있습니다.

http://jsfiddle.net/jfriend00/VHkxu/에서 작동하는 것을 볼 수 있습니다 .


11

또는 on ()과 유사한 jQuery의 one () 함수를 사용하지만 여러 번 바인딩하더라도 이벤트는 한 번만 발생합니다.

http://api.jquery.com/one/


8
때로는 도움이됩니다. 그러나 때때로 당신은 당신이 할 수있는 해결책을 원합니다 : 한 번에 연결하지만 많이 사용하십시오.
Rzassar

5

jQuery를 사용하면 한 번만 매우 쉽게 일부 함수를 호출 할 수 있습니다.

function someMethod()
{

     $(obj).click(function() {});
      this.someMethod = $.noop;
}

1
이것은 someMethod가 객체 나 전역 함수의 메서드 인 경우에만 작동합니다.
jcubic 2014

jQuery.noop은보다 한 문자 만 짧기 function(){}때문에 여기에서 "도움"이라고 말하는 것은 어리석은 일이며 빈 함수 만 제공합니다. 다음은이 일반적인 솔루션의 비 jQuery 비 메서드 예제입니다.var fn = function(){ fn = function(){}; do stuff; };
1j01

1
@ 1j01 $대신 사용하도록 수정 됨
Esailija 2015-02-27

2

나는 당신의 논리를 모르기 때문에 이것은 제안입니다. 당신을 위해 작동하거나 작동하지 않을 수 있습니다.

jquery live () 및 one () 함수를 결합하면 이벤트 리 바인드보다 더 나은 결과를 얻을 수 있습니다.

두 개의 DOM 요소 (상위 및 하위)가있는 경우 특수한 경우가 작동합니다. 부모 노드의 Live ()는 이벤트가 호출되는지 확인한 다음 one ()을 호출하여 한 번만 실행되는 이벤트를 동적으로 등록합니다. (이것은 리 바인드와 같은 유사한 기능을 제공합니다).


One()기능에서 일 chrome하지만 작동하지 않았다 safari에서 Mac.
Half Blood Prince

2

바인딩 된 요소에 css 클래스를 추가 한 다음 필터링 할 수 있습니다.

function someMethod()
{
    $(obj).not('.click-binded')
          .click(function {})
          .addClass('click-binded');
}

이 방법은 플러그인에도 사용할 수 있습니다.

  $(obj).not('.datetimepicker-applied')
        .datetimepicker()
        .addClass('datetimepicker-applied');

1
var bound = false;

function someMethod()
{
    if(!bound)
    {
       $(obj).click(function {});
       bound = true;
    }
}

그러나 나는 아마도 어떤 종류의 해결 방법을 만들기 전에 두 번 호출되는 이유를 조사 할 것입니다.


3
이런 식으로 가려면 전역 이름 공간을 오염시키는 대신 jfriend00의 솔루션 bound이 첨부 된 위치를 고려하십시오 someMethod().
nuala

1

객체에 한 번만 바인딩하려면 플래그를 구현하고 해당 객체에 고정해야합니다.

예를 들면 :

if($('#id') && $('#id').data('done') == null)) {
    $('#id').bind('click', function() {
        alert('hello');
    });

    $('#id').data('done', true);
}

1

이 jQuery 확장 기능을 사용할 수 있습니다.

$.fn.once = function (type, fn, uid) {
  if(uid == undefined) {
    console.error("Called $.once without uid\n", this, "\n", fn);
  }

  var dataStr = type+"-handler-"+uid;
  if(!this.data(dataStr)) {
    this.data(dataStr, true);
    this.on(type, fn);
  }
};

이것을하는 대신

$("button").on("click", function(){
  alert("You Clicked On A Button");
});

Ya do this

$("button").once("click", function(){
  alert("You Clicked On A Button");
}, "btnHandler");

이제 주변에 함수가 있으면

function addBtnHandler() {
  $("button").once("click", function() {
    alert("You Clicked On A Button");
  }, "btnHandler");
}

그리고 여러 번 불러

addBtnHandler();
addBtnHandler();
addBtnHandler();

한 번만 수행합니다.

확장은 uid와 type을 모두 확인하여 작동합니다. 이는 동일한 uid를 사용하여 다른 유형의 핸들러를 바인딩 할 수 있음을 의미합니다. 그것을 변경하려면 편집하십시오.

var dataStr = type+"-handler-"+uid;

같은

var dataStr = "handler-"+uid;


1

나는 또한 아직 존재하지 않거나 dom 요소가 아직 생성되지 않은 dom 요소로 이벤트를 한 번만 바인딩하기 위해 jquery의 off 및 on 메소드를 사용하려고했습니다.

$('.select').off('event').on('event', 'selector', function(e){ // });

이 코드는 제대로 작동하지 않았습니다.

나는 '하나의'방법이라는 매우 유리한 방법을 발견했습니다. 이벤트를 한 번만 바인딩하려는 경우 매우 유용합니다.

http://api.jquery.com/one/ 에서 문서를 찾을 수 있습니다.

이것은 'on'메소드와 동일하지만 여러 선택기에 대해 이벤트를 고수하지 않는 동작이 다릅니다.

$('body').one('click', 'selector', function(){ // do your stuff here });

1

addEventListener 메서드와 번의 옵션을 사용하여 순수 JS로이를 달성 할 수 있습니다.

target.addEventListener('click', handler, {once: true});

2
이로 인해 요소를 한 번 클릭 한 후 이벤트가 바인딩 해제됩니다. 이것은 이벤트가 여러 번 바인딩되는 문제를 해결하지 못합니다.
Top Cat
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.