Как контролировать выполнение функции посредством уменьшения/увеличения экрана на JS?
У меня есть этнично украденная(кхм, скопированная) функция, которая реализует поведение сайдбара так же, как и сайдбар ВК. Но при уменьшении экрана, когда применяется медиа-запрос, при прокрутке среднего блока, к которому "привязан" сайдбар, ломается верстка сайдбара, а точнее текст выстраивается по левому краю в столбик по-одному слову и блок перестает прокручиваться. Я пробовал добавлять доп.классы к сайдбару и меню и при уменьшении страницы убирать их, но тогда, после обратного увеличения размеров страницы, функция отказывается работать. Вопрос: как реализовать отключения данной функции при размерах экрана <=768px и включение при экране >768px. Я читал много разных ответов и примеров по типу: менять значение x с true на false и отслеживать значение x в функции и активировать, отключать ее в зависимости от значения переменной, но у меня не получилось этого сделать, т.к. я тупой немножко.
О Великие Пользователи StackOverflow, пожалуйста, покажите мне, неучу, на наглядном примере, как это реализовать.
Вот код функции:
(function () {
var a = document.querySelector(".l-menu"),
b = null,
K = null,
Z = 0,
P = 20,
N = 0; // если у P ноль заменить на число, то блок будет прилипать до того, как верхний край окна браузера дойдёт до верхнего края элемента, если у N — нижний край дойдёт до нижнего края элемента. Может быть отрицательным числом
window.addEventListener("scroll", Ascroll, false);
document.body.addEventListener("scroll", Ascroll, false);
function Ascroll() {
var Ra = a.getBoundingClientRect(),
R1bottom = document.querySelector(".m-menu").getBoundingClientRect()
.bottom;
if (Ra.bottom < R1bottom) {
if (b == null) {
var Sa = getComputedStyle(a, ""),
s = "";
for (var i = 0; i < Sa.length; i++) {
if (
Sa[i].indexOf("overflow") == 0 ||
Sa[i].indexOf("padding") == 0 ||
Sa[i].indexOf("border") == 0 ||
Sa[i].indexOf("outline") == 0 ||
Sa[i].indexOf("box-shadow") == 0 ||
Sa[i].indexOf("background") == 0
) {
s += Sa[i] + ": " + Sa.getPropertyValue(Sa[i]) + "; ";
}
}
b = document.createElement("div");
b.className = "stop";
b.style.cssText =
s + " box-sizing: border-box; width: " + a.offsetWidth + "px;";
a.insertBefore(b, a.firstChild);
var l = a.childNodes.length;
for (var i = 1; i < l; i++) {
b.appendChild(a.childNodes[1]);
}
a.style.height = b.getBoundingClientRect().height + "px";
a.style.padding = "0";
a.style.border = "0";
}
var Rb = b.getBoundingClientRect(),
Rh = Ra.top + Rb.height,
W = document.documentElement.clientHeight,
R1 = Math.round(Rh - R1bottom),
R2 = Math.round(Rh - W);
if (Rb.height > W) {
if (Ra.top < K) {
// скролл вниз
if (R2 + N > R1) {
// не дойти до низа
if (Rb.bottom - W + N <= 0) {
// подцепиться
b.className = "sticky";
b.style.top = W - Rb.height - N + "px";
Z = N + Ra.top + Rb.height - W;
} else {
b.className = "stop";
b.style.top = -Z + "px";
}
} else {
b.className = "stop";
b.style.top = -R1 + "px";
Z = R1;
}
} else {
// скролл вверх
if (Ra.top - P < 0) {
// не дойти до верха
if (Rb.top - P >= 0) {
// подцепиться
b.className = "sticky";
b.style.top = P + "px";
Z = Ra.top - P;
} else {
b.className = "stop";
b.style.top = -Z + "px";
}
} else {
b.className = "";
b.style.top = "";
Z = 0;
}
}
K = Ra.top;
} else {
if (Ra.top - P <= 0) {
if (Ra.top - P <= R1) {
b.className = "stop";
b.style.top = -R1 + "px";
} else {
b.className = "sticky";
b.style.top = P + "px";
}
} else {
b.className = "";
b.style.top = "";
}
}
window.addEventListener(
"resize",
function () {
a.children[0].style.width = getComputedStyle(a, "").width;
},
false
);
}
}
})();
P.S. в коде ничего не менял еще, даже комментарии не трогал.
Ответы (2 шт):
window.innerWidth - Дает текущую ширину окна в пикселях.
console.log( typeof window.innerWidth)
console.log( window.innerWidth );
Решение будет таким:
function Ascroll() {
if (window.innerWidth < 768) return;
// Остальное - не трогать
При этом, функция всё равно будет запускаться при любом скролле, но прерываться (return), если ширина оказалась меньше 768 (проверьте, вам нужно именно строго меньше 768 или меньше либо равно <= 768?)
Существует и такой подход (не трогая функцию Ascroll):
window.addEventListener("resize", function() {
if (window.innerWidth < 768) {
window.removeEventListener("scroll", Ascroll);
} else {
window.addEventListener("scroll", Ascroll); // Третий параметр и так по умолчанию false
}
});
Формально, так происходит меньше "затрат" на проверку window.innerWidth < 768, но это не серьезно, т.к. речь идет всего о нескольких вызовах в секунду. Первый вариант просто удобнее.
Кроме предложенного метода c innerWidth можно так же воспользоваться методом интерфейса window, под названием matchMedia, который вернет boolean значение в зависимости от собственных настроек и размера viewport'a клиента:
console.log(window.matchMedia("(max-width: 768px)").matches)
function Ascroll() {
if (window.matchMedia("(max-width: 768px)").matches) return
}