싱글 클릭 이벤트와 더블 클릭 이벤트를 어떻게 구분하나요?


116

나는 id와 함께 단일 버튼을 가지고 있습니다 "my_id". 이 요소로 두 개의 jQuery 이벤트를 첨부했습니다.

1.

$("#my_id").click(function() { 
    alert('single click');
});

2.

$("#my_id").dblclick(function() {
    alert('double click');
});

그러나 매번 그것은 나에게 single click


한 번의 클릭은 항상 실행되어야하며, 지정된 더블 클릭 시간 내에 실제로 발생하지 않는 한 더블 클릭이 발생하는지 여부를 알 수 없습니다.
Pieter Germishuys 2011 년

7
가능합니다. 내 대답을 확인하십시오. 첫 번째 클릭 후 몇 ms를 기다려야하며 지정된 시간까지 새 클릭이 있는지 확인해야합니다. 이렇게하면 이것이 단순한 것인지 더블 클릭인지 알 수 있습니다.
Adrien Schuler 2011 년

답변:


65

첫 번째 클릭 후 다른 클릭이 있는지 확인하려면 시간 제한을 사용해야합니다.

트릭은 다음과 같습니다 .

// Author:  Jacek Becela
// Source:  http://gist.github.com/399624
// License: MIT

jQuery.fn.single_double_click = function(single_click_callback, double_click_callback, timeout) {
  return this.each(function(){
    var clicks = 0, self = this;
    jQuery(this).click(function(event){
      clicks++;
      if (clicks == 1) {
        setTimeout(function(){
          if(clicks == 1) {
            single_click_callback.call(self, event);
          } else {
            double_click_callback.call(self, event);
          }
          clicks = 0;
        }, timeout || 300);
      }
    });
  });
}

용법:

$("button").single_double_click(function () {
  alert("Try double-clicking me!")
}, function () {
  alert("Double click detected, I'm hiding")
  $(this).hide()
})
<button>Click Me!</button>

편집하다:

아래에 설명 된대로 기본 dblclick이벤트 사용을 선호합니다 . http://www.quirksmode.org/dom/events/click.html

또는 jQuery에서 제공하는 것 : http://api.jquery.com/dblclick/


14
이것은 일반적으로 잘 작동하는 것처럼 보이지만 클릭 사이에 허용되는 지연 시간 (두 번의 클릭이 더블 클릭으로 해석 됨)이 시스템 구성에 따라 다르지 않습니까? dblclick이벤트 에 의존하는 것이 더 안전 할 것입니다
Jon z

1
네 말이 맞다고 생각합니다. dblclick확실히 오늘가는 길입니다. jQuery는 또한이 이벤트를 처리합니다. api.jquery.com/dblclick
Adrien Schuler

14
@AdrienSchuler-링크하는 문서에서 : 동일한 요소에 대한 click 및 dblclick 이벤트에 핸들러를 바인딩하는 것은 바람직하지 않습니다. 질문은 둘 다 갖는 것 입니다.
Álvaro González

event.detail사용할 수는 클릭 처리기에서 더블 클릭을 감지하는 가장 좋은 방법입니다. 이 답변을 참조하십시오 .
Carl G

좋은 솔루션 Adrien, 하나의 개체에 단일 및 두 번 클릭 이벤트가 있고 하나만 실행되어야하는 경우에 필요합니다. 따라서 귀하의 솔루션은 저에게 완벽합니다. "this"를 제어하기 위해 약간 개선했습니다. playcode.io/492022
LOstBrOkenKeY

79

dblclick이벤트 의 동작은 Quirksmode 에서 설명 합니다.

의 이벤트 순서 dblclick는 다음과 같습니다.

  1. mousedown
  2. mouseup
  3. 딸깍 하는 소리
  4. mousedown
  5. mouseup
  6. 딸깍 하는 소리
  7. dblclick

이 규칙에 대한 한 가지 예외는 (물론) 사용자 지정 순서가 다음과 같은 Internet Explorer입니다.

  1. mousedown
  2. mouseup
  3. 딸깍 하는 소리
  4. mouseup
  5. dblclick

보시다시피 동일한 요소에서 두 이벤트를 함께 수신하면 click핸들러 에 대한 추가 호출이 발생 합니다.


확실하지 않습니다 dblclick... 한 번 클릭하면 ... 1 ~ 2 초 정도 기다렸다가 다시 dblclick클릭하면 두 번째 클릭시 이벤트가 발생합니다!
Michael

이러한 긴 클릭은 예를 들어 파일 이름을 바꿀 때 유용합니다. 그것을 구별하기 위해 'longClick'과 같은 매개 변수가 있으면 좋을 것입니다.
PeterM

1
event.detail사용할 수는 클릭 처리기에서 더블 클릭을 감지하는 가장 좋은 방법입니다. 이 답변을 참조하십시오 .
Carl G

38

더 많은 임시 상태와 setTimeout을 사용하는 대신 객체 detail에서 액세스 할 수있는 라는 네이티브 속성 이 있습니다 event!

element.onclick = event => {
   if (event.detail === 1) {
     // it was a single click
   } else if (event.detail === 2) {
     // it was a double click
   }
};

최신 브라우저와 IE-9도 지원합니다. :)

출처 : https://developer.mozilla.org/en-US/docs/Web/API/UIEvent/detail


가장 좋은 답 :
sk8terboi87ツ

3
더블 클릭의 경우 한 번의 클릭 ( event.detail === 1)이 계속 트리거됩니다. 이 스레드에 대한바이올린 또는 이 주석을 참조하십시오 .
Fabien Snauwaert

좋은 포인트 @FabienSnauwaert. 특정 요소에 대해 단일 및 이중 클릭 이벤트 처리기를 바인딩 할 수 없다고 생각합니다. 위의 방법은 타이머와 같은 물건에 의존하지 않고 더블 클릭을 결정적으로 결정하는 데 유용합니다.
kyw

실행하지 않으려면 첫 번째 클릭에 타이머가 필요합니다. 아래 내 대답을 확인하십시오. stackoverflow.com/questions/5497073/…

접근성 참고 사항 : 키보드에 의해 클릭 이벤트가 발생하면 (예 : 사용자가 탭을 눌러 버튼에 초점을 맞추고 Enter를 누를 때) 세부 속성이 0 인 이벤트가 생성되므로 if(evt.detail !== 1) return;실수로 인한 이중을 거부 하는 것과 같은 작업을 수행합니다. 클릭은 마우스가없는 사용자의 해당 버튼에 대한 액세스를 차단합니다.
gristow

25

간단한 기능. jquery 또는 기타 프레임 워크가 필요하지 않습니다. 함수를 매개 변수로 전달

<div onclick="doubleclick(this, function(){alert('single')}, function(){alert('double')})">click me</div>
    <script>
        function doubleclick(el, onsingle, ondouble) {
            if (el.getAttribute("data-dblclick") == null) {
                el.setAttribute("data-dblclick", 1);
                setTimeout(function () {
                    if (el.getAttribute("data-dblclick") == 1) {
                        onsingle();
                    }
                    el.removeAttribute("data-dblclick");
                }, 300);
            } else {
                el.removeAttribute("data-dblclick");
                ondouble();
            }
        }
    </script>

2
이것이 최선의 대답이라고 생각하지만 Windows IE8에서 작동하려면 제한 시간을 200으로 줄여야했지만이 값은 OS 및 사용자에 따라 다를 수 있습니다. 또한 더블 클릭이 등록되면 클릭 실행을 취소 할 수 있도록 타이머 참조를 저장했습니다.
xpereta 2013 년

이 코드에 감사드립니다. 크롬과 파이어 폭스에서 훌륭하게 작동합니다 (크롬은 dbl과 싱글과 함께 작동하기 위해이 해킹이 필요하지 않습니다).
빅터

를 사용하는 el.dataset.dblclick것이 더 좋은 방법입니다.
WORMSS

event.detail사용할 수는 클릭 처리기에서 더블 클릭을 감지하는 가장 좋은 방법입니다. 이 답변을 참조하십시오 .
Carl G

12

동작이 브라우저에 따라 다릅니다.

동일한 요소에 대해 click 및 dblclick 이벤트 모두에 핸들러를 바인딩하는 것은 바람직하지 않습니다. 트리거되는 이벤트의 순서는 브라우저마다 다르며, 일부는 dblclick 전에 두 번의 클릭 이벤트를 수신하고 다른 일부는 하나만 수신합니다. 더블 클릭 민감도 (더블 클릭으로 감지되는 클릭 사이의 최대 시간)는 운영 체제와 브라우저에 따라 다를 수 있으며 사용자가 구성 할 수있는 경우가 많습니다.

http://api.jquery.com/dblclick/

Firefox에서 코드를 실행하면 click()핸들러 의 alert () 가 두 번째 클릭을 방지합니다. 이러한 경고를 제거하면 두 이벤트가 모두 표시됩니다.


event.detail사용할 수는 클릭 처리기에서 더블 클릭을 감지하는 가장 좋은 방법입니다. 이 답변을 참조하십시오 .
Carl G

11

더블 클릭 (두 번 클릭)하려면 먼저 한 번 클릭해야합니다. click()경고가 팝업 때문에 핸들러 화재는 첫 번째 클릭에, 그리고, 당신은 해고 할 수있는 두 번째 클릭 할 수있는 기회가없는 dblclick()핸들러를.

처리기를 변경하여 an 이외의 작업을 수행 alert()하면 동작을 볼 수 있습니다. (아마도 요소의 배경색을 변경) :

$("#my_id").click(function() { 
    $(this).css('backgroundColor', 'red')
});

$("#my_id").dblclick(function() {
    $(this).css('backgroundColor', 'green')
});

7

이 답변은 시간이 지남에 따라 쓸모 없게 만들어졌습니다.

@AdrienSchuler가 게시 한 요점에서 영감을받은 솔루션을 만들었습니다. 한 번의 클릭과 두 번의 클릭을 요소에 바인딩하려는 경우에만이 솔루션을 사용하십시오. 그렇지 않으면 네이티브 clickdblclick리스너를 사용하는 것이 좋습니다 .

차이점은 다음과 같습니다.

  • Vanillajs, 종속성 없음
  • 기다리지 마십시오 setTimeout에서 클릭 또는 더블 클릭 처리기를 처리 할
  • 두 번 클릭하면 먼저 클릭 핸들러가 실행 된 다음 doubleclick 핸들러가 실행됩니다.

자바 스크립트 :

function makeDoubleClick(doubleClickCallback, singleClickCallback) {
    var clicks = 0, timeout;
    return function() {
        clicks++;
        if (clicks == 1) {
            singleClickCallback && singleClickCallback.apply(this, arguments);
            timeout = setTimeout(function() { clicks = 0; }, 400);
        } else {
            timeout && clearTimeout(timeout);
            doubleClickCallback && doubleClickCallback.apply(this, arguments);
            clicks = 0;
        }
    };
}

용법:

var singleClick = function(){ console.log('single click') };
var doubleClick = function(){ console.log('double click') };
element.addEventListener('click', makeDoubleClick(doubleClick, singleClick));

아래는 jsfiddle에서의 사용법이며 jQuery 버튼은 허용되는 답변의 동작입니다.

jsfiddle


2
위의 코드와 바이올린의 'Vanilla'버전이 작동하지 않습니다. 여기에 고정 된 Vanilla 버전이 있습니다. jsfiddle.net/jeum/cpbwx5vr/19
jeum

@jeum 모든 브라우저에서 여전히 나를 위해 트릭을 수행합니다. "작동하지 않는"것은 무엇이며 무엇을 기대합니까? 귀하의 버전이 내가 의도 한대로 작동하지 않는 것 같습니다.
A1rPun

주먹 나는 내 버전을 수정했습니다 (이중 폐쇄 제거), 새 버전을 시도하십시오 : jsfiddle.net/jeum/cpbwx5vr/20 바이올린 (바닐라 버전)의 문제는 두 번 클릭이 단일 처리기를 트리거한다는 것입니다 : 단일 처리기를 검색합니다 + 나를 위해 두 배.
jeum

@jeum 그 사람은 오류를 제공합니다. 그래 여기 허용하고 다른 답변에서 내 대답 다릅니다과 내가이 라인의 차이 지정 : 화재 클릭, 다음 더블 클릭을 (더블 클릭 똑바로 가지 않는다)
A1rPun

1
예 오류가 다시 발생 하므로이 버전은 jsfiddle.net/jeum/cpbwx5vr/21 주요 질문에 응답합니다 . 이제 버전과 관련하여 (내가 이해하지 못한 것은 사실입니다) 'jQuery'가 바이올린에서 원하는 것을 얻지 못한다는 것을 알았습니까?
jeum

5

에 기초하여 또 다른 간단한 바닐라 솔루션 A1rPun의 대답은 (참조 그의 바이올린 JQuery와 솔루션을, 둘 다에있는 이 하나 ).

사용자가 두 번 클릭 할 때 단일 클릭 핸들러를 트리거하지 않는 것 같습니다. 단일 클릭 핸들러는 지연 후에 반드시 트리거됩니다.

var single = function(e){console.log('single')},
    double = function(e){console.log('double')};

var makeDoubleClick = function(e) {

  var clicks = 0,
      timeout;

  return function (e) {

    clicks++;

    if (clicks == 1) {
      timeout = setTimeout(function () {
        single(e);
        clicks = 0;
      }, 250);
    } else {
      clearTimeout(timeout);
      double(e);
      clicks = 0;
    }
  };
}
document.getElementById('btnVanilla').addEventListener('click', makeDoubleClick(), false);

3
당신은 한 번의 클릭 해고하지 않으려면이 : 실제로 가장 좋은 대안이다
A1rPun

event.detail사용할 수는 클릭 처리기에서 더블 클릭을 감지하는 가장 좋은 방법입니다. 이 답변을 참조하십시오 .
Carl G

5

다음은 임의의 이벤트 수에 대한 jeum 코드의 대안입니다.

 var multiClickHandler = function (handlers, delay) {
    var clicks = 0, timeout, delay = delay || 250;
    return function (e) {
      clicks++;
      clearTimeout(timeout);
      timeout = setTimeout(function () {
        if(handlers[clicks]) handlers[clicks](e);
        clicks = 0;
      }, delay);
    };
  }

  cy.on('click', 'node', multiClickHandler({
    1: function(e){console.log('single clicked ', e.cyTarget.id())},
    2: function(e){console.log('double clicked ', e.cyTarget.id())},
    3: function(e){console.log('triple clicked ', e.cyTarget.id())},
    4: function(e){console.log('quadro clicked ', e.cyTarget.id())},
    // ...
  }, 300));

cytoscape.js 앱에 필요했습니다 .


좋은! 또한 반환 된 함수 내에서 새 변수를 선언 this하고 클릭 한 요소 인을 사용하여 할당 한 다음 핸들러 (함께 e또는 대신)에 전달할 수도 있습니다.
HeyJude jul.

5

하나의 동일한 요소에 대한 단일 클릭과 두 번 클릭을 구별하는 방법은 무엇입니까?

당신이 그들을 혼합 할 필요가없는 경우에는 신뢰할 수 clickdblclick 각은 잘 일을 할 것입니다.

: 문제는 때 그들을 혼합하려고 발생 이벤트가 실제로 트리거 이벤트를뿐만 아니라dblclickclick 한 번의 클릭 더블 클릭의 "독립"한 번의 클릭, 또는 일부인지 여부를 결정해야하므로.

또한 : 당신은 둘 다 사용하지 말아야 click하고 dblclick하나의 동일한 요소를 :

동일한 요소에 대해 click 및 dblclick 이벤트 모두에 핸들러를 바인딩하는 것은 바람직하지 않습니다. 트리거되는 이벤트의 순서는 브라우저마다 다르며, 일부는 dblclick 전에 두 번의 클릭 이벤트를 수신하고 다른 일부는 하나만 수신합니다. 더블 클릭 민감도 (더블 클릭으로 감지되는 클릭 사이의 최대 시간)는 운영 체제와 브라우저에 따라 다를 수 있으며 사용자가 구성 할 수있는 경우가 많습니다.
출처 : https://api.jquery.com/dblclick/

이제 좋은 소식입니다.

이벤트의 detail속성을 사용하여 이벤트 와 관련된 클릭 수를 감지 할 수 있습니다. 내부를 두 번 클릭합니다.click 을 감지하기 쉽게 .

단일 클릭을 감지하고 이중 클릭의 일부인지 여부는 여전히 문제입니다. 이를 위해 다시 타이머를 사용하고setTimeout .

데이터 속성 (전역 변수를 피하기 위해)을 사용하고 직접 클릭을 계산할 필요없이 모든 것을 함께 래핑하면 다음과 같은 결과를 얻을 수 있습니다.

HTML :

<div class="clickit" style="font-size: 200%; margin: 2em; padding: 0.25em; background: orange;">Double click me</div>

<div id="log" style="background: #efefef;"></div>

자바 스크립트 :

<script>
var clickTimeoutID;
$( document ).ready(function() {

    $( '.clickit' ).click( function( event ) {

        if ( event.originalEvent.detail === 1 ) {
            $( '#log' ).append( '(Event:) Single click event received.<br>' );

            /** Is this a true single click or it it a single click that's part of a double click?
             * The only way to find out is to wait it for either a specific amount of time or the `dblclick` event.
             **/
            clickTimeoutID = window.setTimeout(
                    function() {
                        $( '#log' ).append( 'USER BEHAVIOR: Single click detected.<br><br>' );
                    },
                    500 // how much time users have to perform the second click in a double click -- see accessibility note below.
                );

        } else if ( event.originalEvent.detail === 2 ) {
            $( '#log' ).append( '(Event:) Double click event received.<br>' );
            $( '#log' ).append( 'USER BEHAVIOR: Double click detected.<br>' );
            window.clearTimeout( clickTimeoutID ); // it's a dblclick, so cancel the single click behavior.
        } // triple, quadruple, etc. clicks are ignored.

    });

});
</script>

데모:

JSfiddle


접근성 및 두 번 클릭 속도에 대한 참고 사항 :

  • Wikipedia는 "두 번의 연속 클릭이 두 번 클릭으로 해석되는 데 필요한 최대 지연은 표준화되지 않았습니다."라고 설명했습니다.
  • 브라우저에서 시스템의 두 번 클릭 속도를 감지 할 방법이 없습니다.
  • Windows에서 기본값은 500ms이고 범위는 100-900mm 인 것 같습니다 ( 소스 ).
  • OS 설정에서 더블 클릭 속도를 가장 느리게 설정 한 장애인을 생각해보십시오.
    • 시스템 두 번 클릭 속도가 위의 기본값 인 500ms보다 느리면 단일 및 두 번 클릭 동작이 모두 트리거됩니다.
    • 하나의 동일한 항목을 결합한 단일 및 두 번 클릭에 의존하지 마십시오.
    • 또는 : 옵션에 설정을 추가하여 값을 높일 수 있습니다.

만족스러운 솔루션을 찾는 데 시간이 걸렸습니다. 도움이 되었기를 바랍니다.


4

우수한 jQuery Sparkle 플러그인을 사용하십시오. 플러그인은 첫 번째와 마지막 클릭을 감지하는 옵션을 제공합니다. 다른 클릭에 이어 첫 번째 클릭이되었는지 감지하여 클릭과 dblclick을 구별하는 데 사용할 수 있습니다.

http://balupton.com/sandbox/jquery-sparkle/demo/ 에서 확인하십시오.


3

사용자 지정 'singleclick'이벤트를 사용하여 단일 클릭과 두 번 클릭을 구별 할 수있는 간단한 jQuery 플러그인을 작성했습니다.

https://github.com/omriyariv/jquery-singleclick

$('#someDiv').on('singleclick', function(e) {
    // The event will be fired with a small delay.
    console.log('This is certainly a single-click');
}

3

현대의 정답은 받아 들여지는 대답과 @kyw의 솔루션을 혼합 한 것입니다. 첫 번째 클릭을 방지하려면 시간 초과가 필요 event.detail하고 두 번째 클릭을 방지하려면 확인해야합니다.

const button = document.getElementById('button')
let timer
button.addEventListener('click', event => {
  if (event.detail === 1) {
    timer = setTimeout(() => {
      console.log('click')
    }, 200)
  }
})
button.addEventListener('dblclick', event => {
  clearTimeout(timer)
  console.log('dblclick')
})
<button id="button">Click me</button>


1

나는 jquery (및 기타 90-140k libs)를 피하는 것을 좋아하고, 명시된 브라우저가 onclick을 먼저 처리하므로 여기에 내가 만든 웹 사이트에서 수행 한 작업이 있습니다.

clicksNow-0; //global js, owell

function notify2(e, right) {  // called from onclick= and oncontextmenu= (rc)
var x,y,xx,yy;
var ele = document.getElementById('wrap');  
    // offset fixed parent for local win x y
var xxx= ele.offsetLeft;
var yyy= ele.offsetTop;

//NScape
if (document.layers || document.getElementById&&!document.all) {
    xx= e.pageX;
    yy= e.pageY;
} else {
    xx= e.clientX;
    yy= e.clientY;
}
x=xx-xxx;
y=yy-yyy;

clicksNow++;
    // 200 (2/10ths a sec) is about a low as i seem to be able to go
setTimeout( "processClick( " + right + " , " + x + " , " + y + ")", 200);
}

function processClick(right, x, y) {
if (clicksNow==0) return; // already processed as dblclick
if (clicksNow==2) alert('dbl');
clicksNow=0;
    ... handle, etc ...
}

도움이되기를 바랍니다


2
귀하의 답변을 이해하기 위해 게임의 URL이 필요하지 않습니다. 이 게시물이 스팸 시도로 보이지 않도록 삭제하고 있습니다.
Andrew Barber

1
유일하게 마이너스 200 마법 일정하고 크게 OS에서 사용자의 마우스 설정에 따라 다를 수 있습니다
다뉴브 선원

1

Adrien Schuler (정말 감사합니다 !!!) 답변을 기반으로 Datatables.net 및 많은 용도에 대한 수정 사항은 다음과 같습니다.

함수

/**
 * For handle click and single click in child's objects
 * @param {any} selector Parents selector, like 'tr'
 * @param {any} single_click_callback Callback for single click
 * @param {any} double_click_callback Callback for dblclick
 * @param {any} timeout Timeout, optional, 300 by default
 */
jQuery.fn.single_double_click = function (selector, single_click_callback, double_click_callback, timeout) {
    return this.each(function () {
        let clicks = 0;
        jQuery(this).on('click', selector, function (event) {
            let self = this;
            clicks++;
            if (clicks == 1) {
                setTimeout(function () {
                    if (clicks == 1) {
                        single_click_callback.call(self, event);
                    } else {
                        double_click_callback.call(self, event);
                    }
                    clicks = 0;
                }, timeout || 300);
            }
        });
    });
}

사용하다

$("#MyTableId").single_double_click('tr',
            function () {   //  Click
                let row = MyTable.row(this);
                let id = row.id();
                let data = row.data();
                console.log("Click in "+id+" "+data);
            },
            function () {   //  DBLClick
                let row = MyTable.row(this);
                let id = row.id();
                let data = row.data();
                console.log("DBLClick in "+id+" "+data);
            }
        );

0

이것은 나를 위해 일했습니다.

var clicked=0;
function chkBtnClcked(evnt) {
    clicked++;
    // wait to see if dblclick
    if (clicked===1) {
        setTimeout(function() {
            clicked=0;
            .
            .
        }, 300); // test for another click within 300ms
    }
    if (clicked===2) {
        stopTimer=setInterval(function() {
            clicked=0;
            .
            .
        }, 30*1000); // refresh every 30 seconds
    }
}

용법-

<div id="cloneimages" style="position: fixed;" onclick="chkBtnClcked(evnt)"  title="Click for next pic; double-click for slide show"></div>

0

간단하고 HTML이 필요한 경우를 대비하여 기본 HTML 답변을 게시하십시오.

<p ondblclick="myFunction()" id = 'id'>Double-click me</p>

물론 여기에는 기본 Jquery 옵션이 있습니다. 즉 ... $('#id').attr('ondblclick',function(){...})또는 이전에 언급했듯이$('#id').dblclick(function(){...});


0

나는 이것이 오래되었다는 것을 알고 있지만 아래는 단일 타이머와 더블 클릭을 결정하는 단일 타이머가있는 기본 루프 카운터의 JS 전용 예제입니다. 바라건대 이것은 누군가를 도울 것입니다.

var count = 0;
var ele = document.getElementById("my_id");
ele.addEventListener('click', handleSingleDoubleClick, false); 

function handleSingleDoubleClick()
{
  if(!count) setTimeout(TimerFcn, 400); // 400 ms click delay
  count += 1;
}
function TimerFcn() 
{
  if(count > 1) console.log('you double clicked!')
  else console.log('you single clicked')
  count = 0;
}
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.