cferdinandi / tabby

Lightweight, accessible vanilla JS toggle tabs.
MIT License
599 stars 73 forks source link

'tabby' event is not emitted when the tab ID is specified in the URL hash #110

Closed croxton closed 5 years ago

croxton commented 5 years ago

This can be a problem if you rely on the tabby event to load content into a tab with ajax, for example.

This is a workaround but it would be better if this was handled in Tabby:

// has a tab been selected in the URL hash?
const tabID = window.location.hash;

/* create multiple instances of Tabby */
const tabSelectors = document.querySelectorAll('[data-tabs]');
for (const [i, tabs] of [...tabSelectors].entries()) {

    tabs.setAttribute(`data-tabs-${i}`, '');

    let tabbyInstance = new Tabby(`[data-tabs-${i}]`);

    // workaround for when the tabID is specified in the URL hash
    let selectedTab = document.querySelector(`[data-tabs-${i}]` + ' [role="tab"][href*="' + tabID + '"]');

    if (selectedTab) {

        // fool Tabby into thinking the tab is not selected
        selectedTab.removeAttribute('aria-selected');

        // we need to wait for Tabby to setup the dom
        setTimeout(function(){
            tabbyInstance.toggle(tabID);
        }, 100);
    }
}
cferdinandi commented 5 years ago

Can you put together a reduced test case for me?

croxton commented 5 years ago

Sure: https://codepen.io/croxton/pen/ymJjNq

cferdinandi commented 5 years ago

Sorry for taking so long to get back to you on this @croxton. So, the event does fire, but in your demo, you've setup the listener after you have instantiated Tabby, so that first default tab load event fired before an event listener existed to catch it.

Put the event listener first and it will work as expected.

document.addEventListener('tabby', function (event) {
    console.log(event);
}, false);
var tabs = new Tabby('[data-tabs]');