14

我有一张可以展开和折叠的表格,但使用起来太乱了,IE 和 Firefox 无法正常使用它。

因此,这是 JavaScript 代码:

  function toggle_it(itemID){ 
      // Toggle visibility between none and '' 
      if ((document.getElementById(itemID).style.display == 'none')) { 
            document.getElementById(itemID).style.display = '' 
            event.preventDefault()
      } else { 
            document.getElementById(itemID).style.display = 'none'; 
            event.preventDefault()
      }    
  } 

和一个示例 HTML:

<table>
    <tr>
        <td>Product</td>
        <td>Price</td>
        <td>Destination</td>
        <td>Updated on</td>
    </tr>
    <tr>
        <td>Oranges</td>
        <td>100</td>
        <td><a href="#" id="toggle" onClick="toggle_it('tr1');toggle_it('tr2')">+ On Store</a></td>
        <td>22/10</td>
    </tr>
    <tr id="tr1" style="display:none">
        <td></td>
        <td>120</td>
        <td>City 1</td>
        <td>22/10</td>
    </tr>
    <tr id="tr2" style="display:none">
        <td></td>
        <td>140</td>
        <td>City 2</td>
        <td>22/10</td>
    </tr>
    <tr>
        <td>Apples</td>
        <td>100</td>
        <td><a href="#" id="toggle" onClick="toggle_it('tr3');toggle_it('tr4')">+ On Store</a></td>
        <td>22/10</td>
    </tr>
    <tr id="tr3" style="display:none">
        <td></td>
        <td>120</td>
        <td>City 1</td>
        <td>22/10</td>
    </tr>
    <tr id="tr4" style="display:none">
        <td></td>
        <td>140</td>
        <td>City 2</td>
        <td>22/10</td>
    </tr>
</table>

问题是我对每个人都使用一个 ID,这很烦人,因为我想为每个父母和很多父母都有很多隐藏的行,所以要处理的 ID 太多了。而 IE 和 FireFox 只显示第一个隐藏行而不显示其他行。我怀疑发生这种情况是因为我通过同时触发所有 ID 使其工作。我认为如果我使用类而不是 ID 来识别隐藏的行会更好。

我对这一切都很陌生,所以请尝试以任何简单的方式解释它。我也试过 jQuery 但没能得到它。

4

6 回答 6

19

很难弄清楚你想用这个样本做什么,但你实际上在考虑使用类的正确轨道上。我创建了一个 JSFiddle 来帮助演示一种更好的方法(我希望)。

这是小提琴:link

您所做的不是使用 ID,而是使用类。在您的代码示例中,有橘子和苹果。我将它们视为产品类别(因为我真的不知道您的目的是什么),具有自己的 ID。所以,我用or标记产品<tr>s 。class="cat1"class="cat2"

.toggler我还用一个简单的类标记链接。onclick在元素本身上具有属性并不是一个好习惯。您应该使用 JavaScript 在页面加载时“绑定”事件。我使用 jQuery 来做到这一点。

$(".toggler").click(function(e){
    // you handle the event here
});

使用这种格式,您将事件处理程序绑定到click带有 class 的链接事件toggler。在我的代码中,我data-prod-cat向链接添加了一个属性,toggler以指定它们应该控制哪些产品行。(这里解释了我使用data-*属性的原因。您可以谷歌“html5 数据属性”以获取更多信息。)

在事件处理程序中,我这样做:

$('.cat'+$(this).attr('data-prod-cat')).toggle();

使用这段代码,我实际上是在尝试创建一个选择器,$('.cat1')这样我就可以选择特定产品类别的行,并更改它们的可见性。我使用$(this).attr('data-prod-cat')它来访问data-prod-cat用户单击的链接的属性。我使用 jQuery切换功能,因此我不必if visible, then hide element, else make it visible像您在 JS 代码中那样编写逻辑。jQuery 处理这个问题。切换功能按照它所说的做toggle,并且指定元素的可见性。

我希望这已经足够解释了。

于 2013-11-05T20:18:54.420 回答
6

一种方法是在“父”行上放置一个类并删除所有 id 和内联onclick属性:

<table id="products">
    <thead>
    <tr>
        <th>Product</th>
        <th>Price</th>
        <th>Destination</th>
        <th>Updated on</th>
    </tr>
    </thead>
    <tbody>
    <tr class="parent">
        <td>Oranges</td>
        <td>100</td>
        <td><a href="#">+ On Store</a></td>
        <td>22/10</td>
    </tr>
    <tr>
        <td></td>
        <td>120</td>
        <td>City 1</td>
        <td>22/10</td>
    </tr>
    <tr>
        <td></td>
        <td>140</td>
        <td>City 2</td>
        <td>22/10</td>
    </tr>
    ...etc.
    </tbody>
</table>

然后有一些隐藏所有非父母的CSS:

tbody tr {
    display : none;          // default is hidden
}
tr.parent {
    display : table-row;     // parents are shown
}
tr.open {
    display : table-row;     // class to be given to "open" child rows
}

这大大简化了您的 html。请注意,我已将<thead>和添加<tbody>到您的标记中,以便轻松隐藏数据行并忽略标题行。

使用 jQuery,您可以简单地执行以下操作:

// when an anchor in the table is clicked
$("#products").on("click","a",function(e) {
    // prevent default behaviour
    e.preventDefault();
    // find all the following TR elements up to the next "parent"
    // and toggle their "open" class
    $(this).closest("tr").nextUntil(".parent").toggleClass("open");
});

演示:http: //jsfiddle.net/CBLWS/1/

或者,要在纯 JavaScript 中实现类似的东西,可能类似于以下内容:

document.getElementById("products").addEventListener("click", function(e) {
    // if clicked item is an anchor
    if (e.target.tagName === "A") {
        e.preventDefault();
        // get reference to anchor's parent TR
        var row = e.target.parentNode.parentNode;
        // loop through all of the following TRs until the next parent is found
        while ((row = nextTr(row)) && !/\bparent\b/.test(row.className))
            toggle_it(row);
    }
});

function nextTr(row) {
    // find next sibling that is an element (skip text nodes, etc.)
    while ((row = row.nextSibling) && row.nodeType != 1);
    return row;
}

function toggle_it(item){ 
     if (/\bopen\b/.test(item.className))       // if item already has the class
         item.className = item.className.replace(/\bopen\b/," "); // remove it
     else                                       // otherwise
         item.className += " open";             // add it
}

演示:http: //jsfiddle.net/CBLWS/

无论哪种方式,将 JavaScript 放在<script>正文末尾的元素中,以便它在表格被解析后运行。

于 2013-11-05T20:19:53.607 回答
5

JQuery 10.1.2 有一个很好的显示和隐藏函数来封装你正在谈论的行为。这将使您不必编写新函数或跟踪 css 类。

$("tr1").show();

$("tr1").hide();

w3cSchool 链接到 JQuery 显示和隐藏

于 2014-02-07T16:02:10.403 回答
2
event.preventDefault()

不适用于所有浏览器。相反,您可以在 OnClick 事件中返回 false。

onClick="toggle_it('tr1');toggle_it('tr2'); return false;">

不确定这是否是最好的方法,但我在 IE、FF 和 Chrome 中进行了测试,并且工作正常。

于 2013-11-05T20:23:39.623 回答
2

下面是我的脚本,它显示/隐藏 ID 为“agencyrow”的表格行。

<script type="text/javascript">

                        function showhiderow() {
                            if (document.getElementById("<%=RadioButton1.ClientID %>").checked == true) {

                                document.getElementById("agencyrow").style.display = '';
                            } else {

                                document.getElementById("agencyrow").style.display = 'none';
                            }


                        }
    </script> 

只需showhiderow()在单选按钮onClick事件上调用函数

于 2015-09-09T08:22:30.583 回答
0

AngularJS 指令 ng-show, ng-hide 允许显示和隐藏一行:

   <tr ng-show="rw.isExpanded">
   </tr>

当 rw.isExpanded == true 时一行将可见,而当 rw.isExpanded == false 时将隐藏一行。ng-hide 执行相同的任务,但需要相反的条件。

于 2016-05-23T16:48:38.720 回答