香草Javascript操纵窗口上的元素调整大小(Vanilla Javascript manipulating elements on window resize)

编程入门 行业动态 更新时间:2024-10-03 06:23:38
香草Javascript操纵窗口上的元素调整大小(Vanilla Javascript manipulating elements on window resize)

我正在玩一个Javascript标签系统。

当窗口宽度低于某个断点时,选项卡内容会在手风琴布局的链接之后插入,并且当您增加窗口宽度时,该过程会反转。

在减小窗口大小时,一切都按预期工作,但在增加窗口宽度时会中断。 以下代码导致问题tabBody.appendChild( tabBodyItems[k] ); 。

3 .c-Tabs_BodyItem元素中只有2个追加???

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

我不会为实际的标签系统显示Javascript; 这不是导致问题的原因。

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

I'm playing around with a Javascript tab system.

As the window width falls below a certain breakpoint the tab content inserts after the links for an accordion layout, and the process is reversed as you increase the window width.

Everything works as intended as you reduce the window size, but breaks as you increase the window width. The following code is causing the issue tabBody.appendChild( tabBodyItems[k] );.

Only 2 of the 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 the Javascript for the actual tabbing system; this isn't causing the 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 );

最满意答案

原因是getElementsByClassName返回一个实时 NodeList 。 这意味着随着DOM的更改, NodeList的内容会发生变化以反映它。 元素tabBodyItems的顺序基于它们在DOM中的位置,因此当您在DOM中移动元素时, tabBodyItems的索引tabBodyItems发生变化以反映这一点。 当您在for循环中循环遍历集合时会发生这种情况,因此您正在跳过元素,因为它们会重新编号。

最简单的解决方法是使用document.querySelectorAll而不是document.getElementsByClassName 。 这将返回一个静态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> 
  
 

The reason is that getElementsByClassName returns a live NodeList. This means that as the DOM changes, the content of the NodeList changes to reflect it. The order of the elements tabBodyItems is based on their positions in the DOM, so when you move the elements around in the DOM, their indexes in tabBodyItems change to reflect this. This is happening while you're looping through the collection in your for loop, so you're skipping elements because they get renumbered.

The simplest fix to this is to use document.querySelectorAll instead of document.getElementsByClassName. This returns a 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> 
  
 

更多推荐

本文发布于:2023-07-09 10:17:00,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/34/1085585.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:香草   元素   大小   窗口   Javascript

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!