← Назад к заметкам

Заметки

BX24.fitWindow может не уменьшить фрейм

Почему BX24.fitWindow в Bitrix24 можно использовать для увеличения высоты фрейма, но не нужно рассчитывать на надёжное уменьшение.

BX24.fitWindow проще вызывать после загрузки или раскрытия контента. Но если контент стал меньше, этот метод не всегда уменьшает фрейм обратно.

Суть проблемы

В приложениях и виджетах Bitrix24 фрейм может увеличиться после вызова BX24.fitWindow, но не уменьшиться после скрытия части интерфейса.

Суть

BX24.fitWindow подгоняет высоту фрейма под высоту содержимого страницы. В рабочих проектах его лучше воспринимать как способ увеличить фрейм под контент.

Если сначала показать длинный блок, вызвать BX24.fitWindow, а потом этот блок скрыть, фрейм может остаться прежней большой высоты.

Типовая цепочка выглядит так:

  • в приложении открыт короткий интерфейс;
  • пользователь раскрывает длинный блок;
  • вызывается BX24.fitWindow;
  • фрейм увеличивается по высоте;
  • пользователь скрывает длинный блок;
  • повторный вызов BX24.fitWindow может не уменьшить фрейм обратно.

Причина

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);
}

Источники