微小变化后的手风琴按钮未关闭(面板)

时间:2017-07-21 16:54:43

标签: javascript button accordion

使用JavaScript。所以,我已经用两种方式设置了它。一种方式一切正常,另一种方式不会,尽管事实上我看不出它们之间的区别。

我在地图上选择用户后显示表格。每个新选择都会填充一个应该打开和关闭的新手风琴按钮。这些表是在Ajax调用GeoServer之后设置的,因此所有这些都必须是动态的(就像解决方案有效,但按钮不会关闭)。附加了一个计数,以便每次都创建新的面板/表容器/表。

场景1)我硬编码了可以正常工作的html。像这样:

    <div class="container" id="accordionContainer">      
        <button class="accordion">Selection 1</button>
            <div class="panel" id="panel1">
                <div class="container" id="tableContainer">
                     <table id="featureTable" class="display" width="100%">
                        <thead></thead><tfoot></tfoot>
                     </table>
              </div>
            </div>
    </div>

我在身体部分设置了6或7个(头部也适用)并对计数编号进行了硬编码(如上面的panel1)。效果很好。用户选择地图区域,功能以手风琴按钮显示。但我无法对其进行硬编码。对于选择/表的数量,不需要限制。

这让我想到:

场景2)在每个Ajax请求之后动态设置所有内容。这有效,但按钮不会关闭。它们是打开的并显示所有表格。

    var btnPart = '<button class="accordion">' + 'Selection ' + tableCount.toString() + ' ' + activeOverlay+ '</button>';
    var panelPart = '<div class="panel" id="panel' + panelCount.toString() + '">';          
    var tabContPart = '<div class="container" id="tableContainer' + tableContainerCount.toString() +'">';
    var tablePart = '<table id="featureTable' + tableCount.toString() +  '" class="display" width="100%"><thead></thead><tfoot></tfoot></table></div></div></div>';

        $('#accordionContainer').append(btnPart, panelPart, tabContPart, tablePart);
                         var newTable = '#featureTable' + tableCount.toString();
                                $(newTable).DataTable( {
                                    data: data.features,   //get the data under features
                                    columns: columns,
                                   destroy: true
                                } );  

我看不出提前对DOM进行硬编码或动态设置会导致按钮失去打开/关闭功能的区别。

根据要求更新的代码:

<body>

    <div id="map"></div>
    <div id="sidebar"></div>
    <div class="container" id="accordionContainer"></div>   
</body>  

<script>
    var acc = document.getElementsByClassName("accordion");
                var i;
                for (i = 0; i < acc.length; i++) {
                    acc[i].onclick = function(){
                        /* Toggle between adding and removing the "active" class,
                        to highlight the button that controls the panel */
                        this.classList.toggle("active");

                        /* Toggle between hiding and showing the active panel */
                        var panel = this.nextElementSibling;
                        if (panel.style.display === "block") {
                            panel.style.display = "none";
                        } else {
                            panel.style.display = "block";
                        }
                    }
}
        var btnPart = '<button class="accordion">' + 'Selection ' + tableCount.toString() + ' ' + activeOverlay+ '</button>';
        var panelPart = '<div class="panel" id="panel' + panelCount.toString() + '">';          
        var tabContPart = '<div class="container" id="tableContainer' + tableContainerCount.toString() +'">';
        var tablePart = '<table id="featureTable' + tableCount.toString() +  '" class="display" width="100%"><thead></thead>                        <tfoot></tfoot></table></div></div></div>';

            $('#accordionContainer').append(btnPart, panelPart, tabContPart, tablePart);
                             var newTable = '#featureTable' + tableCount.toString();
                                    $(newTable).DataTable( {
                                        data: data.features,   //get the data under features
                                        columns: columns,
                                       destroy: true
                                    } ); 
</script>     

1 个答案:

答案 0 :(得分:1)

因此,对于某些部件使用jquery而对其他部件使用vanilla JS则很奇怪。我是一个jQuery人,你正在使用jQuery,所以我将在jQuery中发布我的答案。

var acc = document.getElementsByClassName("accordion");

我就是这样做的。删除从btnPartonclick的所有内容。

Explination。运行代码时{{1}}执行的操作告诉Javascript查找页面上与您的选择匹配并监听点击的所有元素。在创建侦听器之后,它不会查找任何添加的内容。在您的示例中,只需在添加所有内容后向下移动代码即可。但首选方法是使用事件委托并将侦听器委托给父元素,或者在我的示例中委托文档本身。

我的代码说:

嘿,告诉文档,如果它被点击,检查它是否在.accordian上,以及是否运行此代码。

您的代码说,找到页面上的.accordians,如果点击它们,请运行此代码。

委托的好处是你可以随时通过ajax或任何东西添加更多元素,而听众​​仍然可以工作。