Я использую функцию .resize()
для обнаружения событий изменения размера окна, но это определяет как изменения высоты, так и ширины.
Есть ли способ обнаружить только изменение ширины, а не изменение высоты?
Я использую функцию .resize()
для обнаружения событий изменения размера окна, но это определяет как изменения высоты, так и ширины.
Есть ли способ обнаружить только изменение ширины, а не изменение высоты?
var width = $(window).width();
$(window).on('resize', function() {
if ($(this).width() != width) {
width = $(this).width();
console.log(width);
}
});
вы можете обнаружить оба события и просто выполнить код при изменении ширины:
var lastWidth = $(window).width();
$(window).resize(function(){
if($(window).width()!=lastWidth){
//execute code here.
lastWidth = $(window).width();
}
})
И вы можете захотеть проверить debouncing событий.
Debouncing обеспечивает, чтобы функция не вызывалась снова, пока не прошло определенное количество времени без ее вызова. Как и в "выполнить эту функцию, только если прошло 100 миллисекунд без ее вызова.
Подробнее:
Несмотря на то, что уже есть несколько ответов с рабочими решениями, такая задача критически важна (событие изменения размера окна запускается много раз, когда пользователь меняет размер окна), поэтому я настоятельно рекомендую вам позаботиться о производительности, Пожалуйста, ознакомьтесь с оптимизированным кодом ниже:
/* 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;
}
});
Кроме того, вам может быть интересно проверить шаблоны Debounce/Throttle - они значительно улучшают производительность в таких случаях.
Можно также использовать этот крошечный плагин jQuery для этого: https://github.com/adjohnson916/jquery-resize-dimension
Сохраняет ваш собственный код более читаемым:
ResizeDimension.bind('width');
$(window).on('resize-width', function () {
console.log('resize-width event');
});
или просто:
$(window).resizeDimension('width', function () {
console.log('resize-width event');
});
Ссылка, предоставленная @nachtigall, не работает, поэтому я нашел другую с той же библиотекой, которая помогла мне решить мою проблему: resize-dimension.js
Пример решения следующий: библиотека импорта:
<script src="./resize-dimension.js"></script>
Создать скрипт:
<script type="text/javascript">
ResizeDimension.bind('width');
$(window).on('resize-width', function () {
//alert(window);
ForResize();
});
</script>
Функция ForResize()
срабатывает при изменении размера браузера, хотя в этом случае IE справляется с этим лучше, чем другие браузеры, однако, в моем случае, он работал нормально для мобильных устройств, которые запускали события при прокрутке страницы, который в зависимости от мобильного браузера может скрывать адресную строку, что влияет на размер браузера. Реализация этой библиотеки помогла!
Я использовал счетчик/таймер, представленный здесь, и изменил его для своих нужд. Ниже приведены критические сценарии, которые мне пришлось создать:
<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>
В случае, если ссылка на библиотеку снова разорвана, вот код из того же источника (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;
}));