jQuery - जब दृश्यमान न हो तो तत्व की चौड़ाई प्राप्त करें (प्रदर्शन: कोई नहीं)


108

ऐसा लगता है जैसे jQuery में जब कोई तत्व दृश्यमान चौड़ाई नहीं है () 0. रिटर्न देता है, लेकिन मुझे माता-पिता को दिखाने से पहले माता-पिता की चौड़ाई सेट करने के लिए तालिका की चौड़ाई प्राप्त करने की आवश्यकता होती है।

जैसा कि नीचे उल्लेख किया गया है, माता-पिता में पाठ है, जो माता-पिता को तिरछा बनाता है और गंदा दिखता है। मैं चाहता हूं कि अभिभावक केवल टेबल की तरह चौड़े हों और टेक्स्ट रैप हो।

<div id="parent">
    Text here ... Can get very long and skew the parent
    <table> ... </table>
    Text here too ... which is why I want to shrink the parent based on the table
</div>

सीएसएस:

#parent
{
    display: none;
}

जावास्क्रिप्ट:

var tableWidth = $('#parent').children('table').outerWidth();
if (tableWidth > $('#parent').width())
{
    $('#parent').width(tableWidth);
}

tableWidth हमेशा 0 देता है क्योंकि यह दिखाई नहीं देता है (मेरा अनुमान है क्योंकि यह मुझे एक नंबर देता है जब दृश्य होता है)। क्या माता-पिता को दृश्यमान किए बिना तालिका की चौड़ाई प्राप्त करने का एक तरीका है?

जवाबों:


94

यहाँ एक चाल है जो मैंने प्रयोग की है। इसमें jQuery लगता है कि तत्व दिखाई दे रहा है बनाने के लिए कुछ CSS गुणों को जोड़ना शामिल है, लेकिन वास्तव में यह अभी भी छिपा हुआ है।

var $table = $("#parent").children("table");
$table.css({ position: "absolute", visibility: "hidden", display: "block" });
var tableWidth = $table.outerWidth();
$table.css({ position: "", visibility: "", display: "" });

यह एक तरह का हैक है, लेकिन यह मेरे लिए ठीक काम करता है।

अपडेट करें

मैंने तब से एक ब्लॉग पोस्ट लिखी है जो इस विषय को कवर करती है। ऊपर दी गई विधि में समस्याग्रस्त होने की क्षमता है क्योंकि आप सीएसएस गुणों को रिक्त मानों को रीसेट कर रहे हैं। क्या होगा यदि उनके पास पहले से मान था? अद्यतन समाधान स्वैप () विधि का उपयोग करता है जो jQuery स्रोत कोड में पाया गया था।

संदर्भित ब्लॉग पोस्ट से कोड:

//Optional parameter includeMargin is used when calculating outer dimensions  
(function ($) {
$.fn.getHiddenDimensions = function (includeMargin) {
    var $item = this,
    props = { position: 'absolute', visibility: 'hidden', display: 'block' },
    dim = { width: 0, height: 0, innerWidth: 0, innerHeight: 0, outerWidth: 0, outerHeight: 0 },
    $hiddenParents = $item.parents().andSelf().not(':visible'),
    includeMargin = (includeMargin == null) ? false : includeMargin;

    var oldProps = [];
    $hiddenParents.each(function () {
        var old = {};

        for (var name in props) {
            old[name] = this.style[name];
            this.style[name] = props[name];
        }

        oldProps.push(old);
    });

    dim.width = $item.width();
    dim.outerWidth = $item.outerWidth(includeMargin);
    dim.innerWidth = $item.innerWidth();
    dim.height = $item.height();
    dim.innerHeight = $item.innerHeight();
    dim.outerHeight = $item.outerHeight(includeMargin);

    $hiddenParents.each(function (i) {
        var old = oldProps[i];
        for (var name in props) {
            this.style[name] = old[name];
        }
    });

    return dim;
}
}(jQuery));

1
क्या यह ब्राउज़र को पृष्ठ को दो बार पुनः तैयार नहीं करेगा? यदि हां, तो यह एक उप-अपनाने वाला समाधान है।
marcusklaas

@ बहुत अच्छे बैंक! मैंने वास्तव में एक समान विस्तार लिखा था। क्या मैं देख रहा हूँ फ़ायरफ़ॉक्स में बहुत अजीब व्यवहार है , चौड़ाई () रिटर्न 0, आपके और मेरे प्लगइन दोनों के लिए। और इसके शीर्ष पर यह कभी भी पैडिंग के कारक नहीं होते हैं। jsfiddle.net/67cgB । मैं सबसे कठिन समय लगा रहा हूं कि इसे ठीक करने के लिए और क्या कर सकता हूं।
मार्क पिज़्ज़ाक - त्रिलोन

मैं छिपा समझौते आयाम प्राप्त करने के लिए jquery अकॉर्डियन के अंदर इस हैक का उपयोग कैसे कर सकता हूं? आपकी सहायता की आवश्यकता है।
दीपक इंगोले

1
@FercoCQ मैंने संदर्भित ब्लॉग पोस्ट से कोड जोड़ा।
टिम बैंक्स

1

41
function realWidth(obj){
    var clone = obj.clone();
    clone.css("visibility","hidden");
    $('body').append(clone);
    var width = clone.outerWidth();
    clone.remove();
    return width;
}
realWidth($("#parent").find("table:first"));

गंदा अच्छा चाल !!! सुनिश्चित करें कि क्लोन में सही सीएसएस गुण हैं (उदा। यदि मूल तत्व का फ़ॉन्ट आकार 15 है तो आपको क्लोन। पीसी ("दृश्यता", "छिपा हुआ") का उपयोग करना चाहिए। सीएसएस ("फ़ॉन्ट-आकार", "15px" );)
एलेक्स

18
बस इंगित करने के लिए, यह काम नहीं करेगा यदि आपके तत्व को किसी भी माता-पिता से इसकी चौड़ाई विरासत में मिली है। यह सिर्फ शरीर की चौड़ाई का वारिस होगा जो गलत है।
डीन

3
मैंने संशोधित clone.css("visibility","hidden");किया clone.css({"visibility":"hidden", "display":"table"});जो @Dean द्वारा इंगित किए गए मुद्दे को हल करता है
isapir

बहुत धन्यवाद! इसने मेरे मामले के लिए बहुत कम बदलावों के साथ काम किया: मैंने इसे क्लोन करने के लिए एक वस्तु का समर्थन करने के लिए बदल दिया है और इसके अंदर एक चयनकर्ता को इसकी वास्तविक चौड़ाई प्राप्त करने के लिए। हर समय हम उसी मूल वस्तु को मापना चाहते हैं जो छिपी हुई है।
फाल्सरेला

मैं उसी दृष्टिकोण का उपयोग करता था और मुझे उस दिन डाउनवोट का गुच्छा मिला। अजीब है कि आपके पास बहुत सारे उत्थान हैं: डी मैं आपको बताता हूं कि यह बुरा समाधान क्यों है और कुछ साल पहले मेरे उत्तर के तहत क्या बताया गया था। एक बार जब आप तत्व की प्रतिलिपि बनाते हैं और इसे सीधे शरीर में डालते हैं, तो निश्चित रूप से आप इस विशिष्ट तत्व से संबंधित सभी सीएसएस को हटा रहे हैं। उदाहरण के लिए। इससे: #some wrapper .hidden_element{/*Some CSS*/}आप इसे बना रहे हैं body .hidden_element:। #some_wrapper .hidden_elementकिसी भी अधिक नहीं किया जाता है! परिणामस्वरूप, आपका परिकलित आकार मूल आकार से भिन्न हो सकता है। TLTR: आप सिर्फ शैलियों को खो रहे हैं
इसके बजाय

8

रॉबर्ट्स के जवाब के आधार पर, यहां मेरा कार्य है। यह मेरे लिए काम करता है यदि तत्व या उसके माता-पिता को jQuery के माध्यम से फीका कर दिया गया है, या तो आंतरिक या बाहरी आयाम प्राप्त कर सकते हैं और ऑफसेट मान भी लौटा सकते हैं।

/ edit1: फ़ंक्शन को फिर से लिखना। यह अब छोटा है और इसे ऑब्जेक्ट पर सीधे कहा जा सकता है

/ edit2: फ़ंक्शन अब शरीर के बजाय मूल तत्व के बाद क्लोन को सम्मिलित करेगा, जिससे क्लोन के लिए विरासत में दिए गए आयामों को बनाए रखना संभव होगा।

$.fn.getRealDimensions = function (outer) {
    var $this = $(this);
    if ($this.length == 0) {
        return false;
    }
    var $clone = $this.clone()
        .show()
        .css('visibility','hidden')
        .insertAfter($this);        
    var result = {
        width:      (outer) ? $clone.outerWidth() : $clone.innerWidth(), 
        height:     (outer) ? $clone.outerHeight() : $clone.innerHeight(), 
        offsetTop:  $clone.offset().top, 
        offsetLeft: $clone.offset().left
    };
    $clone.remove();
    return result;
}

var dimensions = $('.hidden').getRealDimensions();

उन लोगों के लिए YUI संस्करण जिन्हें इसकी आवश्यकता है: gist.github.com/samueljseay/13c2e69508563b2f0458
कोड

क्या ऑफसेटटॉप को दिए गए आइटम के लिए सही है कि यह क्लोन है और 'वास्तविक' आइटम नहीं है? क्या आपको $ this.offset () का उपयोग करना चाहिए। इसके अलावा, जिज्ञासु जो आप शीर्ष / बाएं का उपयोग कर रहे हैं? मैं केवल 'चौड़ाई' का उपयोग कर रहा हूं, लेकिन सोच रहा हूं कि क्या मुझे किसी कारण से उन लोगों से चिंतित होना चाहिए।
टेरी

3

ऊपर दिए गए realWidth फ़ंक्शन को पोस्ट करने के लिए धन्यवाद, इसने वास्तव में मेरी मदद की। ऊपर "realWidth" फ़ंक्शन के आधार पर, मैंने लिखा, एक सीएसएस रीसेट, (नीचे वर्णित कारण)।

function getUnvisibleDimensions(obj) {
    if ($(obj).length == 0) {
        return false;
    }

    var clone = obj.clone();
    clone.css({
        visibility:'hidden',
        width : '',
        height: '',
        maxWidth : '',
        maxHeight: ''
    });
    $('body').append(clone);
    var width = clone.outerWidth(),
        height = clone.outerHeight();
    clone.remove();
    return {w:width, h:height};
}

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


3

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

फ्लेक्सिबॉक्स उदाहरण यहां छवि विवरण दर्ज करें

मुझे लगता है कि एकमात्र स्थायी और सरल समाधान वास्तविक समय प्रतिपादन है । उस समय, ब्राउज़र को आपको सही तत्व आकार देना चाहिए ।

अफसोस की बात है कि जब तत्व दिखाया या छिपाया गया है, तो उसे सूचित करने के लिए जावास्क्रिप्ट कोई प्रत्यक्ष घटना नहीं देता है। हालाँकि, मैं DOM एट्रीब्यूट मॉडिफाइड API के आधार पर कुछ फ़ंक्शन बनाता हूं जो तत्व की दृश्यता बदलने पर कॉलबैक फ़ंक्शन को निष्पादित करेगा।

$('[selector]').onVisibleChanged(function(e, isVisible)
{
    var realWidth = $('[selector]').width();
    var realHeight = $('[selector]').height();

    // render or adjust something
});

अधिक जानकारी के लिए, कृपया मेरे प्रोजेक्ट GitHub पर जाएँ।

https://github.com/Soul-Master/visible.event.js

डेमो: http://jsbin.com/ETiGIre/7


4
सीएसएस बहुत जटिल है जितना कि सभी को लगता है कि यह बहुत सच है…
dgellow

3

यदि आपको किसी ऐसी चीज़ की चौड़ाई की आवश्यकता है जो छिपी हुई है और आप इसे किसी भी कारण से छिपा नहीं सकते हैं, तो आप इसे क्लोन कर सकते हैं, CSS को बदल सकते हैं ताकि यह पृष्ठ से प्रदर्शित हो, इसे अदृश्य बना दे और फिर इसे मापें। उपयोगकर्ता कोई भी समझदार नहीं होगा यदि यह छिपा हुआ है और बाद में हटा दिया गया है।

यहां कुछ अन्य उत्तर केवल दृश्यता को छिपाते हैं जो काम करता है, लेकिन यह आपके पृष्ठ पर एक सेकंड के अंश के लिए एक खाली स्थान लेगा।

उदाहरण:

$itemClone = $('.hidden-item').clone().css({
        'visibility': 'hidden',
        'position': 'absolute',
        'z-index': '-99999',
        'left': '99999999px',
        'top': '0px'
    }).appendTo('body');
var width = $itemClone.width();
$itemClone.remove();

2
यह तत्व आयाम लेआउट पदानुक्रम के आधार पर मूल आयाम या अधिक जटिल CSS चयनकर्ता से प्रभावित होने पर काम नहीं करेगा।
सेबस्टियन नोवाक

2

चौड़ाई लेने से पहले पैरेंट डिस्प्ले शो करें, फिर चौड़ाई लें और अंत में पैरेंट डिस्प्ले को छिपाएं। ठीक इसी तरह

$('#parent').show();
var tableWidth = $('#parent').children('table').outerWidth();
 $('#parent').hide();
if (tableWidth > $('#parent').width())
{
    $('#parent').width() = tableWidth;
}

2

एक समाधान, हालांकि यह सभी स्थितियों में काम नहीं करेगा, यह है कि ओपेसिटी को 0. पर सेट करके एलिमेंट को छिपाया जा सकता है। पूरी तरह से पारदर्शी तत्व की चौड़ाई होगी।

ड्रा बैक यह है कि तत्व अभी भी जगह लेगा, लेकिन यह सभी मामलों में एक मुद्दा नहीं होगा।

उदाहरण के लिए:

$(img).css("opacity", 0)  //element cannot be seen
width = $(img).width()    //but has width

1

यहां अधिकांश समाधानों में सबसे बड़ी समस्या यह है कि एक तत्व की चौड़ाई अक्सर सीएसएस द्वारा बदल दी जाती है, जहां यह HTML में स्कैन किया जाता है।

अगर मुझे किसी तत्व के ऑफसेटविडिट को शरीर के लिए जोड़कर निर्धारित करना था, जब इसकी शैली है जो केवल इसके वर्तमान दायरे में लागू होती है तो मुझे गलत चौड़ाई मिलेगी।

उदाहरण के लिए:

// सीएसएस

.मोडुले-कंटेनर .my-elem {बॉर्डर: 60px सॉलिड ब्लैक; }

अब जब मैं शरीर के संदर्भ में मेरे-एलएम की चौड़ाई निर्धारित करने का प्रयास करता हूं तो यह 120px तक बाहर हो जाएगा। आप इसके बजाय मॉड्यूल कंटेनर को क्लोन कर सकते हैं, लेकिन आपके जेएस को इन विवरणों को जानना नहीं चाहिए।

मैंने इसका परीक्षण नहीं किया है, लेकिन अनिवार्य रूप से Soul_Master का समाधान एकमात्र ऐसा प्रतीत होता है जो ठीक से काम कर सकता है। लेकिन दुर्भाग्य से कार्यान्वयन को देखने के लिए इसका उपयोग करना महंगा होगा और प्रदर्शन के लिए खराब होगा (जैसा कि यहां प्रस्तुत अधिकांश समाधान भी हैं।)

यदि संभव हो तो दृश्यता का उपयोग करें: इसके बजाय छिपा हुआ। यह अभी भी तत्व को प्रस्तुत करेगा, जिससे आप सभी उपद्रव के बिना चौड़ाई की गणना कर सकते हैं।


0

टिम बैंकों द्वारा पोस्ट किए गए जवाब के अलावा , जो मेरे मुद्दे को हल करने के बाद मुझे एक साधारण चीज को संपादित करना था।

किसी और के पास एक ही मुद्दा हो सकता है; मैं ड्रॉपडाउन में बूटस्ट्रैप ड्रॉपडाउन के साथ काम कर रहा हूं। लेकिन पाठ इस बिंदु पर वर्तमान सामग्री के रूप में व्यापक हो सकता है (और सीएसएस के माध्यम से इसे हल करने के कई अच्छे तरीके नहीं हैं)।

मैंनें इस्तेमाल किया:

$table.css({ position: "absolute", visibility: "hidden", display: "table" });

इसके बजाय, जो कंटेनर को एक मेज पर सेट करता है जो हमेशा चौड़ाई में तराजू होता है यदि सामग्री व्यापक होती है।


0
jQuery(".megamenu li.level0 .dropdown-container .sub-column ul .level1").on("mouseover", function () {
    var sum = 0;
    jQuery(this).find('ul li.level2').each(function(){
    sum -= jQuery(this).height();
    jQuery(this).parent('ul').css('margin-top', sum / 1.8);
    console.log(sum);
    });
});

होवर पर हम सूची आइटम ऊंचाई की गणना कर सकते हैं।


0

जैसा कि पहले कहा गया है, क्लोन और कहीं और विधि संलग्न है वही परिणाम की गारंटी नहीं देता है क्योंकि स्टाइल अलग हो सकता है।

नीचे मेरा दृष्टिकोण है। यह माता-पिता को यात्रा के लिए जिम्मेदार माता-पिता की तलाश करता है, फिर आवश्यक चौड़ाई, ऊंचाई आदि की गणना करने के लिए अस्थायी रूप से इसे अनहाइड कर देता है।

    var width = parseInt($image.width(), 10);
    var height = parseInt($image.height(), 10);

    if (width === 0) {

        if ($image.css("display") === "none") {

            $image.css("display", "block");
            width = parseInt($image.width(), 10);
            height = parseInt($image.height(), 10);
            $image.css("display", "none");
        }
        else {

            $image.parents().each(function () {

                var $parent = $(this);
                if ($parent.css("display") === "none") {

                    $parent.css("display", "block");
                    width = parseInt($image.width(), 10);
                    height = parseInt($image.height(), 10);
                    $parent.css("display", "none");
                }
            });
        }
    }

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.