jQuery hat das resize()
Ereignis -, funktioniert aber nur mit window.
jQuery(window).resize(function() { /* What ever */ });
Das funktioniert gut! Aber wenn ich das Ereignis einem div-Element hinzufügen möchte, funktioniert es nicht.
Z.B
jQuery('div').resize(function() { /* What ever */ });
Ich möchte einen Rückruf starten, wenn sich die Größe eines div-Elements geändert hat. Ich möchte kein Größenänderungsereignis starten - nur ein Ereignis, um zu überprüfen, ob sich die Größe eines div - Elements geändert hat.
Gibt es eine Lösung dafür?
javascript
jquery
TJR
quelle
quelle
Antworten:
DIV
Löst keinresize
Ereignis aus, sodass Sie nicht genau das tun können, was Sie codiert haben. Sie können sich jedoch mit der Überwachung der DOM-Eigenschaften befassen .Wenn Sie tatsächlich mit so etwas wie Größenänderungen arbeiten und dies die einzige Möglichkeit für ein Div ist, seine Größe zu ändern, wird Ihr Größenänderungs-Plugin wahrscheinlich einen eigenen Rückruf implementieren.
quelle
Ich war nur an einem Trigger interessiert, wenn eine Breite eines Elements geändert wurde (mir ist die Höhe egal), also habe ich ein jquery-Ereignis erstellt, das genau das tut, indem ich ein unsichtbares iframe-Element verwende.
$.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); }; } }
Es erfordert das folgende CSS:
iframe.width-changed { width: 100%; display: block; border: 0; height: 0; margin: 0; }
Sie können es hier in Aktion sehen widthChanged fiddle
quelle
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);
// 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));
quelle
Ich habe das jquery-Plugin jquery.resize erstellt. Verwenden Sie resizeObserver, wenn dies unterstützt wird, oder eine Lösung, die auf dem Bildlaufereignis marcj / css-element-queries basiert , kein setTimeout / setInterval.
Sie verwenden nur
jQuery('div').on('resize', function() { /* What ever */ });
oder als Resizer Plugin
jQuery('div').resizer(function() { /* What ever */ });
Ich habe dies für jQuery Terminal erstellt und in ein getrenntes Repo- und npm-Paket extrahiert, aber in der Zwischenzeit bin ich zu verstecktem Iframe gewechselt, weil ich Probleme mit der Größenänderung hatte, wenn sich das Element im Iframe befand. Ich kann das Plugin entsprechend aktualisieren. Sie können sich das iframe-basierte Resizer-Plugin im jQuery Terminal-Quellcode ansehen .
BEARBEITEN : Neue Version verwendet Iframe und ändert die Größe des Fensterobjekts, da die vorherigen Lösungen nicht funktionierten, wenn sich die Seite im Iframe befand.
EDIT2 : Da der Fallback Iframe verwendet, können Sie ihn nicht mit Formularsteuerelementen oder Bildern verwenden. Sie müssen ihn dem Wrapper-Element hinzufügen.
EDIT3 :: Es gibt eine bessere Lösung mit resizeObserver Polyfill , die Mutationsbeobachter verwendet (wenn resizeObserver nicht unterstützt wird) und sogar im IE funktioniert. Es gibt auch TypeScript-Typisierungen.
quelle
was ist damit:
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);
Übrigens, ich schlage vor, dass Sie dem Div eine ID hinzufügen und $ ("div") in $ ("# yourid") ändern. Es wird schneller und es wird nicht kaputt gehen, wenn Sie später andere Divs hinzufügen
quelle
resize
ausgelöst wird. Es ist durchaus denkbar, dass sich die Größe des Div ändert, ohne dass unmittelbar eine Größenänderung des Fensters folgt. In diesem Fall würde das/* what ever */
Teil nicht ausgewertet.$(window).resize
dem Vorgang der physischen Größenänderung des Browserfensters, indem Sie beispielsweise die untere rechte Ecke ziehen. Es gibt keine DOM-Ereignisse, die dieses Ereignis auslösenoverflow:hidden
oder nicht. Diese Antwort geht nicht auf Ihr Problem ein. Es wäre sinnvoller, diesen Code in einem Timer auszuführen, als an einen zufälligen Ereignis-Listener angehängt zu werden, der wahrscheinlich nie ausgelöst wird. Es wäre noch besser, wenn Sie die DOM-Eigenschaftsüberwachung verwenden und auf einen Timer zurückgreifen könnten (oder ein Ereignis manuell an den Stellen auslösen könnten, an denen sich die Div-Größe ändern kann).Es gibt ein wirklich schönes, benutzerfreundliches und leichtes Plugin (das native Browserereignisse zur Erkennung verwendet) für grundlegendes JavaScript und für jQuery, das dieses Jahr veröffentlicht wurde. Es funktioniert perfekt:
https://github.com/sdecima/javascript-detect-element-resize
quelle
Nur Fenster wird unterstützt, ja, aber Sie können ein Plugin dafür verwenden: http://benalman.com/projects/jquery-resize-plugin/
quelle
Für eine Google Maps-Integration suchte ich nach einer Möglichkeit, um festzustellen, wann sich die Größe eines Div geändert hat. Da Google Maps immer die richtigen Abmessungen benötigt, z. B. Breite und Höhe, um richtig zu rendern.
Die Lösung, die ich gefunden habe, ist eine Delegation eines Ereignisses, in meinem Fall ein Tabulatorklick. Dies könnte natürlich eine Fenstergröße sein, die Idee bleibt dieselbe:
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
in diesem fall ist meine karte div. Da mein Elternteil beim Laden unsichtbar ist, sind die berechnete Breite und Höhe 0 oder stimmen nicht überein. Mit.bind(this)
kann ich die Skriptausführung (this.activate
) an ein Ereignis (click
) delegieren .Jetzt bin ich zuversichtlich, dass dies auch für Größenänderungsereignisse gilt.
$(window).one('resize', function() { this.div.css({ /*whatever*/ }); }.bind(this));
Hoffe es hilft jedem!
quelle
Probieren Sie einfach diese Funktion aus (sie funktioniert möglicherweise nicht nur für Divs):
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); }
Sie können es so verwenden
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"!']);
UPDATE: Sie können auch einen progressiveren Watcher verwenden (er kann für alle Objekte verwendet werden, nicht nur für DOM-Elemente):
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); }
Probier es einfach:
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')})
Es wird jedes Mal "geändert" protokolliert, wenn Sie b, a.foo oder a.ext direkt ändern
quelle
setInterval
kann ziemlich teuer werden, da es immer wieder versucht, die Größe zu ändernconsole.log
kurz vor dem$.each
, werden Sie es sehen alle drucken100ms
, wie Sie in der festgelegt habeninterval
setInterval
funktioniert. Es ist wie eine "lebendige" E-Mail - pingt ständig den Server an. Ich weiß es. Und was? Performance? Lesen Sie meinen Kommentar oben. Besorgt über irgendetwas anderes? Schreib mir, mein Freund.Sie können Ihren Text, Inhalt oder Attribut abhängig von der Bildschirmgröße ändern: HTML:
<p class="change">Frequently Asked Questions (FAQ)</p> <p class="change">Frequently Asked Questions </p>
Javascript:
<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>
quelle
Wenn Sie nur die Größe des Div selbst ändern möchten, müssen Sie dies im CSS-Stil angeben. Sie müssen einen Überlauf hinzufügen und die Größe der Eigenschaft ändern .
Unten ist mein Code-Snippet
#div1 { width: 90%; height: 350px; padding: 10px; border: 1px solid #aaaaaa; overflow: auto; resize: both; } <div id="div1"> </div>
quelle