यह पता लगाने पर कि jQuery का उपयोग करके एक div की ऊँचाई कैसे बदल जाती है


141

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

तो, मैं कैसे पता लगा सकता हूं जब उस div की ऊंचाई बदलती है? मुझे लगता है कि कुछ jQuery की घटना है जिसका मुझे उपयोग करने की आवश्यकता है, लेकिन मुझे यकीन नहीं है कि कौन सा हुक करना है।


4
मुझे आश्चर्य है कि jQuery का उपयोग करते समय कोई प्लगइन का उपयोग क्यों नहीं करना चाहेगा।
आंद्रे कालिल

1
@ user007 आपके तत्वों का आकार क्या बदलता है?
ए। वोल्फ

@ मेरी दिव्य ऊँचाई तब बदल जाती है जब उसमें कुछ आइटम जोड़ा जाता है, परिशिष्ट jquery द्वारा किया जाता है
user007

1
@ user007 जब आप DIV के लिए कुछ करते हैं, तो आप DIV के लिए एक कस्टम आकार घटना को ट्रिगर कर सकते हैं। एक अन्य तरीका (सबसे खराब आईएमओ) सामग्री को लागू करने के लिए एक कस्टम विधि का उपयोग करने के लिए हो सकता है जो कि मूल रूप से देशी जेकरी एपेंड () विधि का विस्तार करता है, इसे कॉलबैक के साथ उपयोग करें जैसे
ए। वोल्फ

टिप के लिए @roasted धन्यवाद।
user007

जवाबों:


64

सीएसएस-एलिमेंट-क्वेरीज़ लाइब्रेरी से रिसाइज़ सेंसर का उपयोग करें:

https://github.com/marcj/css-element-queries

new ResizeSensor(jQuery('#myElement'), function() {
    console.log('myelement has been resized');
});

यह एक घटना आधारित दृष्टिकोण का उपयोग करता है और आपके सीपीयू समय को बर्बाद नहीं करता है। सभी ब्राउज़रों में काम करता है। IE7 +।


5
अच्छा समाधान, यह वांछित लक्ष्य पर एक ओवरले के रूप में एक अदृश्य नए तत्व का उपयोग करता है और परिवर्तनों को ट्रिगर करने के लिए ओवरले पर "स्क्रॉल" घटना का उपयोग करता है।
ईके थिस

2
यह एकमात्र समाधान है जो सभी मामलों में काम करता है, जब सामग्री और विशेषताओं में बदलाव नहीं होता है, लेकिन आयाम बदलते हैं (उदाहरण: सीएसएस का उपयोग करके प्रतिशत आयाम)
FF_Dev

2
अब तक का सबसे अच्छा समाधान।
dlsso

1
यह यहाँ पर शीर्ष मतदान का जवाब नहीं होना एक त्रासदी है। यह वास्तव में 100% काम करता है।
जिम्बो जॉनी

यह उन तत्वों के लिए काम नहीं करता है जो छिपे हुए शुरू करते हैं।
बृहस्पतिवार

48

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

नोट: यह कोड मतदान का उपयोग नहीं करता है

इस सरल डेमो को देखें http://jsfiddle.net/aD49d/

$(function () {
    var prevHeight = $('#test').height();
    $('#test').attrchange({
        callback: function (e) {
            var curHeight = $(this).height();            
            if (prevHeight !== curHeight) {
               $('#logger').text('height changed from ' + prevHeight + ' to ' + curHeight);

                prevHeight = curHeight;
            }            
        }
    }).resizable();
});

प्लगइन पेज: http://meetselva.github.io/attrchange/

न्यूनतम संस्करण: (1.68kb)

(function(e){function t(){var e=document.createElement("p");var t=false;if(e.addEventListener)e.addEventListener("DOMAttrModified",function(){t=true},false);else if(e.attachEvent)e.attachEvent("onDOMAttrModified",function(){t=true});else return false;e.setAttribute("id","target");return t}function n(t,n){if(t){var r=this.data("attr-old-value");if(n.attributeName.indexOf("style")>=0){if(!r["style"])r["style"]={};var i=n.attributeName.split(".");n.attributeName=i[0];n.oldValue=r["style"][i[1]];n.newValue=i[1]+":"+this.prop("style")[e.camelCase(i[1])];r["style"][i[1]]=n.newValue}else{n.oldValue=r[n.attributeName];n.newValue=this.attr(n.attributeName);r[n.attributeName]=n.newValue}this.data("attr-old-value",r)}}var r=window.MutationObserver||window.WebKitMutationObserver;e.fn.attrchange=function(i){var s={trackValues:false,callback:e.noop};if(typeof i==="function"){s.callback=i}else{e.extend(s,i)}if(s.trackValues){e(this).each(function(t,n){var r={};for(var i,t=0,s=n.attributes,o=s.length;t<o;t++){i=s.item(t);r[i.nodeName]=i.value}e(this).data("attr-old-value",r)})}if(r){var o={subtree:false,attributes:true,attributeOldValue:s.trackValues};var u=new r(function(t){t.forEach(function(t){var n=t.target;if(s.trackValues){t.newValue=e(n).attr(t.attributeName)}s.callback.call(n,t)})});return this.each(function(){u.observe(this,o)})}else if(t()){return this.on("DOMAttrModified",function(e){if(e.originalEvent)e=e.originalEvent;e.attributeName=e.attrName;e.oldValue=e.prevValue;s.callback.call(this,e)})}else if("onpropertychange"in document.body){return this.on("propertychange",function(t){t.attributeName=window.event.propertyName;n.call(e(this),s.trackValues,t);s.callback.call(this,t)})}return this}})(jQuery)

25
यह समस्या हल करता है यदि आप मैन्युअल रूप से div का आकार बदलते हैं, तो इससे मूल प्रश्न सं हल नहीं होता है? यदि आप सामग्री को गतिशील रूप से जोड़ते हैं तो यह ऊँचाई में परिवर्तन का पता नहीं लगाता है: jsfiddle.net/aD49d/25
smets.kevin

मुझे यह जानने में भी दिलचस्पी होगी कि क्या गतिशील सामग्री के लिए यह काम करने का कोई तरीका है।
एरिकपी

4
@JoeCoder यह Attrchange कोड उपयोगकर्ता द्वारा कार्रवाई किए जाने पर ब्राउज़र द्वारा ट्रिगर की गई DOM घटनाओं पर निर्भर करता है। हालांकि, उस उदाहरण में गतिशील सामग्री प्रोग्रामेटिक रूप से शामिल होती है जो दुर्भाग्य से किसी भी घटना को ट्रिगर नहीं करती है। "मतदान" यहां एक और आसान विकल्प लगता है .. गतिशील सामग्री शामिल होने के बाद अन्य विकल्प मैन्युअल रूप से ट्रिगर करने में सक्षम होंगे।
सेल्वकुमार अरुमुगम

28

आप DOMSubtreeModified इवेंट का उपयोग कर सकते हैं

$(something).bind('DOMSubtreeModified' ...

लेकिन यह तब भी आग लगाएगा, जब आयाम नहीं बदलते हैं, और जब भी आग लगती है, तो स्थिति को पुन: सौंपने से प्रदर्शन हिट हो सकता है। इस पद्धति का उपयोग करते हुए मेरे अनुभव में, यह जांचना कि क्या आयाम बदल गए हैं, कम खर्चीला है और इसलिए आप दोनों के संयोजन पर विचार कर सकते हैं।

या यदि आप सीधे डिव को बदल रहे हैं (बजाय अप्रत्याशित तरीके से उपयोगकर्ता इनपुट द्वारा बदल दिया जा रहा है, जैसे कि अगर यह संतोषप्रद है), तो आप जब भी ऐसा करते हैं, आप एक कस्टम ईवेंट को आग लगा सकते हैं।

नकारात्मक पक्ष: IE और ओपेरा इस घटना को लागू नहीं करते हैं।


12
IE और ओपेरा इस घटना को लागू नहीं करते हैं: quirksmode.org/dom/events/index.html
DEfusion

14
DomSubtreeModified मिला अपठित
Adonis K. Kakoulidis

2
ऐसा करने का आधुनिक तरीका एक MutationObserver का उपयोग करना होगा: developer.mozilla.org/en-US/docs/Web/API/MutationObserver
Christian Bankester

21

इस तरह मैंने हाल ही में इस समस्या को संभाला है:

$('#your-resizing-div').bind('getheight', function() {
    $('#your-resizing-div').height();
});

function your_function_to_load_content() {
    /*whatever your thing does*/
    $('#your-resizing-div').trigger('getheight');
}

मुझे पता है कि मुझे पार्टी में कुछ साल हो गए हैं, बस मुझे लगता है कि मेरा जवाब भविष्य में कुछ लोगों की मदद कर सकता है, बिना किसी प्लग इन को डाउनलोड किए।


1
मुझे लगता है कि कुछ मायनों में यह ऐसा करने का सबसे अच्छा तरीका नहीं है, लेकिन मुझे वास्तव में यह बहुत पसंद है, क्योंकि इसका मतलब है कि आप इसे एनीमेशन के अंत में कॉलबैक के रूप में ट्रिगर कर सकते हैं। रिसाइज़ प्लगइन एक एनीमेशन के दौरान फायरिंग करता रहेगा, जो सहायक हो सकता है, लेकिन समस्याएँ भी पैदा कर सकता है। यह विधि कम से कम आपको नियंत्रण देती है कि ऊंचाई की जांच कब की जाए।
एंडीज

वास्तव में आपका कोड क्या करता है? क्यों हम केवल उस कोड का उपयोग नहीं कर सकते हैं जिसे आप बाइंड इवेंट के अंदर लिखते हैं, जो बंधन और ट्रिगर के कार्य में होता है?
user1447420

लेकिन यह स्वचालित नहीं है, है ना?
अल्बर्ट कैटला

17

आप MutationObserverवर्ग का उपयोग कर सकते हैं ।

MutationObserverडेवलपर्स को DOM में परिवर्तनों पर प्रतिक्रिया करने का एक तरीका प्रदान करता है। इसे DOM3 ईवेंट स्पेसिफिकेशन में परिभाषित म्यूटेशन इवेंट्स के प्रतिस्थापन के रूप में डिज़ाइन किया गया है।

उदाहरण ( स्रोत )

// select the target node
var target = document.querySelector('#some-id');

// create an observer instance
var observer = new MutationObserver(function(mutations) {
  mutations.forEach(function(mutation) {
    console.log(mutation.type);
  });    
});

// configuration of the observer:
var config = { attributes: true, childList: true, characterData: true };

// pass in the target node, as well as the observer options
observer.observe(target, config);

// later, you can stop observing
observer.disconnect();

यह सही जवाब है। MutationSummary पर एक नज़र डालें, एक लाइब्रेरी जो MutationObservers पर
बनती है

9

एक jQuery प्लगइन है जो इससे बहुत अच्छी तरह से निपट सकता है

http://www.jqui.net/jquery-projects/jquery-mutate-official/

यहाँ विभिन्न परिदृश्यों के साथ इसका एक डेमो है जब ऊँचाई बदलती है, यदि आप लाल बॉर्डर वाले डिव का आकार बदलते हैं।

http://www.jqui.net/demo/mutate/


यह सुंदर है, लेकिन क्या यह परिवर्तनों के लिए डिफ़ॉल्ट रूप से UI को हर मिलीसेकंड को प्रदूषित नहीं करता है? क्या यह कुशल है?
माइकल स्कॉट कथबर्ट

1
@MichaelScottCuthbert यह एक लंबे समय से पहले लिखा गया था, लेकिन मैंने इस्तेमाल किया setTimeout, इसलिए यह 1ms + होगा [संक्षेप में चेक करने में समय लगता है], लेकिन विचार यह था कि आप लगातार इसे सुनें, एक बार जब आपने इसे ट्रिगर किया, तो यह पसंद है एक क़तार। मुझे यकीन है कि मैं इसे बेहतर कर सकता था लेकिन ज्यादा समय नहीं।
वैल

आह, हाँ, मैं देख रहा हूं कि आप वेगा के समाधान से पहले एक साल पहले (जो मैंने अंततः उपयोग किया था) और सभी DOMSubtreeModified से पहले, आदि श्रोताओं को व्यापक रूप से समर्थन किया गया था। मैंने हालांकि आपके कोड को पढ़ने से एक टन सीखा है, इसलिए मुझे लगता है कि यह लिंक को बनाए रखने के लायक है।
माइकल स्कॉट कटहबर्ट

7

User007 के जवाब में:

यदि आपके तत्व की ऊँचाई वस्तुओं के कारण बदल रही है, तो इसका उपयोग करके .append()आपको ऊंचाई में परिवर्तन का पता लगाने की आवश्यकता नहीं है। बस उसी फ़ंक्शन में अपने दूसरे तत्व का स्थान जोड़ें जहां आप अपने पहले तत्व में नई सामग्री जोड़ रहे हैं।

जैसे की:

काम करने का उदाहरण

$('.class1').click(function () {
    $('.class1').append("<div class='newClass'><h1>This is some content</h1></div>");
    $('.class2').css('top', $('.class1').offset().top + $('.class1').outerHeight());
});

2

आप एक साधारण सेट बना सकते हैं।

function someJsClass()
{
  var _resizeInterval = null;
  var _lastHeight = 0;
  var _lastWidth = 0;
  
  this.Initialize = function(){
    var _resizeInterval = setInterval(_resizeIntervalTick, 200);
  };
  
  this.Stop = function(){
    if(_resizeInterval != null)
      clearInterval(_resizeInterval);
  };
  
  var _resizeIntervalTick = function () {
    if ($(yourDiv).width() != _lastWidth || $(yourDiv).height() != _lastHeight) {
      _lastWidth = $(contentBox).width();
      _lastHeight = $(contentBox).height();
      DoWhatYouWantWhenTheSizeChange();
    }
  };
}

var class = new someJsClass();
class.Initialize();

संपादित करें:

यह एक वर्ग के साथ एक उदाहरण है। लेकिन आप कुछ आसान कर सकते हैं।


0

आप इसका उपयोग कर सकते हैं, लेकिन यह केवल फ़ायरफ़ॉक्स और क्रोम का समर्थन करता है।

$(element).bind('DOMSubtreeModified', function () {
  var $this = this;
  var updateHeight = function () {
    var Height = $($this).height();
    console.log(Height);
  };
  setTimeout(updateHeight, 2000);
});


0

सुंदर बुनियादी लेकिन काम करता है:

function dynamicHeight() {
    var height = jQuery('').height();
    jQuery('.edito-wrapper').css('height', editoHeight);
}
editoHeightSize();

jQuery(window).resize(function () {
    editoHeightSize();
});

यह केवल निकाल दिया जाएगा अगर खिड़की का आकार बदल जाता है, लेकिन ओपी एक विशिष्ट कंटेनर में एक आकार घटना को बांधना चाहता है
फैनी शून्य
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.