i'm playing around javascript tab system.
as window width falls below breakpoint tab content inserts after links accordion layout, , process reversed increase window width.
everything works intended reduce window size, breaks increase window width. following code causing issue tabbody.appendchild( tabbodyitems[k] );
.
only 2 of 3 .c-tabs_bodyitem
elements append???
html
<div class="c-tabs" id="js-tabs"> <div class="o-container"> <div class="o-row c-tabs_head"> <div class="o-col-sm-4 c-tabs_headitem"> <a href="" class="c-tabs_link">link 1</a> </div> <div class="o-col-sm-4 c-tabs_headitem is-active"> <a href="" class="c-tabs_link">link 2</a> </div> <div class="o-col-sm-4 c-tabs_headitem"> <a href="" class="c-tabs_link">link 3</a> </div> </div> <div class="c-tabs_body"> <div class="c-tabs_bodyitem"> <ul> <li>lorem ipsum dolor sit amet, consectetur adipisicing elit.</li> <li>lorem ipsum dolor sit amet, consectetur adipisicing elit.</li> </ul> </div> <div class="c-tabs_bodyitem is-active"> <ul> <li>lorem ipsum dolor sit amet, consectetur adipisicing elit.</li> <li>lorem ipsum dolor sit amet, consectetur adipisicing elit.</li> </ul> </div> <div class="c-tabs_bodyitem"> <ul> <li>lorem ipsum dolor sit amet, consectetur adipisicing elit.</li> <li>lorem ipsum dolor sit amet, consectetur adipisicing elit.</li> </ul> </div> </div> </div> </div>
javascript
i won't show javascript actual tabbing system; isn't causing issue.
function insertafter( el, referencenode ) { referencenode.parentnode.insertbefore( el, referencenode.nextsibling ); } function debounce( func, wait, immediate ) { var timeout; return function() { var context = this, args = arguments; var later = function() { timeout = null; if (!immediate) func.apply(context, args); }; var callnow = immediate && !timeout; cleartimeout(timeout); timeout = settimeout(later, wait); if (callnow) func.apply(context, args); }; } var tabheaditems = document.getelementsbyclassname( 'c-tabs_headitem' ); var tabbody = document.queryselector( '.c-tabs_body' ); var tabbodyitems = document.getelementsbyclassname( 'c-tabs_bodyitem' ); var istabs = true; function settab() { if ( window.matchmedia( '(min-width: 768px)' ).matches && istabs === false ) { for( var k = 0, lenk = tabbodyitems.length; k < lenk; k++ ) { tabbody.appendchild( tabbodyitems[k] ); } istabs = true; } else if ( window.matchmedia( '(max-width: 767px)' ).matches && istabs === true ) { for( var l = 0, lenl = tabbodyitems.length; l < lenl; l++ ) { insertafter( tabbodyitems[l], tabheaditems[l] ); } istabs = false; } } settab(); var debouncesettab = debounce(function() { settab(); }, 250 ); window.addeventlistener( 'resize', debouncesettab );
the reason getelementsbyclassname
returns live nodelist
. means dom changes, content of nodelist
changes reflect it. order of elements tabbodyitems
based on positions in dom, when move elements around in dom, indexes in tabbodyitems
change reflect this. happening while you're looping through collection in for
loop, you're skipping elements because renumbered.
the simplest fix use document.queryselectorall
instead of document.getelementsbyclassname
. returns static nodelist
.
function insertafter( el, referencenode ) { referencenode.parentnode.insertbefore( el, referencenode.nextsibling ); } function debounce( func, wait, immediate ) { var timeout; return function() { var context = this, args = arguments; var later = function() { timeout = null; if (!immediate) func.apply(context, args); }; var callnow = immediate && !timeout; cleartimeout(timeout); timeout = settimeout(later, wait); if (callnow) func.apply(context, args); }; } var tabheaditems = document.queryselectorall( '.c-tabs_headitem' ); var tabbody = document.queryselector( '.c-tabs_body' ); var tabbodyitems = document.queryselectorall( '.c-tabs_bodyitem' ); var istabs = true; function settab() { if ( window.matchmedia( '(min-width: 768px)' ).matches && istabs === false ) { for( var k = 0, lenk = tabbodyitems.length; k < lenk; k++ ) { tabbody.appendchild( tabbodyitems[k] ); } istabs = true; } else if ( window.matchmedia( '(max-width: 767px)' ).matches && istabs === true ) { for( var l = 0, lenl = tabbodyitems.length; l < lenl; l++ ) { insertafter( tabbodyitems[l], tabheaditems[l] ); } istabs = false; } } settab(); var debouncesettab = debounce(function() { settab(); }, 250 ); window.addeventlistener( 'resize', debouncesettab );
<div class="c-tabs" id="js-tabs"> <div class="o-container"> <div class="o-row c-tabs_head"> <div class="o-col-sm-4 c-tabs_headitem"> <a href="" class="c-tabs_link">link 1</a> </div> <div class="o-col-sm-4 c-tabs_headitem is-active"> <a href="" class="c-tabs_link">link 2</a> </div> <div class="o-col-sm-4 c-tabs_headitem"> <a href="" class="c-tabs_link">link 3</a> </div> </div> <div class="c-tabs_body"> <div class="c-tabs_bodyitem" id="body1"> <ul> <li>lorem ipsum dolor sit amet, consectetur adipisicing elit.</li> <li>lorem ipsum dolor sit amet, consectetur adipisicing elit.</li> </ul> </div> <div class="c-tabs_bodyitem is-active" id="body2"> <ul> <li>lorem ipsum dolor sit amet, consectetur adipisicing elit.</li> <li>lorem ipsum dolor sit amet, consectetur adipisicing elit.</li> </ul> </div> <div class="c-tabs_bodyitem"id="body3"> <ul> <li>lorem ipsum dolor sit amet, consectetur adipisicing elit.</li> <li>lorem ipsum dolor sit amet, consectetur adipisicing elit.</li> </ul> </div> </div> </div> </div>
Comments
Post a Comment