Заметки
BX24.fitWindow может не уменьшить фрейм
Почему BX24.fitWindow в Bitrix24 удобно использовать для увеличения высоты фрейма, но не стоит рассчитывать на надёжное уменьшение.
BX24.fitWindow удобно вызывать после загрузки или раскрытия контента.
Но если контент стал меньше, этот метод не всегда уменьшает фрейм обратно.
Суть проблемы
В приложениях и виджетах Bitrix24 фрейм может увеличиться после вызова
BX24.fitWindow, но не уменьшиться после скрытия части интерфейса.
Коротко
BX24.fitWindow подгоняет высоту фрейма под высоту содержимого страницы.
На практике его лучше воспринимать как способ увеличить фрейм под контент.
Если сначала показать длинный блок, вызвать BX24.fitWindow, а потом этот блок скрыть,
фрейм может остаться прежней большой высоты.
Типовая цепочка выглядит так:
- в приложении открыт короткий интерфейс;
- пользователь раскрывает длинный блок;
- вызывается
BX24.fitWindow; - фрейм увеличивается по высоте;
- пользователь скрывает длинный блок;
- повторный вызов
BX24.fitWindowможет не уменьшить фрейм обратно.
Где встречается
Чаще всего это заметно в интерфейсных встройках:
- в локальных приложениях Bitrix24;
- во вкладках CRM-карточки;
- в виджетах, добавленных через
placement.bind; - в приложениях со сворачиваемыми блоками;
- в таблицах, фильтрах и формах с динамической высотой;
- в интерфейсах, где контент подгружается после открытия фрейма.
Проблема особенно заметна, когда пользователь сначала открывает длинный список, а потом возвращается к короткому состоянию интерфейса.
Причина
BX24.fitWindow ориентируется на высоту содержимого, но не всегда корректно пересчитывает
сценарии, где контент был скрыт или схлопнут.
fitWindow подстраивается под scrollHeight
По документации BX24.fitWindow использует высоту содержимого фрейма:
BX24.getScrollSize().scrollHeight.
BX24.init(function () {
BX24.fitWindow(function () {
console.log('Команда изменения размера отправлена');
});
}); Это хорошо работает, когда содержимое стало выше: например, после загрузки таблицы, раскрытия деталей или добавления нового блока.
Уменьшение может не сработать
Если содержимое стало меньше, fitWindow не стоит использовать как гарантированное
уменьшение высоты фрейма.
function collapseDetails() {
const details = document.querySelector('[data-details]');
if (!details) {
return;
}
details.hidden = true;
BX24.fitWindow(function () {
console.log('Ожидаем уменьшение, но фрейм может остаться прежним');
});
} Для интерфейса это выглядит так, будто внизу приложения осталась лишняя пустая область.
Решение
Для раскрытия контента можно использовать BX24.fitWindow, а для уменьшения лучше
задавать размер явно.
Не рассчитывать на fitWindow при схлопывании
Простой рабочий подход:
- после увеличения контента вызывать
BX24.fitWindow; - после уменьшения контента явно вызывать
BX24.resizeWindow; - не ожидать, что
fitWindowвсегда вернёт фрейм к меньшей высоте; - держать минимальную высоту интерфейса в константе.
Использовать resizeWindow
Если нужно вернуть фрейм к известной высоте, лучше вызвать BX24.resizeWindow.
const FRAME_WIDTH = 1000;
const COLLAPSED_FRAME_HEIGHT = 420;
/**
* Раскрывает блок и подстраивает фрейм под увеличившийся контент.
*/
function expandDetails() {
const details = document.querySelector('[data-details]');
if (!details) {
return;
}
details.hidden = false;
BX24.fitWindow();
}
/**
* Скрывает блок и явно уменьшает фрейм.
*/
function collapseDetails() {
const details = document.querySelector('[data-details]');
if (!details) {
return;
}
details.hidden = true;
BX24.resizeWindow(FRAME_WIDTH, COLLAPSED_FRAME_HEIGHT, function () {
console.log('Фрейм явно уменьшен');
});
}
Если высота зависит от текущей разметки, её можно посчитать после изменения DOM и передать
в BX24.resizeWindow.
const FRAME_WIDTH = 1000;
const MIN_FRAME_HEIGHT = 320;
const FRAME_PADDING = 24;
/**
* Возвращает безопасную высоту фрейма.
*/
function calculateFrameHeight() {
const app = document.querySelector('[data-app]');
if (!app) {
return MIN_FRAME_HEIGHT;
}
const content_height = app.offsetHeight + FRAME_PADDING;
return Math.max(content_height, MIN_FRAME_HEIGHT);
}
/**
* Явно обновляет высоту фрейма.
*/
function resizeFrameToContent() {
const frame_height = calculateFrameHeight();
BX24.resizeWindow(FRAME_WIDTH, frame_height);
} Ширину в примерах нужно заменить на фактическую ширину приложения. Если ширина не меняется, её обычно выносят в константу и используют только для корректного вызова метода.