2012-01-30 12 views
9

तो मैं एक मुद्दे को छोड़कर बड़ी सफलता के साथ Jquery मोबाइल का उपयोग कर रहा हूं। अब जब भी किसी गतिशील सामग्री पृष्ठ को किसी उपयोगकर्ता द्वारा नेविगेट किया जाता है, इससे कोई फर्क नहीं पड़ता कि सामग्री किस प्रकार प्रदर्शित होती है, नीचे हमेशा एक बटन होता है जब निर्दिष्ट पते पर सामग्री को ईमेल पर क्लिक किया जाता है; बहुत अच्छा काम करता है। अब पहली बार एक पृष्ठ लोड हो गया है, क्लिक एक बार घटना को आग लगती है। दूसरी यात्रा पर इसे दो बार, तीसरा 3 बार, निकाल दिया गया। आपको बिंदु मिल गया। मैंने नेट को खराब कर दिया है और हर फिक्स को लागू कर सकता हूं, जैसे कि "पेजिनिट" के बजाय "पेजक्रेट" का उपयोग करना, बाध्यकारी, अनबाइंडिंग, div को हटा देना, डीओएम में कैशिंग बंद करना, लेकिन कुछ भी काम नहीं करता है। मेरे पास एकमात्र सफलता क्लिक पर .one() का उपयोग कर रही है लेकिन फिर से क्लिक होने पर उसे निकाल दिया जाना चाहिए। संरचना यहाँ है। मुझे लगता है कि इस के साथ प्रत्येक लोड .js करने के लिए फ़ाइलोंJquery मोबाइल। नए पेज पर कई बार फायरिंग पर जाएं

$("#page").live("pageinit", function() { 

अब मैं एक फ़ाइल में ईमेल समारोह और अन्य सामान था शुरू कर दिया है, लेकिन यह आसान उन्हें अलग करने और मैंने सुना है यह कोई बात नहीं करता है। अब, यहाँ ईमेल समारोह में pageinit

$('.eb').live('click', function() { 
     var id = $('.eb').attr('id'); 
     var to = $('#recipient').val(); 
     var message = $('#email').html(); 

     var atpos = to.indexOf("@"); 
     var dotpos = to.lastIndexOf("."); 
     if (atpos < 1 || dotpos < atpos + 2 || dotpos + 2 >= to.length) { 
      alert('Please enter a valid email address!'); 
      return false; 
     } 

     if(to.length == 0) { 
      alert('Please enter a valid email address!'); 
      return false; 
     } 

     $.mobile.showPageLoadingMsg(); 

     $.post('./services/service.email.php', { id: id, to: to, message: message}, function(data) { 
      if(data.success == true) { 
       $.mobile.hidePageLoadingMsg(); 
       alert('Your recipe has been sent!'); 
       $('#recipient').val(''); 
       return true; 
      } 

      if(data.success == false) { 
       if(data.fail == 1) { 
        alert('An error has occured sending your recipe. Try again soon!'); 
        return false; 
       } 

       if(data.fail == 2) { 
        alert('Please enter a valid email address!'); 
       } 
      } 
     }, 'json'); 
      return false; 
    }); 

सब कुछ कहा जाता है प्रत्येक नए पृष्ठ पर .click के वृद्धिशील फायरिंग छोड़कर दोषरहित काम करता है। क्या कोई मुझे सही दिशा में ले जा सकता है?

उत्तर

2

मैं इस मुद्दे को साकार करके इस हल div ही है, #page के साथ था: .delegate() असली ताकत आप बल्कि document तत्व करने के लिए बाध्य करने के लिए की तुलना में मूल तत्व का चयन कर सकते हैं। यह पृष्ठ गतिशील सामग्री के साथ लोड किया गया था लेकिन आईडी कभी नहीं हुई थी, इसलिए लाइन के साथ कहीं कहीं इसे कैश किया गया था और प्रत्येक नई विज़िट पर एक से बढ़ाया गया था। मैंने प्रत्येक पृष्ठ लोड पर एक अद्वितीय div आईडी बनाने के लिए अभी कुछ PHP कोड जोड़ा है।

<?php $id = uniqid() ?> 
<div id="<?php echo $id; ?>">CONTENT</div> 

इससे समस्या हल हो गई और यह केवल तभी आग लगती है जब पेज रीलोड हो सकता है।

+4

यह प्रक्रिया सभी प्रकार की घटना बाइंडिंग के पीछे जा रही है जो आवश्यक नहीं हैं (आपकी साइट उपयोगकर्ताओं को आगे बढ़ने के लिए धीमा कर दिया जाएगा क्योंकि आप केवल अधिक से अधिक प्रतिनिधि कार्यक्रम हैंडलर लोड कर रहे हैं जिन्हें किसी ईवेंट के दौरान जांचना होगा डीओएम ऊपर बुलबुले)। आपकी समस्या गतिशील सामग्री के साथ काम करने का नियमित नुकसान था, आप अपने ईवेंट बाइंडिंग के साथ बहुत उदार थे। वास्तविक फिक्स प्रतिनिधि कार्यक्रम हैंडलर का उपयोग करना बंद करना है जहां वे आवश्यक नहीं हैं। मुझे खुशी है कि आपने कुछ पता लगाया लेकिन यह एक अच्छा जवाब नहीं है। – Jasper

13

jQuery 1.7 के रूप में, .live() विधि बहिष्कृत है। ईवेंट हैंडलर संलग्न करने के लिए .on() का उपयोग करें।

यदि आप 1.7+ का उपयोग कर रहे हैं तो .off() का उपयोग कर क्लिक ईवेंट को अनबिंड करने का प्रयास करें।

$('.eb').off('click').on('click', function() { 
// ... 
}); 

आप .live() उपयोग करने के लिए आप .die()

$('.eb').die('click').live('click', function() { 
// ... 
}); 

या बेहतर उपयोग .delegate() और .undelegate() संयुक्त राष्ट्र पेरेंट तत्व के साथ घटनाओं निकल कर सकते हैं:

$(document).undelegate('.eb', 'click').delegate('.eb', 'click', function() { 
// ... 
}); 
+0

jQuery मोबाइल अभी भी jQuery कोर 1.6.4 के साथ जहाज़ है, जिसमें '.on()' नहीं है, लेकिन '.delegate()' अभी भी '.live()' से अधिक पसंद है। – Jasper

+0

मैंने अपना जवाब संपादित कर लिया है और '.delegate() ' – Ingemar

+1

ठीक है, कुछ मुद्दों के लिए एक उदाहरण जोड़ा है। ** 1) ** '$ ('। Eb')। ('क्लिक''' .live() ',' $ (दस्तावेज़) .on (' क्लिक ',' .eb 'का उपयोग करने जैसा नहीं है। , फ़ंक्शन() {...}) '' live() 'जैसा ही है। जिस तरह से आप '.on()' का उपयोग कर रहे हैं, यह '.bind()' ** के समान है। * * JQuery मोबाइल में भी आप आमतौर पर 'दस्तावेज़' तत्व से ईवेंट का प्रतिनिधित्व करते हैं क्योंकि यह ** ** ** ** ** किसी भी बिंदु पर डोम में होने की गारंटी वाला ** तत्व है। – Jasper

10

सीधे शब्दों में click घटना के लिए कदम हैंडलर कोड pageinit इवेंट हैंडलर कोड के बाहर इस तरह:

$(document).delegate("#page", "pageinit", function() { 


}); 
$(document).delegate('.eb', 'click', function() { 
     var id = $('.eb').attr('id'); 
     var to = $('#recipient').val(); 
     var message = $('#email').html(); 

     var atpos = to.indexOf("@"); 
     var dotpos = to.lastIndexOf("."); 
     if (atpos < 1 || dotpos < atpos + 2 || dotpos + 2 >= to.length) { 
      alert('Please enter a valid email address!'); 
      return false; 
     } 

     if(to.length == 0) { 
      alert('Please enter a valid email address!'); 
      return false; 
     } 

     $.mobile.showPageLoadingMsg(); 

     $.post('./services/service.email.php', { id: id, to: to, message: message}, function(data) { 
      if(data.success == true) { 
       $.mobile.hidePageLoadingMsg(); 
       alert('Your recipe has been sent!'); 
       $('#recipient').val(''); 
       return true; 
      } 

      if(data.success == false) { 
       if(data.fail == 1) { 
        alert('An error has occured sending your recipe. Try again soon!'); 
        return false; 
       } 

       if(data.fail == 2) { 
        alert('Please enter a valid email address!'); 
       } 
      } 
     }, 'json'); 
      return false; 
    }); 

आप घटना प्रतिनिधिमंडल का उपयोग करते हैं तो आप नहीं है एक और ईवेंट हैंडलर के अंदर बाध्य करने के लिए है, क्योंकि हर बार है कि आप ईवेंट हैंडलर हो जाएगा फिर से बाध्यकारी (और जब आप ईवेंट हैंडलर्स प्रतिनिधि वे जीवन के लिए दिए गए हैं आग चाहते हैं डीओएम का)।

तुम भी .live() के बजाय .bind() उपयोग कर सकते हैं (यह मेरा पसंदीदा तरीका है):

$(document).delegate("#page", "pageinit", function() { 
    $('.eb').bind('click', ...); 
}); 

आप देखेंगे मेरी उदाहरण के दोनों बदल-आउट कि .live().delegate() के लिए के रूप में यह थोड़ा तेज भी जब से सौंपने के प्रदर्शन करती है document तत्व। http://api.jquery.com/delegate

+0

मैंने दोनों के साथ-साथ Ingemar समाधान की कोशिश की है और दोनों शानदार हैं जो शानदार है। समस्या यह है कि व्यवहार इतनी छद्म है कि मुझे समझ में नहीं आता है। अगर आग लगती है तो मैं इसे क्लिक करता हूं, इसे फिर से क्लिक नहीं करता हूं, इसे 3 बार बार आग पर क्लिक करें, इसे फायर करने के बाद इसे क्लिक करें..एटीसी, यह अजीब व्यवहार है। – Naterade

+0

उपरोक्त कोड किसी भी एकाधिक आग को ट्रिगर नहीं करेगा और यदि इसे वैश्विक दायरे में रखा गया है तो यह '.eb' तत्वों पर निकाले गए प्रत्येक 'क्लिक' ईवेंट के लिए उपलब्ध होना चाहिए। यदि आपको अभी भी समस्याएं आ रही हैं तो हो सकता है कि आपने गलत फिक्स में अपना फिक्स पोस्ट किया हो या आपके कोड में कहीं और त्रुटि हो। त्रुटियों की जांच करने के लिए अपने डिलीपर कंसोल (लगभग हमेशा 'एफ +12') खोलें। – Jasper

+0

आपने मुझे घंटे बचाया! धन्यवाद! – Michal

0

यदि आपको संदेह है कि एक फॉर्म (उदाहरण के लिए एक पॉपअप फॉर्म) कई पेज बना रहा है, तो आप प्रत्येक फॉर्म के फॉर्म तत्व में डेटा-AJAX = "false" जोड़ने का प्रयास करते हैं। यह मेरी समस्या हल हो गई।

संबंधित मुद्दे