2012-06-01 23 views
5

पर दायरे और गुजरने वाले पैरामीटर के साथ समस्या नीचे दिए गए कोड में आप देखेंगे कि मैं छवि के लिए इवेंट हैंडलर को परिभाषित करने की कोशिश कर रहा हूं। ऑनक्लिक जो अतिरिक्त पैरामीटर लेता है, मैं उन पैरामीटर को थोड़ी देर के अंदर घोषित कर रहा था लूप उम्मीद कर रहा है जावास्क्रिप्ट इस तरह के दायरे परिभाषित किया लेकिन यह नहीं करता है। मूल रूप से यहां सभी ईवेंट हैंडलर को अंतिम मूल्य मिल रहा है जो मैं चर आईडी और section_id को देता हूं। ऐसी स्थिति को संभालने के बारे में कोई विचार जहां मैं इन हैंडलरों को गतिशील रूप से उत्पन्न करना चाहता हूं?जावास्क्रिप्ट - गतिशील रूप से बनाए गए ईवेंट हैंडलर

function handlePicturesResult(){ 
    if (req.readyState == 4) { // Complete 
     if (req.status == 200) { // OK response 

      var el = document.getElementById('pictureHolder'); 
      while(el.hasChildNodes()){ 
       el.removeChild(el.lastChild); 
      } 

      var tempObject = JSON.parse(req.responseText); 
      var pictures = tempObject.images; 
      var i=0; 

      while(i<pictures.length){ 

       var picIndex = i; 

       var image= new Image(120,80); 
       image.src = 'images/' + pictures[i].url; 
       image.width = 120; 
       image.height = 80; 
       var id = pictures[picIndex].id; 
       var section_id = pictures[picIndex].sectionId; 
       image.onclick = function(event){ 
        deleteImage(event,id,section_id); 
       } 


       var txtNode = document.createTextNode(pictures[picIndex.valueOf()].id); 
       el.appendChild(image); 
       el.appendChild(txtNode); 
       i++; 
      } 
     } else { 
     alert("Problem: " + req.statusText); 
     } 
    } 

} 

उत्तर

13

फिर भी एक और समस्या closures द्वारा हल की गई!

image.onclick = function(id, section_id){ 
    return function(event) { 
     deleteImage(event,id,section_id); 
    } 
}(id, section_id); 

बाहरी समारोह एक ही बार में चलाया जाता है (अंत में तर्क के साथ कोष्ठक नोटिस), और यह भीतरी समारोह है, जो कि यात्रा पर अपने दायरे में रहता है चर का एक प्रतिलिपि वे कर रहे हैं के रूप में देता है लूप का।

जावास्क्रिप्ट बाहरी कार्य के लिए id और section_id पास करके, उस फ़ंक्शन के अंदर उनकी एक प्रति बनाकर, मूल्य से गैर-ऑब्जेक्ट चर को पास करता है। जब आप आंतरिक फ़ंक्शन को बनाते और वापस करते हैं, तो वह आंतरिक फ़ंक्शन सभी सृजनों के दायरे में रहता है जो इसकी रचना के समय (what a closure is के दिल में) है, जिसमें id और section_id की स्थानीय-चरणीय प्रतियां शामिल हैं। आंतरिक कार्य, अपने अद्वितीय दायरे के साथ, उस तत्व के लिए ईवेंट हैंडलर बन जाता है।

+0

आपकी सभी मदद के लिए धन्यवाद! – flips

+0

क्षमा करें मुझे नहीं पता था कि मैंने अभी कैसे किया :) – flips

0

आपको एक बंद करने का उपयोग करने की आवश्यकता है। जावास्क्रिप्ट में https://developer.mozilla.org/en/JavaScript/Guide/Closures

image.onclick = function(id, s_id){ 
    return function(event){ 
    deleteImage(event, id, s_id); 
    } 
}(id, section_id) 

स्कोप एक समारोह, यही वजह है कि एक बाहरी समारोह इसे करने के लिए पारित कर दिया पाश में विशिष्ट समय पर इनके मूल्य सुरक्षित करेगा तर्क के साथ निष्पादित होने के घुंघराले ब्रेसिज़ के भीतर परिभाषित किया जा सकता आप उनकी जरूरत।

उनके बिना, आईडी और सेक्शन_आईडी के मान हमेशा अंतिम पुनरावृत्ति पर उनके मूल्य का संदर्भ लेंगे।

0

यह एक क्लासिक जावास्क्रिप्ट समस्या है जो फ़ंक्शन स्कोप के बारे में समझने की कमी से उत्पन्न होती है। इस लाइन पर:

deleteImage(event,id,section_id); 

ऐसा कोई कारण नहीं है कि मानकों deleteImage के लिए पारित समय जब कॉलबैक बनाया गया था पर मान वे था बनाए रखने चाहिए। चर id और section_idhandlePicturesResult के दायरे से बंधे हैं; वे चर हैं जो उस स्थान के भीतर मौजूद हैं, और प्रत्येक की केवल एक ही प्रति है। इस प्रकार, जब कॉलबैक चलता है, तो वह उन विशिष्ट चर और उन मानों का उपयोग करेगा जिन्हें वे वर्तमान में संदर्भित करते हैं (लूप के अंतिम पुनरावृत्ति से)।

समाधान वेरिएबल्स को उस दायरे में प्राप्त करना है जो लूप के प्रत्येक पुनरावृत्ति को उनके मूल्यों को "बचाता है"। कार्य जेएस में केवल ऐसे स्कोप प्रदान करते हैं। मैं पहले से प्रदान किए गए उत्कृष्ट समाधान दोहराऊंगा। एक वैकल्पिक पुनरावृत्तियों के लिए jQuery के each उपयोग करने के लिए है, और आप फिर से यह समस्या नहीं होगी:

$.each(pictures, function(i, picture) { 

    var image= new Image(120,80); 
    var id = pictures.id; 
    var section_id = picture.sectionId; 
    var txtNode = document.createTextNode(id); 

    image.width = 120; 
    image.height = 80; 
    image.src = 'images/' + picture.url; 

    image.onclick = function(event){ 
     deleteImage(event, id, section_id); 
    } 

    el.appendChild(image); 
    el.appendChild(txtNode); 

}); 
  • मान लिया गया pictures एक सरणी है।
संबंधित मुद्दे