Как открыть якорь на вложенном «начальном аккордеоне» и прокрутить к вершине активного (открытого) аккордеона при загрузке страницы - PullRequest
0 голосов
/ 15 января 2019

У меня есть вложенный Аккордеон Bootstrap, подобный этому:

- Collapse1
----- Collapse1
----- Collapse2
------- Collapse1
------- Collapse2
--Collapse2
----- Collapse1
----- Collapse2
----- Collapse3
--Collapse3
----- Collapse1
----- Collapse2
----- Свернуть3

Моя цель: когда страница загрузится, я хочу открыть нужный коллапс (с помощью параметра 'anchor' в URL) и прокрутить окно браузера до него. Мой код:

$(function() {
    var searchParams = new URLSearchParams(location.search);
    var anchor = searchParams.get('anchor');
    if (!anchor) {
        throw new TypeError('There is no "anchor" parameter in the URL');
    }
    openCollapse(anchor);
});

$('#w0-collapse2').on('shown.bs.collapse', function () {
    var element =  document.getElementById('w0-collapse2');
    element.scrollIntoView({
        behavior: 'smooth',
        block: 'start'
    });
});

function openCollapse (elementId) {
    var targetCollapse = $('#' + elementId);
    if (!targetCollapse.hasClass('collapse')) {
        throw new TypeError('error');
    }
    var parents = targetCollapse.parents('.panel-collapse').toArray().reverse();
    parents.push(targetCollapse);

    $.each(parents, function (key, object) {
        $(object).collapse('show');
    });
}

Проблема в том, что коллапс открывается, но прокрутка не происходит: (
Я пытался подписаться на родительские события в цикле и использовать Deferred objects, но это не помогло :( Есть идеи?

UPD: Я думаю, это происходит потому, что "коллапс" рендерится не мгновенно. Это будет работать, если я добавлю таймер. Но это плохая идея. Как я могу избежать этого?
UPD2: Я также добавил свой код, используя обещания. Но это тоже не работает.

$(function() {
    var searchParams = new URLSearchParams(location.search);
    var anchor = searchParams.get('anchor');
    if (!anchor) {
        throw new TypeError('There is no "anchor" parameter in the URL');
    }
    openCollapse(anchor).done(function () {
        var element =  document.getElementById(anchor);
        element.scrollIntoView({
            behavior: 'smooth',
            block: 'start'
        });
        console.log('It worked on main function');
    });
});

function openCollapse (elementId) {
    var promises = [];
    var targetCollapse = $('#' + elementId);
    if (!targetCollapse.hasClass('collapse')) {
        throw new TypeError('error');
    }
    var parents = targetCollapse.parents('.panel-collapse').toArray().reverse();
    parents.push(targetCollapse);

    $.each(parents, function (key, object) {
        var dfd = new $.Deferred();
        $(object).collapse('show');
        $(object).on('shown.bs.collapse', function () {
            dfd.resolve();
        });
        promises.push(dfd);
    });

    return $.when.apply($, promises).promise();
}
...