2012-02-04 14 views
8

मेरे पास एक छायाबॉक्स स्क्रिप्ट है। जब मैं पृष्ठ लोड करता हूं तो सब कुछ ठीक काम करता है, लेकिन जब मैं इस jquery लोड फ़ंक्शन को कॉल करता हूं और फिर छवि पर क्लिक करके छायाबॉक्स को ट्रिगर करने का प्रयास करता हूं, तो बड़ी छवि इसके बजाय नई विंडो में खुलती है। यहां कोड है:शैडोबॉक्स jquery फ़ंक्शन कॉल के बाद काम करना बंद कर देता है

<link href="CSS/main.css" rel="stylesheet" type="text/css" /> 
<script type="text/javascript" src="shadowbox-3.0.3/shadowbox.js"></script> 
<script type="text/javascript"> 
Shadowbox.init(); 
</script> 

<p id="compas"><a href="images/coverage.jpg" rel="shadowbox" title="Coverage map"></a></p> 

कोई विचार यह क्यों हो रहा है?

+0

के लिए धन्यवाद क्या त्रुटि कंसोल (Firebug, क्रोम कंसोल) रिपोर्ट करता है?आप शायद पर्सिस्ट का भी उपयोग करना चाहेंगे। –

+0

कुछ भी नहीं दिखाता है। छवियां नई साधारण खिड़की में खुलती हैं। – Igor

+0

जो मैं देख रहा हूं, मैं प्रति गलत कुछ भी नहीं खोजता हूं। क्या आपके पास एक लिंक है? –

उत्तर

10

संपादित

तो, हम अंत में इस के नीचे मिल । इस मुद्दे पर पहली बार टिप्पणी करने के 15 घंटे बाद, और कम से कम 50 पुनरावृत्तियों बाद में, हमने अंततः पहचान की है कि समस्या क्या है और इसे कैसे ठीक किया जाए।

यह वास्तव में अचानक मुझे मारा जब मैं अपने सर्वर पर स्थानीय aaa.html और bbb.html बना रहा था। वह तब था जब उसने मुझे मारा कि सामग्री को बदलने के लिए तत्व नोड्स को डीओएम से हटा दिया गया था जब $.load() कॉलबैक फ़ंक्शन चलाता है। इसलिए, #menu-home सामग्री तत्वों को प्रतिस्थापित करने के बाद, उन्हें DOM से हटा दिया गया था और अब उन्हें छायाबॉक्स लागू नहीं किया गया था।

एक बार मैं इस पता लगा है, यह एक वेब खोज का मामला था और मैंने पाया:

Nabble-Shadowbox - Reinit Shadowbox

विशेष रूप से, mjijackson से प्रतिक्रिया।

Shadowbox.clearCache(); 
Shadowbox.setup(); 

तो एक बार #menu-home सामग्री पुनः लोड किया गया था, क्या होने की जरूरत है Shadowbox कैश साफ़ कर दिया की जरूरत है (अनिवार्य रूप से, पर यह नीचे बंद: क्या वह बताता है कि कैसे करने के लिए "पुनः आरंभ" (reinitialize) Shadowbox उपयोग कर रहा है पृष्ठ), तो Shadowbox.setup() चलाया गया है, जो सभी बार तत्वों का पता लगाएगा। आप फिर से Shadowbox.init() विधि नहीं चलाते हैं।

मैंने देखा कि आपने के बाद के बाद कोड में कम से कम अनुक्रमिक रूप से कॉपी/पेस्ट करने का प्रयास किया था। हालांकि, यह कैश समाशोधन के कारण काम नहीं करेगा, क्योंकि पहले होने की आवश्यकता है, और मुख्य रूप से .clearCache() और .setup() कार्यों को $.load() पूरा करने के बाद (किसी भी कॉलबैक को समाप्त और चलाता है) चलाने की आवश्यकता है। उन दो कार्यों को $.load() कॉलबैक हैंडलर में चलाने की आवश्यकता है; अन्यथा, आप इसे तुरंत चला रहे हैं, लेकिन $.load() असीमित है और कुछ समय बाद पूरा हो जाएगा।

मैं अपने द्वारा किए गए कुछ अन्य परिवर्तनों पर जा रहा हूं, बस आप समझते हैं कि क्यों, क्यों और क्यों।

ध्यान दें, मुझे यकीन है कि अगर आप <base> से परिचित हैं नहीं कर रहा हूँ, लेकिन अगले HEAD तत्व के शीर्ष पर है:

<base href="http://62.162.170.125/"/> 

यह सिर्फ मुझे अपने कंप्यूटर पर संसाधन फ़ाइलों का उपयोग करते हैं। आप इसे अपनी वास्तविक साइट पर संभवतः अधिक से अधिक उपयोग नहीं करना चाहेंगे। यदि आप कॉपी/पेस्ट करते हैं, तो सुनिश्चित करें और इस लाइन को हटा दें।

<div id="menu"> 
    <ul> 
    <li><a id="menu-home" href="index.html" rel="http://jfcoder.com/test/homecontent.html">Home</a></li> 
    <li><a id="menu-services" href="services.html" rel="http://jfcoder.com/test/servicescontent.html">Services</a></li> 
    <li><a id="menu-tour" href="tour.html" rel="http://jfcoder.com/test/tourcontent.html">Tour</a></li> 
    <li><a id="menulogin" href="login.html">Login</a></li> 
    </ul> 
</div> 

यहाँ, आप मैं HREF विशेषता में एक रिश्तेदार यूआरएल, और अपने सर्वर पर कुछ पृष्ठों के लिए एक कड़ी पर ध्यान देंगे। मेरे सर्वर के लिंक का कारण यह है कि मैं क्रॉस-साइट स्क्रिप्टिंग सीमाओं के कारण AJAX के माध्यम से aaa.html और bbb.html फ़ाइलों तक नहीं पहुंच सका। मेरी वेबसाइट के लिंक भी हटा दिए जाने चाहिए।

अब, कारण मैं rel विशेषता का उपयोग कर रहा हूं, यह है कि मैं href विशेषता के माध्यम से लिंक को अनुमति देना जारी रखता हूं ताकि जेएस सही तरीके से काम न करे या कोई अन्य त्रुटि हो। यदि आपके पास अलग-अलग फाइलें हैं, एक पूर्ण HTML दस्तावेज़ के लिए और दूसरा केवल टुकड़ों के लिए, यह वही है जो आप करना चाहते हैं। यदि आप पूरी तरह से लिंक किए गए फ़ाइल से पूर्ण दस्तावेज़ और सामग्री दोनों की सेवा कर सकते हैं, तो आपको शायद rel विशेषता की आवश्यकता नहीं है, लेकिन आपको अनुरोध प्रबंधित करने की आवश्यकता होगी ताकि सर्वर जानता है कि कैसे प्रतिक्रिया दें (पूर्ण दस्तावेज़ या बस सामग्री भाग)।

var boxInitialize = function(){ 
    try { 
     if (!Shadowbox.initialized) { 
      Shadowbox.init(); 
      Shadowbox.initialized = true; 
     } else { 
      Shadowbox.clearCache(); 
      Shadowbox.setup(); 
     } 
    } catch(e) { 
     try { 
      Shadowbox.init(); 
     } catch(e) {}; 
    } 
}; 

मैंने जो कुछ किया है वह प्रारंभिक/सेटअप अनुरोधों के लिए एक केंद्रीय स्थान बना रहा है। काफी सरल। ध्यान दें, मैंने Shadowbox.initialized संपत्ति को जोड़ा है, इसलिए मैं ट्रैक कर सकता हूं कि Shadowbox.init() चलाया गया था, जिसे केवल एक बार चलाया जा सकता है। हालांकि, यदि संभव हो तो इसे एक ही स्थान पर रखना एक अच्छा विचार है।

मैं भी एक चर समारोह है जो या तो एक नियमित रूप से समारोह के रूप में कहा जा सकता है बनाया:

boxInitialize(); 

या एक समारोह संदर्भ के रूप में:

window.onload = boxInitialize; // Note, no() at the end, which execute the function 

आप शायद ध्यान देंगे मैं हटा दिया $() और इसके बजाय jQuery() के साथ उन्हें बदल दिया। यदि आप $() के लिए प्रतिस्पर्धा करने वाले कई ढांचे और पुस्तकालयों के साथ पर्यावरण के साथ समाप्त होते हैं, तो यह वास्तविक दुःस्वप्न में बदल सकता है, इसलिए इससे बचने के लिए सबसे अच्छा है। यह वास्तव में बस मुझे दूसरे दिन अच्छा लगा।

चूंकि हमारे पास .ready() कॉलबैक के भीतर एक बंद करने का दायरा है, इसलिए हम स्क्रिप्ट निष्पादन में अलग-अलग समय पर ओउ उपयोग के लिए कई "निजी" चरों को सहेजने के लिए इसका लाभ उठा सकते हैं।

var $ = jQuery, 
    $content = jQuery("#content"), // This is "caching" the jQuery selected result 
    view = '', 
    detectcachedview = '', 
    $fragment, 
    s = Object.prototype.toString, 
    init; 

नोट सभी के अंत में , लेकिन अंतिम पंक्ति। देखें कि मैं $ को jQuery चर के बराबर बनाकर "आयात" कैसे करता हूं, जिसका अर्थ है कि आप वास्तव में उस # में इसका उपयोग कर सकते हैं।

var loadCallback = function(response, status, xhr){ 
    if (init != '' && s.call(init) == '[object Function]') { 
     boxInitialize(); 
    } 

    if (xhr.success() 
      && view != '' 
      && typeof view == 'string' 
       && view.length > 1) { 
     $fragment = $content.clone(true, true); 
     cacheContent(view, $fragment); 
    } 
}; 

यह तब चलता है जब $.load() AJAX अनुरोध करने की प्रक्रिया पूरा करती है। ध्यान दें, अनुरोध में लौटाई गई सामग्री को पहले ही डीओएम पर चलाया जा चुका है। ध्यान दें कि हम $content.data() में वास्तविक कैश्ड सामग्री संग्रहीत कर रहे हैं, जिसे पृष्ठ से कभी नहीं हटाया जाना चाहिए; केवल इसके नीचे सामग्री।

var cacheContent = function(key, $data){ 
    if (typeof key == 'string' 
      && key.length > 1 
      && $data instanceof jQuery) { 
     $content.data(key, $data.html()); 
     $content.data(detectcachedview, true); 
    } 
}; 

cacheContent() एक ऐसा तरीका है जिसे आप नहीं चाहते हैं; अनिवार्य रूप से, अगर यह पहले से ही पिछले अनुरोध पर लोड किया गया था, तो उसे सर्वर से सामग्री प्राप्त करने के लिए एक और $.load() शुरू करने के बजाय कैश किया जाएगा और फिर सीधे पुनर्प्राप्त किया जाएगा। आप ऐसा नहीं करना चाहेंगे; यदि ऐसा है, तो menuLoadContent() फ़ंक्शन में दूसरे if ब्लॉक पर टिप्पणी करें।

var setContent = function(html){ 
    $content.empty().html(html); 

    if (init != '' && s.call(init) == '[object Function]') { 
     boxInitialize(); 
    } 
}; 

यह क्या करता है पहले खाली $content यह तत्व सामग्री/तत्व है, तो यह है कि हम $content.html() हो रही द्वारा पहले सहेजा निर्दिष्ट स्ट्रिंग आधारित मार्कअप जोड़ना है। जब हम संभव हो तो हम फिर से जोड़ देंगे; एक बार विभिन्न लिंक क्लिक किए जाने और लोड होने के बाद आप देख सकते हैं, इसे फिर से चलाने के लिए पुनः प्राप्त करना वास्तव में तेज़ है। साथ ही, यदि यह वर्तमान में लोड होने के समान अनुरोध है, तो यह कोड को पूरी तरह से चलाने को छोड़ देगा।

(हम $content का उपयोग करते हैं क्योंकि यह एक jQuery तत्व युक्त चर के संदर्भ में है। मैं ऐसा इसलिए कर रहा हूं क्योंकि यह एक बंद-दायरे में है, जिसका अर्थ यह है कि यह वैश्विक दायरे में दिखाई नहीं देता है, लेकिन होगा ।। कोड में इनलाइन टिप्पणी के लिए ईवेंट हैंडलर्स जैसी चीजों के लिए उपलब्ध

देखो

var menuLoadContent = function(){ 
    // This is where I cancel the request; we're going to show the same thing 
    // again, so why not just cancel? 
    if (view == this.id || !this.rel) { 
     return false; 
    } 

    // I use this in setContent() and loadCallback() functions to detect if 
    // the Shadowbox needs to be cleared and re-setup. This and code below 
    // resolve the issue you were having with the compass functionality. 
    init = this.id == 'menu-home' ? boxInitialize : ''; 
    view = this.id; 
    detectcachedview = "__" + view; 

    // This is what blocks the superfluous $.load() calls for content that's 
    // already been cached. 
    if ($content.data(detectcachedview) === true) { 
     setContent($content.data(view)); 
     return false; 
    } 

    // Now I have this in two different spots; there's also one up in 
    // loadCallback(). Why? Because I want to cache the content that 
    // loaded on the initial page view, so if you try to go back to 
    // it, you'll just pickup what was sent with the full document. 
    // Also note I'm cloning $content, and then get it's .html() 
    // in cacheContent(). 
    $fragment = $content.clone(true, true); 
    cacheContent(view, $fragment); 

    // See how I use the loadCallback as a function reference, and omit 
    // the() so it's not called immediately? 
    $content.load(this.rel, loadCallback); 

    // These return false's in this function block the link from navigating 
    // to it's href URL. 
    return false; 
}; 

अब, मैं अलग तरह से प्रासंगिक मेनू आइटम का चयन आप प्रत्येक तत्व के लिए एक अलग $.click() घोषणा की जरूरत नहीं है। इसके बजाय, मैं #menu a[rel] का चयन करता हूं, जो प्रत्येकप्राप्त करेगा मेनू मेंतत्व जिसमें rel="not empty rel attribute" है। दोबारा, ध्यान दें कि मैं फ़ंक्शन संदर्भ के रूप में यहां menuLoadContent का उपयोग कैसे करता हूं।

jQuery("#menu a[rel]").click(menuLoadContent); 

फिर, निचले भाग पर, मैं boxInitialize(); सेटअप करने के लिए Shadowbox चलाते हैं।

यदि आपके कोई प्रश्न हैं तो मुझे बताएं।


मुझे लगता है कि मैं इसके नीचे जा रहा हूं। मुझे लगता है कि दोष जिस तरह से आप नई सामग्री का $.load() संभाल रहे हैं जब एक मेनू आइटम पर क्लिक करके, न आया हुआ अपवाद मैं एक iframe साथ क्या करने वाले देखा के साथ मिलकर है:

न आया हुआ अपवाद: अज्ञात खिलाड़ी आइफ्रेम

यह Nabble-Shadowbox forum thread इस त्रुटि से संबंधित है। मैं वास्तव में अब यह नहीं प्राप्त कर रहा हूं, हालांकि मुझे लगता है कि यह आया है कि मैंने tour मेनू आइटम पर क्लिक किया था।

अब, मेनू आइटम के लिए सामग्री को लोड करने के लिए आप क्या कर रहे हैं वास्तव में कोई समझ नहीं आता है। आप एक संपूर्ण HTML दस्तावेज़ का अनुरोध कर रहे हैं, और फिर class="content" के साथ केवल एक तत्व का चयन कर रहे हैं। ऐसा करने के लिए मैं केवल एकमात्र लाभ देख सकता हूं कि पृष्ठ कभी भी पुनः लोड नहीं होता है, लेकिन आपको उस डेटा को कैसे प्राप्त और प्रदर्शित करने के लिए एक और दृष्टिकोण लेने की आवश्यकता है जिसमें पूरे पृष्ठ को AJAX के माध्यम से डाउनलोड करने और फिर पार्स को पार्स करने का प्रयास करने में शामिल नहीं है बस आप चाहते हैं कि हिस्सा।

मुझे विश्वास है कि इस तरह से लोड होने वाली सामग्री को संभालने से आपकी समस्या का मूल कारण है, इसलिए $.load() मेनू दृश्यों की टॉगलिंग आपके पृष्ठ को अप्रत्याशित तरीके से तोड़ देती है।

प्रश्न: आप वास्तविक पृष्ठ से क्यों लिंक नहीं करते हैं और सभी $.load() फैंसीपन को छोड़ते हैं? स्पीड-वार, इससे कोई प्रभाव नहीं पड़ेगा, अगर कोई भी हो। यह इस तरह AJAX का उपयोग करने के लिए समझ में नहीं आता है, जब आप उन्हें बिना किसी समस्या के एक ही सामग्री से जोड़ सकते हैं।

  1. सेटअप आपके AJAX कॉल केवल मार्कअप के .content भाग अनुरोध करने के लिए यदि आप URL में ?contentonly=true झंडा है, नहीं:

    दो विकल्प है कि आप गोल पृष्ठ पुनः लोड को रोकने के लिए अनुमति होगी रहे हैं संपूर्ण एचटीएमएल दस्तावेज़। इस तरह परंपरागत रूप से किया जाता है, और आमतौर पर ऐसा करने के लिए सापेक्ष सरल होता है यदि आपके पास एक स्क्रिप्टिंग वातावरण है।

    $(".content").load('index.html?contentonly=true'); 
    

    तब आपका सर्वर अनुरोधित सामग्री दृश्य के साथ ही प्रतिक्रिया देता है।

  2. परोसें ही HTML दस्तावेज़ में सामग्री दृश्यों के सभी है, तो के रूप में उपयुक्त दिखाने:

    var $content = $('.content'); 
    $content.find('.content-view').hide(); 
    $content.find('#services-content').show(); 
    

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

या तो इन तकनीकों, सामग्री लोड करने हालांकि मेरा मानना ​​है कि वहाँ खोज इंजन के लिए इस के साथ कुछ मुद्दों कर रहे हैं #! (hashbang) तकनीक का इस्तेमाल कर सकते है। हालांकि, यहां एक सरल तकनीक मैं एक साथ कुछ समय पहले डाल करने के लिए एक कड़ी है:

http://jfcoder.com/test/hash.html

इसके अलावा, यह सिर्फ एक टिप है, लेकिन एक class, यानी के साथ अपने "सामग्री" तत्व का उल्लेख नहीं है , .content। मार्कअप में केवल एक सामग्री-प्रदर्शित तत्व होना चाहिए, है ना? एक से अधिक नहीं है? id="content" का उपयोग करें; एक ही तत्व को संदर्भित करने के लिए ID विशेषताएँ हैं। class es कुछ तत्वों द्वारा समूह तत्वों को समूहित करने के लिए हैं, इसलिए जब मैं .hide() इनलाइन सामग्री दृश्य (देखें # 2), तो मैं सभी class="content-view" तत्वों की तलाश करता हूं, जो सभी समान हैं (उनमें सामग्री दृश्य मार्कअप शामिल है)। लेकिन $content चर को $('#content'); का संदर्भ लेना चाहिए। यह तत्वों के बारे में वर्णनात्मक है।

+0

मैं वास्तविक पृष्ठों को लिंक करना चाहता हूं, लेकिन यह आवश्यकताओं में नहीं है। ग्राहक पृष्ठ रीलोडिंग के बिना सामग्री को बदलना चाहता है। मैं एक संपूर्ण HTML पृष्ठ का अनुरोध कर रहा हूं और इससे सामग्री का चयन कर रहा हूं क्योंकि मैं मेनू आइटम 'href में वास्तविक लिंक डालने की सोच रहा था, इसलिए यदि कुछ उपयोगकर्ता का ब्राउज़र जावास्क्रिप्ट का समर्थन नहीं करता है, तो यह अभी भी काम करेगा। – Igor

+0

AJAX किसी लिंक-जैसी व्यवहार के माध्यम से गिरने वाला नहीं है, यह कुछ भी नहीं करेगा (जिसमें पूर्ण पृष्ठ लोड ट्रिगर नहीं किया जा रहा है)। आपको पूर्ण HTML दस्तावेज़ (नियमित रूप से GET roundtrip अनुरोध, जैसे एक लिंक क्लिक किया गया था), या केवल AJAX अनुरोध के दौरान प्रदर्शित करने के लिए खंड (सामग्री भाग) के साथ जवाब देने की आवश्यकता है। आप AJAX पर एक GET ध्वज के साथ इसे पूरा कर सकते हैं; बस 'href' विशेषता URL से ध्वज को छोड़ दें, इसलिए यह पूरे पृष्ठ पर आ जाएगा। फिर, सर्वर स्क्रिप्ट पर, यह पता लगाएं कि आपको पूर्ण HTML दस्तावेज़ या केवल सामग्री के साथ प्रतिक्रिया देने की आवश्यकता है या नहीं। –

+0

देखें [यह डेमो] (http://www.asp.net/ajaxLibrary/jQueryCodeSamplesWebForms/jQueryLoad/MainContentForm.aspx) फ़ायरबग या क्रोम के नेट कंसोल के साथ खुला है, और जब पृष्ठ खंड के लिए अनुरोध किया जाता है, तो देखें कि प्रतिक्रिया क्या है पाठ था। आप देखेंगे कि यह सिर्फ एक HTML खंड है, पूर्ण दस्तावेज़ नहीं। –

1

यह हमारे लिए काम किया है, हम एक साइट है कि ऊर्ध्वाधर टैब का इस्तेमाल किया और jQuery.load

का उपयोग कर बस अपने लंगर के सभी देना हमारे shadowbox छवियों के साथ पृष्ठों में बुलाया वर्ग = "sbox" टैग और इस पेस्ट बना शीर्षलेख में लिपि।

<script> 
    Shadowbox.init({ 
    skipSetup:true, 
}); 
$(document).ready(function() { 
    Shadowbox.setup($('.sbox'));//set up links with class of sbox 
    $('a.sbox').live('click',function(e){ 
     Shadowbox.open(this); 
     //Stops loading link 
     e.preventDefault(); 
    }); 
}); 
</script> 

नोट: हम सब अपने rel = "shadowbox" पर .sbox वर्ग को लगानी थी टैब है कि इस guy- को .load

धन्यवाद कहा जाता है के लिए लंगर पर और साथ ही लंगर >http://www.webmuse.co.uk/blog/shadowbox-ajax-and-other-generated-content-with-jquery-and-javascript/

0

ठीक है, शेम के उत्तर के आधार पर, यह मेरा समाधान है। विशिष्ट वर्ग, सेटअप और खुला shadowbox एक ही कक्षा से तत्वों के साथ पर प्रत्येक क्लिक:

jQuery('.sb-gallery a').live('click',function(e){ 
    Shadowbox.setup(jQuery('.sb-gallery a')); 
    Shadowbox.open(this); 
    //Stops loading link 
    e.preventDefault(); 
}); 

सभी

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