2009-05-21 21 views
15

ओवरराइट किए बिना ऑनक्लिक हैंडलर जोड़ना मैं एक पृष्ठ पर सभी लिंक संशोधित करने की कोशिश कर रहा हूं ताकि वे क्लिक होने पर कुछ अतिरिक्त काम कर सकें।जावास्क्रिप्ट: मौजूदा एक

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

लेकिन लिंक के कुछ पहले से ही एक onClick हैंडलर कि संरक्षित किया जाना चाहिए है:

एक तुच्छ दृष्टिकोण कुछ इस तरह हो सकता है।

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

मुझे लगता है कि इसी तरह के कई कार्यों aroun देखा है था डी jQuery का उपयोग कर हल कर रहे हैं। मैं वर्तमान में इसे देख रहा हूं क्योंकि यह कई अन्य कार्यों को भी कम करता है। Quirksmode पेज के लिए – rluba

उत्तर

16

आप प्रत्येक लिंक के मूल onclick मूल्य संरक्षित करने के लिए एक बंद बनाना होगा। यह ठीक है अगर आप यही चाहते हैं, लेकिन ध्यान रखें कि यदि आप मूल हैंडलर झूठी वापसी करते हैं तो भी आपको नया ऑनक्लिक हैंडलिंग करना है, तो आपको कोड को थोड़ा संशोधित करना होगा।

comp.lang.javascript FAQ और Douglas Crockford से बंद होने पर अधिक।

+0

+1। मेरा उदाहरण विशेष रूप से केवल तभी निष्पादित करने के लिए डिज़ाइन किया गया था जब मूल हैंडलर रद्द नहीं हुआ था, इसलिए आपका उदाहरण अच्छी तरह से फिट बैठता है। – rluba

18

सीधे एक ईवेंट हैंडलर के लिए असाइन मत करो: सदस्यता के मॉडल addEventListener/attachEvent बजाय का उपयोग करें (जो भी जोड़े को दूर किया है!)।

अच्छी परिचय here

+1

+1। – outis

+0

या, आप एक जावास्क्रिप्ट लाइब्रेरी (/ मुझे jQuery के लिए वोट) का उपयोग कर सकते हैं जो आपको बहुत अधिक आसानी से ऐसा करने देगा। लेकिन आपको अभी भी quirksmode पेज पर सिद्धांत के माध्यम से जाना चाहिए। यह एक जावास्क्रिप्ट डेवलपर के लिए काफी आत्मा-समृद्ध है। – jrharshath

+1

"आसानी" सापेक्ष है। मैं इस सामान को 5 लाइन विधि में लपेट सकता हूं या मैं एक बहु-के पुस्तकालय डाउनलोड कर सकता हूं। एक पुस्तकालय अच्छा है, लेकिन यह जानने के खर्च पर नहीं कि वास्तव में खुद को कुछ कैसे करना है। मैं एंटी-वोट jquery नहीं होगा, मैं सिर्फ kneejerk पर उत्सुक नहीं हूँ। – annakata

4

addEventListener (DOM समर्थन ब्राउज़र) या attachEvent (IE) के आसपास एक रैपर का उपयोग करें।

ध्यान दें कि यदि आप कभी भी पुराने मान को ओवरराइट किए बिना एक चर में एक मूल्य संग्रहीत करना चाहते हैं, तो आप closures का उपयोग कर सकते हैं।

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); 

Aspect Oriented Programming में, यह "advice" के रूप में जाना जाता है।

0

oldClick = links[i].onclick or an empty function सेटिंग के बारे में कैसे। जैसा तो

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 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

यह उस समस्या को हल नहीं करता है जब पुराने ऑनक्लिक का मूल्यांकन किया जाता है जब हैंडलर को बुलाया जाता है और जब यह लिखा जाता है। इसके अलावा: अगर पुराने ऑनक्लिक हैंडलर झूठे लौटते हैं (काम से लिंक को रोकने के लिए) झूठी वापसी में विफल रहता है। – rluba

+0

आह, मैं समस्या को बेहतर समझता हूं। यदि पुरानी ऑनक्लिक झूठी वापसी करता है तो क्या आप झूठी वापसी नहीं कर सकते? बंद होने पर संकेत के लिए –

0

JQuery का उपयोग करते हुए की तरह का उपयोग किया है, निम्नलिखित कोड काम करता है:

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

इसके लिए एक अतिरिक्त लाइब्रेरी का उपयोग करने की आवश्यकता है लेकिन addEventListener/attachEvent (this references के साथ बाद की समस्या की तरह) के साथ मौजूद कुछ मुद्दों से बचाता है।

सिर्फ एक ख़तरा है: यदि मूल onClick हैंडलर "सामान्य" जावास्क्रिप्ट, लाइन

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

हमेशा सच हो जाएगी का उपयोग कर असाइन किया गया है, यहाँ तक कि मामले में मूल हैंडलर रद्द झूठी वापसी से घटना। इसे ठीक करने के लिए, मूल हैंडलर को JQuery का भी उपयोग करना होगा।कि इस कार्यान्वयन केवल प्रदर्शन नई onclick निपटने यदि मूल onclick हैंडलर सच रिटर्न

<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

इस समारोह प्रयोग करने योग्य होना चाहिए (घटना श्रोताओं दृष्टिकोण):

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; 
} 

या आप कुछ और कोड इस समारोह जोड़ने बचा सकता है (यदि आप कई तत्वों के लिए एक ही घटना श्रोता जोड़ने की जरूरत है):

function addClickListener(element) { 
    addEventListener(element, 'click', clickHandler, false); 
} 
संबंधित मुद्दे