Reputation: 12529
I'm using the .resize()
function to detect window re-size events, but this detects both height and width changes.
Is there any way to detect just a width change and not a height change?
Upvotes: 50
Views: 84330
Reputation: 87073
var width = $(window).width();
$(window).on('resize', function() {
if ($(this).width() !== width) {
width = $(this).width();
console.log(width);
}
});
Upvotes: 101
Reputation: 69
The link provided by @nachtigall is broken, so I found this other with the same library, which helped me to solve my issue: resize-dimension.js
Example of solution is as follow: Import library:
<script src="./resize-dimension.js"></script>
Create script:
<script type="text/javascript">
ResizeDimension.bind('width');
$(window).on('resize-width', function () {
//alert(window);
ForResize();
});
</script>
The function ForResize()
gets fired when the browser is resized, though in this case, IE handles it better than the other browsers, however, in my case, it worked fine for mobile devices, which where firing the events when scrolling the page, which depending on the mobile browser, it can hide the address bar, which affects the browser's size. Implementing that library helped!
I used the counter/timer provided here and modified it to my needs. The following are the critical scripts that I had to create:
<script type="text/javascript">
function RefreshWidth() {
var _hcontainer = $("#chart_container").width();
var _hcontainerInt = parseInt(_hcontainer, 10);
$("#txChartSize").val(_hcontainerInt);
$("#txChartSize_1").val(_hcontainerInt);
$("#textWidthFire").val(_hcontainerInt);
DetectResizeChange();
}
</script>
<script type="text/javascript">
var myTimer; //also in C#
var c = 0;
//these functions are needed in order to fire RefreshWidth() so it will fire DetectResizeChange() after browser changes size
function clock() {
//RefreshWidth();
myTimer = setInterval(myClock, 1000);
c = 3;
function myClock() {
document.getElementById("loadMsg").innerHTML = "Processing chart, please wait...";
--c; //--->>counts in reverse to resize
if (c == 0) {
RefreshWidth(); //--->>gives enough time for the width value to be refreshed in the textbox
clearInterval(myTimer);
}
}
}
//detects size change on the browser
function DetectResizeChange() {
var _NoDataAvailable = $('#txNoDataAvailable').val();
if (_NoDataAvailable != 'NoData') {
var refLine = $("#refLine").width();
var _hcontainer = $("#chart_container").width();
var _width = _hcontainer;
var _hcontainerInt = parseInt(_hcontainer, 10);
$("#txChartSize").val(_hcontainerInt);
$("#textWidthFire").val(_hcontainerInt);
$('#msgAdjustView').show();
$("#msgAdjustView").text("Loading data and adjusting chart view, please wait...");
$('.modal').show();
var checkOption = document.getElementById('lbViewingData').value;
var button;
var btnWidth;
btnWidth = document.getElementById('btnStopTimer');
if (checkOption == 'Option 1') {
button = document.getElementById('firstTab');
} else if (checkOption == 'Option 2') {
button = document.getElementById('secondTab');
} else if (checkOption == 'Option 3') {
button = document.getElementById('thirdTab');
}
button.click();
}
}
</script>
<script type="text/javascript">
function ForResize() {
var _NoDataAvailable = $('#txNoDataAvailable').val();
if (_NoDataAvailable != 'NoData') {
clock();
document.getElementById('loadMsg').innerHTML = 'Resizing chart in progress...';
}
}
</script>
In case that the library's link gets broken again, here is the code from the same source (resize-dimension.js):
(function (root, factory) {
var moduleName = 'ResizeDimension';
if (typeof define === 'function' && define.amd) {
define(['jquery'], function ($) {
return (root[moduleName] = factory($));
});
} else {
root[moduleName] = factory(root.$);
}
}(this, function ($) {
var $window = $(window);
var ResizeDimension = function ($el, dimension, handler, options) {
if (! (this instanceof ResizeDimension)) {
return new ResizeDimension($el, dimension, handler, options);
}
this.$el = $el;
this.init(dimension, handler, options);
return this;
};
/**
* Stub - overridden on #init()
*/
ResizeDimension.prototype.onResize = function () {};
ResizeDimension.bound = {};
ResizeDimension.bind = function (dimension, options) {
if (ResizeDimension.bound[dimension]) return;
ResizeDimension.bound[dimension] = true;
$window.resizeDimension(dimension, function () {
$window.trigger('resize-' + dimension);
}, options);
};
ResizeDimension.prototype.init = function (dimension, handler, options) {
if (typeof dimension === 'object') {
options = dimension;
dimension = options.dimension;
handler = options.handler;
}
options = $.extend({}, options);
options.dimension = dimension;
options.handler = handler;
this.options = options;
if ($.isFunction(options.changed)) {
this.changed = options.changed;
}
this.dimension = this.normalize(options.dimension);
this.handler = options.handler;
this.previousValue = this.value();
var proxied = $.proxy(this.handle, this);
if (options.throttler) {
this.onResize = options.throttler(proxied);
}
else {
this.onResize = proxied;
}
};
ResizeDimension.prototype.normalize = function (dimension) {
return dimension;
};
ResizeDimension.prototype.changed = function (previous, current) {
return previous !== current;
};
ResizeDimension.prototype.value = function (e) {
return this.$el[this.dimension]();
};
ResizeDimension.prototype.handle = function (e) {
var currentValue = this.value();
if (this.changed(this.previousValue, currentValue)) {
this.previousValue = currentValue;
return this.handler.call(this.$el, e);
}
};
var $resizeDimension = function () {
var args = Array.prototype.slice.call(arguments);
return this.each( function() {
var $el = $(this);
args = [$el].concat(args);
var instance = ResizeDimension.apply(null, args);
$el.on('resize', $.proxy(instance.onResize, instance));
});
};
$.fn.resizeDimension = $resizeDimension;
return ResizeDimension;
}));
Upvotes: 0
Reputation: 15616
you can detect both events and just execute code when it's a width change:
var lastWidth = $(window).width();
$(window).resize(function(){
if($(window).width()!=lastWidth){
//execute code here.
lastWidth = $(window).width();
}
})
And you might want to check event debouncing.
Debouncing enforces that a function not be called again until a certain amount of time has passed without it being called. As in "execute this function only if 100 milliseconds have passed without it being called.
Read more:
Upvotes: 22
Reputation: 2636
Even though there are already a couple of answers with working solutions, this kind of task is performance critical (window resize event is triggered many times while a user is resizing the window) so I strongly suggest you to take care of the performance. Please, have a look at the optimized code below:
/* Do not waste time by creating jQuery object from window multiple times.
* Do it just once and store it in a variable. */
var $window = $(window);
var lastWindowWidth = $window.width();
$window.resize(function () {
/* Do not calculate the new window width twice.
* Do it just once and store it in a variable. */
var windowWidth = $window.width();
/* Use !== operator instead of !=. */
if (lastWindowWidth !== windowWidth) {
// EXECUTE YOUR CODE HERE
lastWindowWidth = windowWidth;
}
});
Plus, you might be interested in checking the Debounce / Throttle patterns - they improve performance enormously in cases like this.
Upvotes: 5
Reputation: 2497
One can also use this tiny jQuery plugin for this: https://github.com/adjohnson916/jquery-resize-dimension
Keeps your own code more readable:
ResizeDimension.bind('width');
$(window).on('resize-width', function () {
console.log('resize-width event');
});
or just:
$(window).resizeDimension('width', function () {
console.log('resize-width event');
});
Upvotes: 2