【问题标题】:how to use JQuery "toggle" with parameters?如何使用带有参数的 JQuery“切换”?
【发布时间】:2011-01-21 01:09:31
【问题描述】:

我有一张这样的桌子:

<table>
  <tr>
    <td><input type="button" title="Toggle" value="Show" id="btn534534" class="toggle" />    </td>
    <td>some data about ID 534534</td>
  </tr>
  <tr id="row534534" class="hiddenRow">
    <td colspan="2">some hidden data about ID 534534 that must show/hide with toggle</td>
  </tr>
  <tr>
    <td><input type="button" title="Toggle" value="Show" id="btn2423434" class="toggle" /></td>
    <td>some data about ID 2423434</td>
  </tr>
  <tr id="row2423434" class="hiddenRow">
    <td colspan="2">some hidden data about ID 2423434that must show/hide with toggle</td>
  </tr>
  <!-- many more rows here -->
</table>

有很多像上面这样的行“集”。对于每一“组”行,表中的一行是可见的。具有“hiddenRow”类的第二行在页面加载时被 JQuery 隐藏,如下所示:

$("tr.hiddenRow").hide();

现在我希望每个按钮在它之后立即切换行的可见性。请注意,可见行中的 INPUT 和隐藏行的 TR 共享一个唯一 ID。我想让按钮 onclick 调用 JQuery 函数并传递 ID,以便 JQuery 知道要切换哪一行。

有什么想法吗?我在网上找不到任何这样的例子。

【问题讨论】:

    标签: jquery


    【解决方案1】:

    这应该可以解决问题:

    $(document).ready(function() {
        $(".toggle").click(function() {
            $(this).closest('tr').next('tr.hiddenRow').toggle(); 
        });
    });
    

    http://jsfiddle.net/DU8rd/1(感谢Šime Vidas

    注意:这不会像您所指示的那样传递 ID,但它确实会创建您描述的行为。

    【讨论】:

    • closest('tr') 更合适,因为你不需要所有的父母,只需要 TR 元素
    • @ŠimeVidas 你能做一个小提琴(fork mine)来演示这个吗?我试了也没用。
    • 小心无标签的类选择器——它们在 CPU 周期中很昂贵。看看 JQuery 在 IE 中是如何在幕后实现它们的......它并不漂亮。
    • Nathan 的代码运行良好。但如果知道如何制作 ID 参数版本以供将来参考,那就太好了。
    【解决方案2】:

    我更喜欢@Nathan的解决方案,但是如果DOM关系会变得更复杂,你会这样做:

    $('#tableID input.toggle').click(function() {
        $('#row' + this.id.replace('btn', '')).toggle();
    });
    

    现场演示: http://jsfiddle.net/pHKat/1/


    更新:与上述相同,但使用事件委托:

    $('#tableID').click(function(e) {
        if (!$(e.target).hasClass('toggle')) { return; }
        $('#row' + e.target.id.replace('btn', '')).toggle();
    });
    

    这段代码多了一行代码,但在性能方面,这段代码更好,因为只绑定了一个事件处理程序(到表元素)。为了比较,我最初的解决方案(上图)为每个按钮绑定了一个事件处理程序。

    【讨论】:

    • 这里有两个问题:1) 使用 'tr.toggle' 否则在 IE 中对于较大的文档会很慢,2) 如果表格是动态的 - 如果 JS 可以添加和删除行对 - 你'我想使用 .live('click', function... 而不是 .click()。
    • @Chris 1. 是的,更具体的选择器肯定更好 2. 是的,对于动态表。我会坚持我的假设,即桌子是静态的。 (我尽量避免 live ,因为每次点击事件(在这种情况下)发生时它都会执行选择器查询)
    • @Chris & @Šime - $('#tableID').delegate('input.toggle','click', fn) - 两全其美 ;)
    • @gnarf 非常酷,没有遇到过 .delegate()。不幸的是,这个名字令人困惑,但功能是一个伟大的性能胜利。 api.jquery.com/delegate
    • @gnarf $('#tableID').delegate('input.toggle','click', fn) 等价于 $('#tableID').each(function() { $('input.toggle', this).live('click', fn); }); 它在内部使用 live()。我相信,如果可能的话,应该避免 live()。
    【解决方案3】:

    我的第一个建议是:

    "MANY ... hidden on page load" 是您使用 Javascript 来完成 CSS 的工作,它已经导致或将导致性能问题。定义:

    tr.hiddenRow {
        display: none;
    }
    

    在您的样式表中,并摆脱页面加载代码。

    我将使用以下代码来实现您的按钮代码:

    $('input.toggle').live('click', function(ev) {
        var id = this.id.substr(3);
        var row = $('#row' + id);
        if (row.hasClass('hiddenRow'))
            row.removeClass('hiddenRow');
        else
            row.addClass('hiddenRow');
    });
    

    如果其他功能不需要行 ID,您可以通过去掉 input 和 tr 上的 ID 来减小 HTML 的大小,然后使用 DOM-walking 实现切换:

    $('input.toggle').live('click', function(ev) {
        var row = $(this).parents('tr').next('tr');
        if (row.hasClass('hiddenRow'))
            row.removeClass('hiddenRow');
        else
            row.addClass('hiddenRow');
    });
    

    编辑:以前没有遇到过 jsfiddle - 这很有趣。给你:http://jsfiddle.net/z6rAe/

    再次更新以包括我对 Šime 答案的更正 - 为什么 StackOverflow 不在 cmets 中编写代码?

    $('#tableID').click(function(ev) {
        if (!$(ev.target).hasClass('toggle')) { return; }
        $(ev.target.id.replace('btn', '#row')).toggle();
    });
    

    http://jsfiddle.net/7Dy5s/3/

    【讨论】:

    • @Chris 您可以轻松地将这 6 行代码减少到一行:$('#row' + this.id.substr(3)).toggleClass('hiddenRow'); 1. 不需要这些局部变量,因为您只使用它们一次,2. 而不是if-else 语句只使用 toggleClass()
    • @Šime 同意,但是当你把事情分解成更小的步骤时,测试和教学会容易得多。否则,较新的编码员可能会打出简单的错字,最终出现错误,并留下这个单一的大规模复杂操作,并且不知道从哪里开始修复它。
    • 当我说 MANY 时,我的意思是最多 100 个隐藏行,因此性能并不是什么大问题,但我更喜欢可以在另一种情况下重用的最优雅的解决方案,比如要切换的数据恰好不与按钮相邻,并且行 ID 很关键。
    • @Chris 如果我们有很多代码,那可能是真的。但是在这种情况下,代码就足够简单了。我不认为初学者会对我上面发布的那行代码有问题。
    • @Blackcoil - 这里有两种解决方案。您需要保留 .hasClass() ,因为您可能还想切换按钮上的消息。看看我作为答案的一部分发布的 jsfiddle。
    【解决方案4】:

    使用像这样的自定义方法:

        <script type="text/javascript">
            function viewToggle(id){
                $('#'+id).slideToggle(500);
            }
        </script>
    

    然后让每个按钮调用上面的函数,传入你想要切换视图的 id 值:

    <table>
      <tr>
        <td><input type="button" onclick="viewToggle('row534534');" title="Toggle" value="Show" id="btn534534" class="toggle" />    </td>
        <td>some data about ID 534534</td>
      </tr>
      <tr id="row534534" class="hiddenRow">
        <td colspan="2">some hidden data about ID 534534 that must show/hide with toggle</td>
      </tr>
      <tr>
        <td><input type="button" onclick="viewToggle('row2423434');" title="Toggle" value="Show" id="btn2423434" class="toggle" /></td>
        <td>some data about ID 2423434</td>
      </tr>
      <tr id="row2423434" class="hiddenRow">
        <td colspan="2">some hidden data about ID 2423434that must show/hide with toggle</td>
      </tr>
      <!-- many more rows here -->
    </table>
    

    【讨论】:

    • @Nerd 我不明白为什么要定义一个单独的函数,因为该函数可以很容易地作为参数传递给 jQuery 的 click 方法。
    • 我同意之前的评论。
    • @gnarf 我因使用 onclick 而被否决,但原始发帖人因使用表格而被否决?如果您要成为 HTML 势利小人,请不要有选择性。 ;) 在我从中获取的代码中,我使用了该函数,因为我有几个想要切换视图的嵌套元素,一些是表,而另一些是嵌套在表结构中的 div。这样我就不需要写 2 个选择器了。整个报告(html + js)是从 C# 程序输出的……最重要的是 - 旧习惯很难改掉。
    • 这是表格数据,因此我使用表格。我没有使用表格进行 UI 布局,而是用于显示表格数据。
    • 作为对社区的承诺,在回答更多 jquery 问题之前,我将阅读不显眼的 javascript。
    猜你喜欢
    • 2011-07-24
    • 2014-05-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-08-31
    • 1970-01-01
    相关资源
    最近更新 更多