2012-04-17 7 views
13

का उपयोग कर LI तत्वों डालने मुझे लगता है कि एन कॉलम इतना बड़ा हो स्तंभ के सभी से संभव LI के सभी तत्वों को शामिल करने की जरूरत है कि होता है एक HTML/जावास्क्रिप्ट आवेदन किया है।जावास्क्रिप्ट यूएल तत्व की ऊंचाई का आकार बदलने नहीं कभी कभी जब Jquery

सरल उपाय, प्रत्येक स्तंभ में आइटम के सभी की ऊंचाइयों गिनती गद्दी के लिए क्षतिपूर्ति, और फिर कॉलम से प्रत्येक के लिए है कि कुल करने के लिए ऊंचाई सेट करने लगता है।

यह महान काम करता है जब LI तत्वों सादा पाठ होते हैं। दुर्भाग्यवश, जब LI तत्वों के बजाय छवियां होती हैं, तो विभिन्न ब्राउज़रों में समस्याएं होती हैं। उदाहरण के लिए, जब मैं पहली बार फ़ायरफ़ॉक्स में पेज लोड करता हूं, तो यह नीचे स्क्रीनशॉट जैसा दिखता है, लेकिन एक और रीफ्रेश पर, यह ठीक काम करता है। यह क्रोम में अपेक्षा के अनुसार काम नहीं करता है।

Screenshot Showing the height of the UL element is not in sync with the LI elements

मेरा आवेदन नहीं LI तत्वों प्री-पॉप्युलेट करता है पृष्ठ लोड होने - यह जावास्क्रिप्ट का उपयोग करता, इस प्रकार है:

function populateUnsetAnswers(unsetCategoryAnswers) { 
    for (i in unsetCategoryAnswers) { 
     if (unsetCategoryAnswers.hasOwnProperty(i.toString())) { 
      $('#categoryQuestionArea #possibleAnswers').append(
       categoryAnswerLiTag(unsetCategoryAnswers[i]) 
      ); 
     } 
    } 
} 

function categoryAnswerLiTag(unsetCategoryAnswer) { 
    var html = '<li id="' + unsetCategoryAnswer.id + '">'; 

    if (unsetCategoryAnswer.image) { 
     html += '<img class="categoryAnswerImage" title="'; 
     html += unsetCategoryAnswer.text; 
     html += '" src="/trainingdividend/rest/streaming/'; 
     html += unsetCategoryAnswer.image.fileName; 
     html += '" style="height: '; 
     html += unsetCategoryAnswer.image.height; 
     html += ';'; 
     html += '" />'; 
    } else { 
     html += unsetCategoryAnswer.text 
    } 

    html += '</li>'; 

    return html; 
} 

पेज लोड हो रहा है किया जाता है, तो एक ajax अनुरोध सभी को हासिल करेगा वस्तुओं को एलआई तत्वों में डालने के लिए, और फिर ऊपर दिए गए पहले कार्य को कॉल करें।

LI तत्वों की सब के बाद बनाई गई हैं, मैं इसे बाद सही इस फ़ंक्शन को कॉल करें:

function resize() { 
    var currentHeight, totalHeight; 
    totalHeight = 0; 

    $("#categoryQuestionArea ul").children().each(function() { 
     currentHeight = $(this).height(); 

     totalHeight += currentHeight + 13; 
    }); 

    $("#categoryQuestionArea ul").height(totalHeight); 
    $("#categoryQuestionArea div#separator").css("padding-top", (totalHeight/2) + "px"); 
} 

वहाँ किसी भी तरह से jQuery बताने के लिए है, "आकार परिवर्तन() LI के के सभी जब तक कॉल न करें पूरी तरह से लोड और छवियों ने प्रस्तुत किया है "?

मुझे लगता है कि क्या हो रहा है यह है कि प्रारंभिक पृष्ठ लोड पर, इन LI तत्वों की ऊंचाई 0 या एक छोटा मान है क्योंकि इसमें छवि नहीं है, इसलिए मेरा आकार बदलने का कार्य गलत परिणाम की गणना कर रहा है (मैंने इसका परीक्षण किया कुछ चेतावनी बयान के साथ)। जब तक एलआईएस आबादी हो जाती है और छवियां लोड हो जाती हैं, तो कुल ऊंचाई की गणना ठीक होती है।

कोई मदद? धन्यवाद

+0

जहां आप अपने कोड में बिल्कुल 'आकार बदलें) फ़ंक्शन को कॉल कर रहे हैं? जो मैं यहां देख सकता हूं, उससे आप इसे 'populateUnsetAnswers()' के अंत में कॉल कर सकते हैं और 'जावास्क्रिप्ट' आकार का आकार बदल देगा। –

+0

@ केमालफैडिलह हां, आकार बदलें() को पहले से ही populateUnsetAnswers() के बाद बुलाया जाता है। यह केवल तभी फ़ायरफ़ॉक्स में काम करता है जब आप पेज रीफ्रेश करते हैं। यह अभी भी क्रोम में बिल्कुल काम नहीं करता है। –

+0

@FireEmblem आपको ऊंचाई को सेट करने की आवश्यकता नहीं है, कॉलम सामग्री फिट करने के लिए लंबवत विस्तारित होगा। –

उत्तर

1

आप पहली बार पृष्ठ लोड पर छवियों के साथ समस्या है करते हैं शायद यह तथ्य है कि वे कैश नहीं हैं और इसलिए तत्काल उपलब्ध नहीं के कारण है। तो उनकी ऊंचाई मापने बुरा परिणाम प्राप्त होंगे ... आप ऊंचाई कि उदाहरण

currentHeight = $(this).height(); 
console.log(currentHeight); 

एक ही तरीका है कि ऐसा करने के लिए मैं सभी छवियों की इवेंट लोड (निरीक्षण करने के लिए लगता है के लिए jQuery (के माध्यम से प्राप्त किया गया था डिबग था और शायद के रूप में अच्छी त्रुटि) और गिनती कि क्या सभी अनुरोध समाप्त कर दिया है

+0

हां, मैंने वर्तमान ऊंचाई को डीबग किया था। पहले पृष्ठ लोड पर, ऊंचाई अक्सर 0 होती है। बाद के पृष्ठ पर ताज़ा होता है, ऊंचाई सही होती है। –

+1

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

+0

@FireEmblem - मैंने नीचे दिए गए मेरे उत्तर में कोड दिया है जो सभी छवियों को लोड होने पर ट्रैक रखता है और सभी ऊंचाई मान्य होने पर 'आकार बदलें) कॉल करता है। – jfriend00

0

$('img').load(function(){ 
    //put code here 
}); 
0

का उपयोग कर मुझे लगता है कि अपने HTML। विशेष रूप से, अपने <img> टैग बँधा हुआ है की कोशिश करो।

+०१२३५१६४१०

अपने <img> टैग करने के लिए width और height विशेषताएं जोड़ें। सबकुछ जादुई हल हो जाएगा। http://jsfiddle.net/Ralt/Vwg7P/

हालांकि में कोई छवि नहीं है, width और height गुण अंतरिक्ष छवि के लिए आवश्यक को घेरता है:

इस jsfiddle को समझने के लिए मैं क्या मतलब देखें। जैसे ही डोम लोड हो जाता है।

2

यहाँ है की जाँच करता है कि छवियों लोड किया है एक jQuery प्लगइन: अपने मामले के लिए https://github.com/alexanderdickson/waitForImages

नमूना उपयोग होगा:

$('#categoryQuestionArea').waitForImages(function() { 
    resize(); 
}); 

मैं भी सिर्फ <ul> के बजाय की कुल ऊंचाई के लिए जाँच करेगा सूची आइटम के माध्यम से पाशन आप मैन्युअल रूप से स्क्रिप्ट बदलने के लिए करता है, तो या तो गद्दी, मार्जिन, या सूची आइटम पर सीमाओं पर बाद में बदल जाता है के रूप में।

+0

यह निश्चित रूप से सर्वर से छवियों को लोड करने वाले ब्राउज़र से पहले ऊंचाई की गणना करने का प्रयास करने वाला एक मुद्दा है। (दूसरे अनुरोध पर, छवियों को कैश किया जाता है।) समाधान सभी छवियों को लोड होने के बाद गणना में देरी करना है (या प्रत्येक छवि लोड होने के बाद भी इसे अद्यतन करना)। –

-1

मुझे लगता है कि ब्राउज़र छवियों के आयामों को नहीं जानता है, क्योंकि वे लोड नहीं होते हैं।

या तो एक

jQuery(document).load(function funcName() { 
    ... 
}) 

में resize के आह्वान रैप करने के लिए या छवि एचटीएमएल img टैग में width और height विशेषताओं देने का प्रयास करें।

हो सकता है कि दोनों

+0

यह काम नहीं करेगा क्योंकि छवियों को जावास्क्रिप्ट कोड के माध्यम से पृष्ठ में गतिशील रूप से डाला जाता है। – jfriend00

+0

जेएस के माध्यम से छवियों को सम्मिलित करते समय, आपको छवि आयामों को भी लोड करना चाहिए। – HerrSerker

0

यह एक सीएसएस समस्या, सबसे शायद कारण एक निश्चित ऊंचाई बल्कि है आइटम के साथ या तो जारी या बिल्कुल तैनात।

इसे ठीक करने के कई तरीके हैं।

  1. बजाय एक ऊंचाई फिक्सिंग के min-height दे।

    #container { min-height: 100px; } 
    
  2. साफ़ float और निर्धारित नहीं करते किसी भी ऊंचाइयों

    #container { overflow: hidden; } 
    
  3. उपयोग स्क्रिप्ट ऊंचाई को जोड़ने के लिए, एक बार हर तत्व जोड़ा जाता है। jQuery की तरह झलकी

    नीचे
    $("#container").append($("#theimg")); 
    $("#container").height($("#container").height()+$("#theimg").height()); 
    
0

मुझे लगता है कि मैं तुम्हारे लिए एक समाधान हो सकता है।

मेरे समाधान का मुख्य विचार सीएसएस में निहित है। आप एक ही ऊंचाई के 3 कॉलम के लिए, है ना? http://jsfiddle.net/agilius/NvzZp/46/

काफी सीएसएस का एक बहुत वहाँ है, लेकिन मुख्य विचार यह है::

  1. मैं वास्तविक सामग्री के तहत एक 3 कॉलम लेआउट अनुकरण, .inner के साथ और आप कुछ इस तरह हो सकता है .column कक्षाएं।
  2. सामग्री को (जेड-इंडेक्स 2> .inner zindex 1 के माध्यम से) पर रखा गया है, जो कॉलम के समान चौड़ाई के साथ है।
  3. सामग्री सामग्री क्षेत्रों के लिए मुख्य #container अपडेट की ऊंचाई जोड़ा जाता है,।
  4. चूंकि .inner शीर्ष, बाएं, दाएं, नीचे = 0 है, यह अपडेट होता है, और चूंकि .columns में 100% ऊंचाई होती है, इसलिए वे # कंटेनर ऊंचाई से मेल खाने के लिए अपनी ऊंचाई अपडेट करते हैं।

अवलोकन।

आप फिट बैठते समय .column कक्षा में पैडिंग, सीमाएं, मार्जिन प्राप्त कर सकते हैं।

कोई जावास्क्रिप्ट आवश्यक नहीं है।

3

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

  • एक चर remainingAnswerImages जोड़ें:

    var remainingAnswerImages = 0; 
    
    function categoryAnswerImageLoadHandler() { 
        --remainingAnswerImages; 
        if (remainingAnswerImages === 0) { 
         resize(); 
        } 
    } 
    
    function populateUnsetAnswers(unsetCategoryAnswers) { 
        // add one extra to the image count so we won't have any chance 
        // at getting to zero before loading all the images 
        ++remainingAnswerImages; 
        var possibleAnswers$ = $('#categoryQuestionArea #possibleAnswers'); 
        for (i in unsetCategoryAnswers) { 
         if (unsetCategoryAnswers.hasOwnProperty(i.toString())) { 
          possibleAnswers$.append(categoryAnswerLiTag(unsetCategoryAnswers[i])); 
         } 
        } 
        // remove the one extra 
        --remainingAnswerImages; 
        // if we hit zero on the count, then there either were no images 
        // or all of them loaded immediately from the cache 
        // if the count isn't zero here, then the 
        // categoryAnswerImageLoadHandler() function will detect when it does hit zero 
        if (remainingAnswerImages === 0) { 
         resize(); 
        } 
    } 
    
    function categoryAnswerLiTag(unsetCategoryAnswer) { 
        var obj = document.createElement("li"); 
        obj.id = unsetCategoryAnswer.id; 
    
        if (unsetCategoryAnswer.image) { 
         // count this image 
         ++remainingAnswerImages; 
         var img = new Image(); 
         img.onload = img.onerror = img.onabort = categoryAnswerImageLoadHandler; 
         img.title = unsetCategoryAnswer.text; 
         img.style.height = unsetCategoryAnswer.image.height; 
         img.src = "/trainingdividend/rest/streaming/" + unsetCategoryAnswer.image.fileName; 
         obj.appendChild(img); 
        } else { 
         obj.innerHTML = unsetCategoryAnswer.text; 
        } 
        return obj; 
    } 
    

    विवरण के वैसे, इस कोड को निम्नलिखित परिवर्तन करता है लोड किया जाना है।

  • प्रत्येक <img> टैग के लिए एक अधिभार हैंडलर जोड़ें जो बनाया गया है ताकि हम लोड होने पर ट्रैक रख सकें।
  • प्रत्येक बार हम ऑनलोड हैंडलर के साथ टैग के लिए HTML उत्पन्न करते हैं, remainingAnswerImages वृद्धि करते हैं।
  • जब आप सभी एचटीएमएल जोड़ते हैं, तो यह देखने के लिए remainingAnswerImages गिनती देखें कि यह शून्य है (यह केवल तभी होगा जब कोई छवि न हो या ब्राउज़र छवि कैश से तुरंत सभी छवियां लोड हों)। यदि ऐसा है, तो तुरंत आकार बदलें()।
  • ऑनलोड हैंडलर में प्रत्येक छवि के लिए कहा जाएगा, remainingAnswerImages घटाएं और यदि गिनती शून्य हो गई है, तो resize() पर कॉल करें।
  • छवियों को जोड़ने के दौरान, remainingAnswerImages पर एक अतिरिक्त गेट तक पहुंचने के लिए एक गेट के रूप में जोड़ें, जब तक कि हम छवियों को जोड़ नहीं लेते। छवियों को जोड़ने के दौरान, इसे एक अतिरिक्त निकालें।
  • मैं भी categoryAnswerLiTag() फ़ंक्शन को फिर से लिखता हूं ताकि HTML में स्ट्रिंग्स के समूह को एक साथ जोड़कर सीधे डोम ऑब्जेक्ट्स बना सकें। इस मामले में, कोड पढ़ने और बनाए रखने के लिए बहुत साफ है।
  • मैंने आपके for लूप से $('#categoryQuestionArea #possibleAnswers') भी स्थानांतरित कर दिया क्योंकि यह हर बार एक ही चीज़ को हल करता है। लूप से पहले एक बार ऐसा करने के लिए बेहतर है। इसके अलावा, ज्यादातर मामलों में, इसे $('#possibleAnswers') तक सरलीकृत किया जा सकता है क्योंकि पेज में आईडी को अद्वितीय माना जाता है।
0

एक और सरल समान ऊंचाई सीएसएस समाधान:

लॉजिक बहुत सरल है - कॉलम/LI के सभी के साथ .eH {padding-bottom जारी कर रहे हैं: एक्स; margin-bottom: -X} और आवरण/यूएल .eW है {अतिप्रवाह: छिपा हुआ}

एक्स = बड़े मनमाना पिक्सल की सुरक्षा के कारक के लिए राशि

उदाहरण: http://jsfiddle.net/rahen/TXVYD/4/

0

यह सूडोस्लाइडर को कोड करते समय मेरी समस्याओं में से एक जैसा लगता है।

नीचे मैंने कोड को कॉपी किया है जिसके साथ मैंने इसे हल किया है। अपने आकार() फ़ंक्शन के अंदर बस autoheightwidth(i, 0, true) पर कॉल करें।

मूल विचार यह है कि आपको पता नहीं है कि ब्राउजर ने छवियों को लोड करने के दौरान कब पूरा किया है, इसलिए एक ऊंचाई समायोजन पर भरोसा करने के बजाय, जब भी कुछ होता है तो ऊंचाई को समायोजित करते हैं (ज्यादातर सिर्फ एक छवि लोड हो जाती है) ।

यदि आप पहले 2 तरीकों में "obj" और "li" के संदर्भों को बदलते हैं तो यह काम करना चाहिए।

यह बहुत पठनीय नहीं है, लेकिन जब मैंने इसे कोड किया तो आकार पर एक बड़ा फोकस था।

// Automaticly adjust the height and width, i love this function. 
// Before i had one function for adjusting height, and one for width. 
function autoheightwidth(i, speed, axis) // Axis: true == height, false == width. 
{ 
    obj.ready(function() {// Not using .load(), because that only triggers when something is loaded. 
     adjustHeightWidth (i, speed, axis); 
     // Then i run it again after the images has been loaded. (If any) 
     // I know everything should be loaded, but just in case. 
     runOnImagesLoaded (li.eq(i), falsev, function(){ 
      adjustHeightWidth (i, speed, axis); 
     }); 
    }); 
}; 
function adjustHeightWidth (i, speed, axis) 
{ 
    var i = getRealPos(i); // I assume that the continuous clones, and the original element is the same height. So i allways adjust acording to the original element. 
    var target = li.eq(i); 
    // First i run it. In case there are no images to be loaded. 
    var b = target[axis ? "height" : "width"](); 
    obj.animate(
     axis ? {height : b} : {width : b}, 
     { 
      queue:falsev, 
      duration:speed, 
      easing:option[8]/*ease*/ 
     } 
    ); 
} 
function runOnImagesLoaded (target, allSlides, callback) // This function have to be rock stable, cause i use it ALL the time! 
{ 
    var elems = target.add(target.find('img')).filter('img'); 
    var len = elems.length; 
    if (!len) 
    { 
     callback(); 
     // No need to do anything else. 
     return this; 
    } 
    function loadFunction(that) 
    { 
     $(that).unbind('load').unbind('error'); 
     // Webkit/Chrome (not sure) fix. 
     if (that.naturalHeight && !that.clientHeight) 
     { 
      $(that).height(that.naturalHeight).width(that.naturalWidth); 
     } 
     if (allSlides) 
     { 
      len--; 
      if (len == 0) 
      { 
       callback(); 
      } 
     } 
     else 
     { 
      callback(); 
     } 
    } 
    elems.each(function(){ 
     var that = this; 
     $(that).load(function() { 
      loadFunction(that); 
     }).error(function() { 
      loadFunction(that); 
     }); 
     /* 
     * Start ugly working IE fix. 
     */ 
     if (that.readyState == "complete") 
     { 
      $(that).trigger("load");  
     } 
     else if (that.readyState) 
     { 
      // Sometimes IE doesn't fire the readystatechange, even though the readystate has been changed to complete. AARRGHH!! I HATE IE, I HATE IT, I HATE IE! 
      that.src = that.src; // Do not ask me why this works, ask the IE team! 
     } 
     /* 
     * End ugly working IE fix. 
     */ 
     else if (that.complete) 
     { 
      $(that).trigger("load"); 
     } 
     else if (that.complete === undefined) 
     { 
      var src = that.src; 
      // webkit hack from http://groups.google.com/group/jquery-dev/browse_thread/thread/eee6ab7b2da50e1f 
      // data uri bypasses webkit log warning (thx doug jones) 
      that.src = "data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///ywAAAAAAQABAAACAUwAOw=="; // This is about the smallest image you can make. 
      that.src = src; 
     } 
    }); 
} 
संबंधित मुद्दे