2009-05-21 7 views
15

클릭 할 때 추가 작업을 수행 할 수 있도록 페이지의 모든 링크를 수정하려고합니다.JavaScript : 기존 페이지를 덮어 쓰지 않고 onClick 핸들러 추가하기

function adaptLinks() 
{ 
    var links = document.getElementsByTagName('a'); 
    for(i = 0; i != links.length; i++) 
    { 
     links[i].onclick = function (e) 
     { 
      <do some work> 
      return true; 
     } 
    } 
} 

그러나 링크 중 일부는 이미 보존되어야 온 클릭 핸들러를 가지고 :

일반의 접근 방식은 다음과 같이 될 수 있습니다.

function adaptLinks() 
{ 
    var links = document.getElementsByTagName('a'); 
    for(i = 0; i != links.length; i++) 
    { 
     var oldOnClick = links[i].onclick; 
     links[i].onclick = function (e) 
     { 
      if(oldOnClick != null && !oldOnClick()) 
      { 
       return false; 
      } 
      <do some work> 
      return true; 
     } 
    } 
} 

을하지만 (이이 지점으로 마지막 링크의 값을 포함) 핸들러가 호출 될 때 oldOnClick 만 평가하기 때문에이 작동하지 않습니다 나는 다음 시도했다.

+0

훌륭한 자원이었다 d는 jQuery를 사용하여 해결됩니다. 다른 여러 작업을 쉽게 처리 할 수 ​​있도록 현재 조사 중입니다. Quirksmode 페이지의 경우 – rluba

답변

16

는 각 링크의 원래 onclick 값을 보존하기 위해 클로저를 작성해야합니다. 원래 처리기가 false를 반환하는 경우에도 새 onclick 처리를 수행하려면 코드를 약간 수정해야한다는 점을 명심하십시오.

클로저에 대한 자세한 내용은 comp.lang.javascript FAQDouglas Crockford입니다.

function addEventListener(element, eventType, eventHandler, useCapture) { 
    if (element.addEventListener) { 
     element.addEventListener(eventType, eventHandler, useCapture); 
     return true; 
    } else if (element.attachEvent) { 
     return element.attachEvent('on' + eventType, eventHandler); 
    } 
    element['on' + eventType] = eventHandler; 
} 

또는 (당신이 많은 요소에 동일한 이벤트 리스너를 추가해야하는 경우)이 기능을 추가 좀 더 코드를 저장할 수 있습니다 :

+0

클로저에 대한 힌트는 +1입니다. 내 예제는 원래 처리기가 취소되지 않은 경우에만 실행되도록 특별히 설계되었으므로 예제가 적절하게 맞습니다. – rluba

18

직접 이벤트 핸들러에 할당 안 함 :이 모델 하여 addEventListener에게 대신/는 attachEvent 가입 사용 (또한 쌍을 제거해야!).

좋은 소개 here.

+1

+1. – outis

+0

또는 자바 스크립트 라이브러리 (/ me는 jQuery에 투표)를 사용하면 훨씬 쉽게 동일한 작업을 수행 할 수 있습니다. 그러나 당신은 여전히 ​​quirksmode 페이지에서 이론을 따라 가야합니다. 자바 스크립트 개발자에게는 영혼을 풍부하게합니다. – jrharshath

+1

"편안함"은 상대적입니다. 이 자료를 5 줄 방법으로 포장하거나 다중 K 라이브러리를 다운로드 할 수 있습니다. 도서관은 가지고있는 것이 좋지만, 실제로 무언가를하는 방법을 모르는 대신에. 나는 반 투표 jquery를하지 않을 것입니다, 나는 단지 kneejerk에 열중하지 않습니다. – annakata

4

addEventListener (DOM 지원 브라우저) 또는 attachEvent (IE)의 래퍼를 사용하십시오.

이전 값을 덮어 쓰지 않고 변수에 값을 저장하려는 경우 closures을 사용할 수 있습니다. Aspect Oriented Programming에서

function chain(oldFunc, newFunc) { 
    if (oldFunc) { 
    return function() { 
     oldFunc.call(this, arguments); 
     newFunc.call(this, arguments); 
    } 
    } else { 
    return newFunc; 
    } 
} 

obj.method = chain(obj.method, newMethod); 

는이를 "advice"로 알려져있다.

0

설정 방법은 oldClick = links[i].onclick or an empty function입니다. 다른 사람들이

function addEvent(obj, type, fn) { 
     if (obj.addEventListener) 
       obj.addEventListener(type, fn, false); 
     else if (obj.attachEvent) 
       obj.attachEvent('on' + type, function() { return fn.apply(obj, [window.event]);}); 
} 

을 추천 등

addEvent(links[i], 'click', [your function here]); 
+0

핸들러가 호출 될 때 oldOnClick이 평가되고 쓰여질 때가 아니라 oldOnClick이 평가되는 문제는 해결되지 않습니다. 더하기 : 이전 onclick 핸들러가 false를 반환하면 (링크 작동을 중지시키기 위해) false를 반환하지 않습니다. – rluba

+0

아, 문제가 더 잘 이해됩니다. oldOnClick이 false를 반환하면 false를 반환 할 수 있습니까? –

0

jQuery를 사용하여 같이 사용하는 것처럼

var oldOnClick = links[i].onclick || function() { return true; }; 

links[i].onclick = function (e) 
    { 
     if (!oldOnClick()) 
      return false; 
     //<do some work> 
     return true; 
    } 

아니면 attachEvent를 사용할 수 있고 addEventListener과 같이, 다음 코드는 작동 :

function adaptLinks(table, sortableTable) 
{ 
    $('a[href]').click(function (e) 
    { 
     if(!e.isDefaultPrevented()) 
     { 
      <do some work> 
     } 
    }); 
} 

추가 라이브러리 사용이 필요하지만 addEventListener/attachEvent (후자의 this references 문제)와 같은 문제는 피할 수 있습니다.

하나의 함정이있다 : 원래 온 클릭 핸들러가 "정상"자바 스크립트,

... 
if(!e.isDefaultPrevented()) 
... 

항상 사실에 해결 될 줄을 사용하여 할당 된 경우, 원래의 핸들러가 취소하는 경우에도 false를 반환하여 이벤트. 이 문제를 해결하려면 원래 처리기에서 JQuery도 사용해야합니다.이 구현은 원래의 onclick 핸들러가 true를 돌려주는 경우 새가 온 클릭 처리를 수행하는

<a href="#" onclick="alert('hi');return false;">Hi</a> 
<a href="#" onclick="alert('there');return true;">There</a> 
<script type="text/javascript"> 
function adaptLinks() { 
    var links = document.getElementsByTagName('a'); 
    for (i = 0; i != links.length; i++) { 
     links[i].onclick = (function() { 
      var origOnClick = links[i].onclick; 
      return function (e) { 
       if (origOnClick != null && !origOnClick()) { 
        return false; 
       } 
       // do new onclick handling only if 
       // original onclick returns true 
       alert('some work'); 
       return true; 
      } 
     })(); 
    } 
} 
adaptLinks(); 
</script> 

참고 :

0

이 기능은 (이벤트 리스너 접근) 사용할 수 있어야

0

function addClickListener(element) { 
    addEventListener(element, 'click', clickHandler, false); 
} 
내가 간단한 방법으로 과부하로 문제가 있었다 -이 페이지는 나는 많은 유사한 작업 aroun를 것을 본 적이 http://www.quirksmode.org/js/events_advanced.html

관련 문제