दिव्य तत्व का आकार बदलें


80

jQuery के पास resize()ईवेंट है, लेकिन यह सिर्फ विंडो के साथ काम करता है।

jQuery(window).resize(function() { /* What ever */ });

यह ठीक काम करता है! लेकिन जब मैं ईवेंट को एक दिव्य तत्व में जोड़ना चाहता हूं तो यह काम नहीं करता है।

उदाहरण के लिए

jQuery('div').resize(function() { /* What ever */ });

मैं एक कॉलबैक शुरू करना चाहता हूं जब एक div-element का आकार बदल गया है। मैं एक resizable - घटना शुरू नहीं करना चाहता - एक घटना की जाँच करने के लिए अगर एक div - तत्व का आकार बदल गया है।

क्या ऐसा करने का कोई समाधान है?


2
आकार बदलने की घटनाओं को केवल खिड़की (वस्तुओं) और (iframes हो सकता है) पर निकाल दिया जाता है।
BiAiB

3
इस पृष्ठ पर एक नज़र डालें - benalman.com/code/projects/jquery-resize/examples/resize
Elen

यह मदद कर सकता है: resizeObserver। developer.mozilla.org/en-US/docs/Web/API/ResizeObserver । क्रोम 64, फ़ायरफ़ॉक्स 69 द्वारा समर्थित ...
कप्तान

जवाबों:


35

DIVकिसी resizeईवेंट को फायर नहीं करता है , इसलिए आप वही नहीं कर पाएंगे जो आपने कोडित किया है, लेकिन आप DOM प्रॉपर्टीज की निगरानी कर सकते हैं

यदि आप वास्तव में रिज़ेज़ेबल्स जैसी किसी चीज़ के साथ काम कर रहे हैं, और यह एक डिव का आकार बदलने का एकमात्र तरीका है, तो आपका रिसाइज़ प्लगइन संभवतः अपने खुद के कॉलबैक को लागू करेगा।


आप $ (विंडो) .trigger ("आकार") के साथ विंडो आकार घटना को ट्रिगर कर सकते हैं;
लॉरेंट

32

मुझे केवल एक ट्रिगर के लिए दिलचस्पी थी जब एक तत्व की चौड़ाई बदल दी गई थी (मैं ऊंचाई के बारे में परवाह नहीं करता), इसलिए मैंने एक jquery घटना बनाई जो वास्तव में ऐसा करती है, एक अदृश्य iframe तत्व का उपयोग करके।

$.event.special.widthChanged = {
  remove: function() {
      $(this).children('iframe.width-changed').remove();
  },
  add: function () {
      var elm = $(this);
      var iframe = elm.children('iframe.width-changed');
      if (!iframe.length) {
          iframe = $('<iframe/>').addClass('width-changed').prependTo(this);
      }
      var oldWidth = elm.width();
      function elmResized() {
          var width = elm.width();
          if (oldWidth != width) {
              elm.trigger('widthChanged', [width, oldWidth]);
              oldWidth = width;
          }
      }

      var timer = 0;
      var ielm = iframe[0];
      (ielm.contentWindow || ielm).onresize = function() {
          clearTimeout(timer);
          timer = setTimeout(elmResized, 20);
      };
  }
}

यह निम्नलिखित सीएसएस की आवश्यकता है:

iframe.width-changed {
    width: 100%;
    display: block;
    border: 0;
    height: 0;
    margin: 0;
}

आप इसे यहां एक्शन में देख सकते हैं जिसमें चौड़ाई फीकी है


यह सही जवाब है। घटना को एक iframe की विंडो में जोड़ना एक अंतराल से बहुत कम हैकी है।
केविन बील

1
यह पूर्ण है! मैंने स्टाइलशीट को गतिशील रूप से जोड़कर मेरा पूरी तरह से js बना दिया: var ss = document.createElement('style'); ss.type = "text/css"; ss.innerHTML = "iframe.width-changed {width: 100%;display: block;border: 0;height: 0;margin: 0;}"; document.body.appendChild(ss);
sroskelley

यह शुद्ध प्रतिभा है।
थॉमस

मैं इसका उपयोग करने वाला हूं लेकिन मुझे आश्चर्य है कि टाइमर और सेटटाइमआउट की भूमिका क्या है? क्या यह एक "पराजय" की तरह है / थ्रॉटल को रोकने के लिए बहुत से आकार का पता लगाने के लिए जब उपयोगकर्ता तत्व का आकार बदलता है?
मैथ्यू

हाँ, यह कई बार "चौड़ाई" ट्रिगर को रोकने के लिए है
Panos Theof

22
// this is a Jquery plugin function that fires an event when the size of an element is changed
// usage: $().sizeChanged(function(){})

(function ($) {

$.fn.sizeChanged = function (handleFunction) {
    var element = this;
    var lastWidth = element.width();
    var lastHeight = element.height();

    setInterval(function () {
        if (lastWidth === element.width()&&lastHeight === element.height())
            return;
        if (typeof (handleFunction) == 'function') {
            handleFunction({ width: lastWidth, height: lastHeight },
                           { width: element.width(), height: element.height() });
            lastWidth = element.width();
            lastHeight = element.height();
        }
    }, 100);


    return element;
};

}(jQuery));

7

मैंने jquery प्लगइन jquery.resize बनाया है, अगर यह मार्सिज़ / सीएसएस-एलिमेंट्स-क्वेरीज़ स्क्रॉल इवेंट, कोई सेटटाइमआउट / सेटइंटरवल के आधार पर समर्थित या समाधान का उपयोग करता है, तो resizeObserver का उपयोग करें।

आप बस इस्तेमाल करें

 jQuery('div').on('resize', function() { /* What ever */ });

या resizer प्लगइन के रूप में

jQuery('div').resizer(function() { /* What ever */ });

मैंने इसे jQuery टर्मिनल के लिए बनाया है और अलग-अलग रेपो और npm पैकेज में निकाला है, लेकिन एक ही समय में मैंने छिपे हुए iframe पर स्विच किया क्योंकि मुझे iframe के अंदर तत्व होने पर resize की समस्या थी। मैं तदनुसार प्लगइन को अपडेट कर सकता हूं। आप jQuery टर्मिनल स्रोत कोड में iframe आधारित पुनर्विक्रेता प्लगइन देख सकते हैं ।

संपादित करें : नया संस्करण iframe का उपयोग करता है और इसे विंडो ऑब्जेक्ट पर आकार देता है क्योंकि पिछले समाधान तब काम नहीं कर रहा था जब पेज iframe के अंदर था।

EDIT2 : क्योंकि फ़ॉलबैक का उपयोग iframe आप इसे प्रपत्र नियंत्रण या छवियों के साथ उपयोग नहीं कर सकते हैं, आपको इसे रैपर तत्व में जोड़ना होगा।

EDIT3: : वहाँ बेहतर का उपयोग कर हल है resizeObserver polyfill कि उपयोग उत्परिवर्तन पर्यवेक्षक (यदि resizeObserver समर्थित नहीं है) और काम IE में भी। इसमें टाइपस्क्रिप्ट टाइपिंग भी है।


यह एक महान विचार था। अच्छी नौकरी, वास्तव में।
मार्को लूजारा

6

इस बारे में क्या:

divH = divW = 0;
jQuery(document).ready(function(){
    divW = jQuery("div").width();
    divH = jQuery("div").height();
});
function checkResize(){
    var w = jQuery("div").width();
    var h = jQuery("div").height();
    if (w != divW || h != divH) {
        /*what ever*/
        divH = h;
        divW = w;
    }
}
jQuery(window).resize(checkResize);
var timer = setInterval(checkResize, 1000);

BTW मैं आपको div में एक आईडी जोड़ने और $ ("div") को $ ("# yourid") में बदलने का सुझाव देता हूं, यह तेजी से होने वाला है, और बाद में जब आप अन्य div को जोड़ते हैं तो यह नहीं टूटेगा


बेशक - यह सिर्फ एक उदाहरण था - बेशक मैं अपने तत्वों का चयन करने के लिए आईडी और कक्षाओं का उपयोग करता हूं। मुझे आपका विचार पसंद है - मुझे लगता है कि यह काम करेगा! बहुत बहुत धन्यवाद। मैं कुछ मिनटों में कोशिश करूँगा और एक प्रतिक्रिया दूंगा।
TJR

जब भी विंडो के resizeईवेंट को निकाल दिया जाता है , तो यह आकार परिवर्तन के लिए DIV पर नज़र रखता है। यह काफी बोधगम्य है कि खिड़की के आकार के तुरंत बाद div का आकार बदल जाएगा, जिस स्थिति में /* what ever */भाग का मूल्यांकन नहीं किया जाएगा।
डेविड हेडलंड

सही! और यह मेरी परियोजना में समस्या है। Div एलिमेंट एक बाहरी आवरण में होता है, जिसमें css विशेषता ओवरफ्लो होती है: छिपी हुई - इसलिए विंडो फ्लॉप आकार को नहीं बदलती है। लेकिन अन्य तरीकों से उदाहरण ठीक काम करेगा - मैंने अभी इसका परीक्षण किया है।
TJR

@Timo: $(window).resizeनीचे दाएं कोने को खींचते हुए, ब्राउज़र विंडो को भौतिक रूप से आकार देने के कार्य को सुनता है। कोई डोम ईवेंट नहीं हैं जो कभी भी इस ईवेंट को ट्रिगर करते हैं, overflow:hiddenया नहीं। यह उत्तर आपकी समस्या का समाधान नहीं करता है। इस कोड को टाइमर में चलाने के लिए और अधिक समझदारी होगी, एक यादृच्छिक घटना श्रोता से जुड़ी होने की संभावना है जो कभी भी ट्रिगर नहीं होगी। यह तब भी बेहतर होगा जब आप DOM प्रॉपर्टी मॉनिटरिंग का उपयोग कर सकते हैं और एक टाइमर पर वापस आ सकते हैं (या मैन्युअल रूप से उन जगहों पर कुछ ईवेंट बढ़ा सकते हैं जहां div आकार बदल सकते हैं)।
डेविड हेडलंड

setInterval के लिए जोड़ा गया कोड। आपको इसे ठीक करने की आवश्यकता है, क्योंकि आपके लिए 1000ms बहुत अधिक हो सकते हैं, दूसरी तरफ बहुत कम संख्या में आसानी से आपके सीपीयू को मार सकते हैं। यदि आप जानते हैं कि आपको कोई और सुनने की आवश्यकता नहीं है, तो कॉल करें: ClearInterval (टाइमर)!
गेवरियल

5

वहाँ एक बहुत अच्छा, प्रयोग करने में आसान, हल्का है (मूल ब्राउज़र घटनाओं का पता लगाने के लिए उपयोग करता है) दोनों मूल जावास्क्रिप्ट के लिए प्लगइन और jQuery के लिए जो इस साल जारी किया गया था। यह पूरी तरह से प्रदर्शन करता है:

https://github.com/sdecima/javascript-detect-element-resize


1
आपने कहा कि यह लगातार मतदान नहीं करता है, लेकिन यह करता है, यह requestAnimationFrame का उपयोग करता है: github.com/sdecima/javascript-detect-element-resize/blob/master/…
मुहम्मद उमर

1
दिलचस्प: संदर्भित GitHub प्रोजेक्ट इस ब्लॉग पोस्ट से प्रेरित था: backalleycoder.com/2013/03/18/… लेकिन पोस्ट में कोड बाद में काफी बदल दिया गया था, जबकि GitHub प्रोजेक्ट पुराने दृष्टिकोण का उपयोग करने लगता है। इसलिए इसका उपयोग करने से पहले दोनों को देखने लायक है।
CF

2

केवल विंडो ही समर्थित है, लेकिन आप इसके लिए एक प्लगइन का उपयोग कर सकते हैं: http://benalman.com/projects/jquery-resize-bugin/


1
नहीं, यह वही है जो ओपी ने कोशिश की, और बताया कि यह काम नहीं करता है।
डेविड हेडलंड

यदि आप कई बार इस का उपयोग करते हैं तो यह सेटटाइमआउट काफी महंगा हो सकता है।
jcubic

0

एक गूगल मैप्स इंटीग्रेशन के लिए मैं यह पता लगाने का एक तरीका खोज रहा था कि कब डिव का आकार बदल गया है। चूँकि गूगल मैप्स को हमेशा उचित आयामों की आवश्यकता होती है जैसे कि चौड़ाई और ऊँचाई ठीक से प्रस्तुत करने के लिए।

मैं जिस समाधान के साथ आया था वह एक घटना का एक प्रतिनिधिमंडल है, मेरे मामले में एक टैब क्लिक। यह निश्चित रूप से एक खिड़की का आकार बदल सकता है, विचार समान है:

if (parent.is(':visible')) {
    w = parent.outerWidth(false);
    h = w * mapRatio /*9/16*/;
    this.map.css({ width: w, height: h });
} else {
    this.map.closest('.tab').one('click', function() {
        this.activate();
    }.bind(this));
}

this.mapइस मामले में मेरा नक्शा div है। चूंकि मेरे माता-पिता लोड पर अदृश्य हैं, इसलिए गणना की गई चौड़ाई और ऊंचाई 0 है या मेल नहीं खाते हैं। उपयोग करके .bind(this)मैं स्क्रिप्ट निष्पादन ( this.activate) को एक घटना ( click) में सौंप सकता हूं ।

अब मुझे विश्वास है कि आकार बदलने वाली घटनाओं के लिए भी यही बात लागू होती है।

$(window).one('resize', function() {
    this.div.css({ /*whatever*/ });
}.bind(this));

आशा है कि यह किसी को भी मदद करता है!


0

बस इस फंक को आज़माएं (यह न केवल डिव के लिए काम कर सकता है):

function resized(elem, func = function(){}, args = []){
    elem = jQuery(elem);
    func = func.bind(elem);
    var h = -1, w = -1;
    setInterval(function(){
        if (elem.height() != h || elem.width() != w){
            h = elem.height();
            w = elem.width();
            func.apply(null, args);
        }
    }, 100);
}

आप इसे इस तरह से उपयोग कर सकते हैं

resized(/*element*/ '.advs-columns-main > div > div', /*callback*/ function(a){
    console.log(a);
    console.log(this); //for accessing the jQuery element you passed
}, /*callback arguments in array*/ ['I\'m the first arg named "a"!']);

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

function changed(elem, propsToBeChanged, func = function(){}, args = [], interval = 100){
        func = func.bind(elem);
        var currentVal = {call: {}, std: {}};
        $.each(propsToBeChanged, (property, needCall)=>{
            needCall = needCall ? 'call' : 'std';
            currentVal[needCall][property] = new Boolean(); // is a minimal and unique value, its equivalent comparsion with each other will always return false
        });
        setInterval(function(){
            $.each(propsToBeChanged, (property, needCall)=>{
                try{
                    var currVal = needCall ? elem[property]() : elem[property];
                } catch (e){ // elem[property] is not a function anymore
                    var currVal = elem[property];
                    needCall = false;
                    propsToBeChanged[property] = false;
                }
                needCall = needCall ? 'call' : 'std';
                if (currVal !== currentVal[needCall][property]){
                    currentVal[needCall][property] = currVal;
                    func.apply(null, args);
                }
            });
        }, interval);
    }

कर के देखो:

var b = '2',
    a = {foo: 'bar', ext: ()=>{return b}};
changed(a, {
// prop name || do eval like a function?
    foo:        false,
    ext:        true
}, ()=>{console.log('changed')})

जब आप b, a.foo या a.ext को सीधे बदलते हैं, तो यह हर बार 'परिवर्तित' हो जाएगा


setIntervalबहुत महंगा हो सकता है क्योंकि यह आकार बदलने का प्रयास करता रहता है
टन

@टन: मुझे लगता है कि आप पूरी तरह से सही नहीं हैं। यह केवल एक तत्व का आकार बदलने की कोशिश करने के मामले में होता है। : / या आप प्रदर्शन के बारे में चिंतित हैं? नवीनतम ब्राउज़रों पर यह "भारी" साइटों पर भी पूरी तरह से काम करता है
KaMeHb

आप एक सरल जोड़ देंगे तो console.logबस से पहले $.each, आप इसे हर प्रिंट देखेंगे 100ms, जैसा कि आप में सेट किया हैinterval
टन

@टन: आपने मुझे गलत समझा। मुझे अच्छी तरह पता है कि कैसे setIntervalकाम करता है। यह एक "जीवित" ई-मेल की तरह है - लगातार पिंग्स सर्वर। मुझे यह पता है। और क्या? प्रदर्शन? ऊपर मेरी टिप्पणी पढ़ें किसी और चीज के बारे में चिंतित हैं? मुझे, मेरे दोस्त लिखो।
KaMeHb

0

आप अपना पाठ या सामग्री बदल सकते हैं या विशेषता स्क्रीन आकार पर निर्भर कर सकते हैं: HTML:

<p class="change">Frequently Asked Questions (FAQ)</p>
<p class="change">Frequently Asked Questions </p>

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

<script>
const changeText = document.querySelector('.change');
function resize() {
  if((window.innerWidth<500)&&(changeText.textContent="Frequently Asked Questions (FAQ)")){
    changeText.textContent="FAQ";
  } else {
    changeText.textContent="Frequently Asked Questions (FAQ)";
  }
}
window.onresize = resize;
</script>

-2

यदि आप केवल उस div को आकार देना चाहते हैं जो आपको css शैली में निर्दिष्ट करने की आवश्यकता है। आपको अतिप्रवाह जोड़ने और संपत्ति का आकार बदलने की आवश्यकता है

नीचे मेरा कोड स्निपेट है

#div1 {
        width: 90%;
        height: 350px;
        padding: 10px;
        border: 1px solid #aaaaaa;
        overflow: auto;
        resize: both;
    }

<div id="div1">

</div>

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