0

我有这个包含事件的表,单击它的图标(箭头)我创建新行(称为子事件),然后将其添加到当前行下。我想点击同一个图标来隐藏它的子事件,但只有他的。现在,如果我点击一个新事件(不同的行),它将切换每个隐藏的行,即使它们与当前行无关......

只是我试图强制获得某种UntilNext,但我无法使该功能正常工作,并且通过我正在执行的简单循环 atm 它跳过 oneEvent 但触发每个子行而不是我想要的那个。

$('.JSONArrow').on("click", function () {

    var image = $(this);
    var Row = image.closest("tr");

    Row.toggleClass("Opened");

    if (Row.hasClass("Opened")) {

        image.attr("src", "/Images/downArrow.png")

        if (!(Row.hasClass("alreadyOpen"))) {
            var id = image.attr("id");

            $.get("/Home/Child/" + id, function (data) {
                Row.after(data);
                Row.addClass("alreadyOpen");
            });
        }
    } else {
        image.attr("src", "/Images/rightArrow.png");
    }

    var tr = Row.nextAll('tr');

    for (i = 0; i < tr.length; i++) {
        var eventClass = $(tr[i]).attr('class');
        if (eventClass == 'ChildEvent')
            $(tr[i]).slideToggle()
        else {
            if (eventClass == 'oneEvent')
                return;
        }
    }
});

必须很简单,才能使 nextUntil 仅在子行上工作,但到目前为止我还没有管理它,根据 jquery doc,它应该很简单,例如:

   var tr = Row.nextUntil('tr',$(".oneEvent"));

    for (i = 0; i < tr.length; i++) {
        var eventClass = $(tr[i]).attr('class');
        if (eventClass == 'ChildEvent'){
            $(tr[i]).slideToggle()
        }
    }

但我不能让它工作。任何人都可以指出如何做到这一点,或者使用另一个我不知道的 jquery 函数将选择链接(childEvent)到我的 Row 变量而不是其他变量的所有('tr')。

如果您不了解 asp 或 mvc4,我不确定人们是否会更了解 hthml,但这里是:编辑::

<div class="TableHolder">
    <table id="mainTable">
        <thead> 
            <tr class="header">

                <th class="iconColumn">Child</th>

                <th>Date </th>
                .... other <th>
                </th>
        </tr>
    </thead>

            @Html.EditorFor(x => x.logs)

 </table>

这就是每个说的表格行:

     string dynamicClass = "";
if (Model.Parent == null )
{
    dynamicClass = "oneEvent";
}
else 
{  
    dynamicClass = "ChildEvent";
}

}

  <tr class="@dynamicClass">

      <td class="iconColumn">
        @if (Model.Parent == null )
        {
            <img class="JSONArrow" id="@Model.EventID" src="~/Images/rightArrow.png"/>
        }
    </td>

    <td>@Model.TimeUTC.ToString("dddd, dd MMMM yyyy")<br />@Model.TimeUTC.ToString("HH:mm:ss") </td>
    .... other column

</tr>

我会尽量简化我所说的:

您有行。(事件)当您单击行(事件)时,新的动态行会出现在其下方(称为 ChildEvent)。

如果您在行(事件)上再次单击,如果行存在于他之下,则隐藏行,但前提是它们是 ChildEvent 类。

我当前的代码隐藏了桌子上的所有 ChildEvent,我只想隐藏(事件)点击下的那些。

如果用户单击行(事件),它将显示(ChildEvent)(如果存在),但仅显示与单击的行(事件)相关的(childEvent),而不是整个表的ChildEvent。

childEvent 只能添加到其相关 Event 下。

重新编辑:

     row.nextUntil(".oneEvent", ".ChildEvent").slidetoggle();

这就是我想要的,文本:切换我点击的下方的 tr,如果他们有 ChildEvent 类。测试直到你到达一个拥有“oneEvent”类的tr。

我只是无法理解参数去了哪里。

重新编辑:

<table>
  <tr class=oneEvent></tr>
  <tr class=oneEvent></tr>
  <tr class=oneEvent></tr>
  <tr class=oneEvent></tr>
  <tr class=oneEvent></tr>
  <tr class=oneEvent></tr>
</table>

点击:

 <table>
  <tr class="oneEvent, Opened, alreadyOpened"></tr>
   <tr class=ChildEvent display = true></tr>
   <tr class=ChildEvent display = true></tr>
   <tr class=ChildEvent display = true></tr>
   <tr class=ChildEvent display = true></tr>
   <tr class=ChildEvent display = true></tr>
  <tr class=oneEvent></tr>
  <tr class=oneEvent></tr>
  <tr class=oneEvent></tr>
  <tr class=oneEvent></tr>
  <tr class=oneEvent></tr>
</table>

点击同一个事件

 <table>
  <tr class="oneEvent, alreadyOpened"></tr>
   <tr class=ChildEvent display = false></tr>
   <tr class=ChildEvent display = false></tr>
   <tr class=ChildEvent display = false></tr>
   <tr class=ChildEvent display = false></tr>
   <tr class=ChildEvent display = false></tr>
  <tr class=oneEvent></tr>
  <tr class=oneEvent></tr>
  <tr class=oneEvent></tr>
  <tr class=oneEvent></tr>
  <tr class=oneEvent></tr>
</table>

点击一个新的事件:

<table>
  <tr class="oneEvent, alreadyOpened"></tr>
   <tr class=ChildEvent display = false></tr>
   <tr class=ChildEvent display = false></tr>
   <tr class=ChildEvent display = false></tr>
   <tr class=ChildEvent display = false></tr>
   <tr class=ChildEvent display = false></tr>
  <tr class=oneEvent></tr>
  <tr class=oneEvent></tr>
  <tr class="oneEvent, Opened, alreadyOpened"></tr>
   <tr class=ChildEvent display = true></tr>
   <tr class=ChildEvent display = true></tr>
   <tr class=ChildEvent display = true></tr>
  <tr class=oneEvent></tr>
  <tr class=oneEvent></tr>
</table>

点击另一个新的事件

<table>
  <tr class="oneEvent, alreadyOpened"></tr>
   <tr class=ChildEvent display = false></tr>
   <tr class=ChildEvent display = false></tr>
   <tr class=ChildEvent display = false></tr>
   <tr class=ChildEvent display = false></tr>
   <tr class=ChildEvent display = false></tr>
  <tr class=oneEvent></tr>
  <tr class="oneEvent, Opened, alreadyOpened"></tr>
   <tr class=ChildEvent display = true></tr>
   <tr class=ChildEvent display = true></tr>
  <tr class="oneEvent, Opened, alreadyOpened"></tr>
   <tr class=ChildEvent display = true></tr>
   <tr class=ChildEvent display = true></tr>
   <tr class=ChildEvent display = true></tr>
  <tr class=oneEvent></tr>
  <tr class=oneEvent></tr>

点击前一个事件:

<table>
  <tr class="oneEvent, alreadyOpened"></tr>
   <tr class=ChildEvent display = false></tr>
   <tr class=ChildEvent display = false></tr>
   <tr class=ChildEvent display = false></tr>
   <tr class=ChildEvent display = false></tr>
   <tr class=ChildEvent display = false></tr>
  <tr class=oneEvent></tr>
  <tr class="oneEvent, Opened, alreadyOpened"></tr>
   <tr class=ChildEvent display = true></tr>
   <tr class=ChildEvent display = true></tr>
  <tr class="oneEvent, alreadyOpened"></tr>
   <tr class=ChildEvent display = false></tr>
   <tr class=ChildEvent display = false></tr>
   <tr class=ChildEvent display = false></tr>
  <tr class=oneEvent></tr>
  <tr class=oneEvent></tr>

单击第一个 OneEvent :

<table>
  <tr class="oneEvent, Opened, alreadyOpened"></tr>
   <tr class=ChildEvent display = true></tr>
   <tr class=ChildEvent display = true></tr>
   <tr class=ChildEvent display = true></tr>
   <tr class=ChildEvent display = true></tr>
   <tr class=ChildEvent display = true></tr>
  <tr class=oneEvent></tr>
  <tr class="oneEvent, Opened, alreadyOpened"></tr>
   <tr class=ChildEvent display = true></tr>
   <tr class=ChildEvent display = true></tr>
  <tr class="oneEvent, alreadyOpened"></tr>
   <tr class=ChildEvent display = false></tr>
   <tr class=ChildEvent display = false></tr>
   <tr class=ChildEvent display = false></tr>
  <tr class=oneEvent></tr>
  <tr class=oneEvent></tr>

4

2 回答 2

1

是的。我们有足够的 HTML 来查看您现在的要求!这是我的建议:

$('.JSONArrow').on("click", function () {
    var row = $(this).closest("tr");
    if (row.hasClass("Opened")) {
        // click on an already opened row
        this.src = "/Images/rightArrow.png";
        row.removeClass("Opened");
        // close all following .ChildEvent rows until you get to the next .oneEvent
        row.nextUntil(".oneEvent", ".ChildEvent").slideUp();
    } else {
        // click on a closed row
        this.src = "/Images/downArrow.png";
        row.addClass("Opened");
        // if not previously opened, then add the child HTML
        if (!row.hasClass("alreadyOpened")) {
            $.get("/Home/Child/" + this.id, function(data) {
                row.after(data);
                row.addClass("alreadyOpened");
            });
        } else {
            // show all following .ChildEvent rows until you get to the next .oneEvent
            row.nextUntil(".oneEvent", ".ChildEvent").slideDown();
        }
    }
});

您还必须修复您的 HTML。在 HTML 中放置多个类名时,使用空格而不是逗号分隔类名。请参阅此处以获取工作演示:

http://jsfiddle.net/jfriend00/ZkvgN/


由于您似乎遇到了性能问题,这里有一个特殊用途的 nextUntil 版本,在这个 jsperf 中测得它快 3 倍:http: //jsperf.com/nextuntilfast

jQuery.fn.nextUntilFast = function(untilClass) {
    // for speed reasons, this operates only on the 
    // first DOM object in the jQuery object
    var result = [], cur;
    if (this.length) {
        cur = this[0];
        while (cur = cur.nextSibling) {
            // check elements only
            if (cur.nodeType === 1) {
                if ($(cur).hasClass(untilClass)) {
                    break;
                } else {
                    result.push(cur);
                }
            }
        }
    }
    return this.pushStack(result, "nextUntilFast", untilClass);
};

您可以通过替换它来使用它:

 row.nextUntil(".oneEvent", ".ChildEvent").slideDown();

有了这个:

 row.nextUntilFast("oneEvent").slideDown();

好的,这是我想隐藏.ChildEvent当前行中所有对象的第三个猜测。由于您包含的 HTML 中没有.ChildEvent对象,这又是一个猜测:

Row.find(".ChildEvent").slideToggle();

由于您没有包含 HTML,因此很难确切知道如何解决此问题。

在阅读了您的问题大约 20 次之后(因为您不在身边回答澄清问题),这是我对您所问问题的最佳猜测。如果您想要对函数中的最后一段代码执行的操作是将单击后的任何行向上滑动,并且不包括带有 的行.oneEvent,那么您可以使用以下代码执行此操作:

 Row.nextUntil(".oneEvent", ".ChildEvent").slideUp();

.oneEvent指示停止匹配兄弟元素的位置。这.ChildEvent是一个过滤器,用于从结果中删除与该选择器不匹配的项目。这将为您提供所有后续行,直到(但不包括)也是该行的行,.oneEvent然后.ChildEvent它将它们向上滑动。如果它们已经关闭,它将使它们保持关闭状态。如果您真的想要切换,那么您可以.slideToggle()像原始代码一样使用,但我猜您真正想要的是折叠其他行。

这将是您的代码的修订版本:

$('.JSONArrow').on("click", function () {
    var row = $(this).closest("tr");
    if (row.hasClass("Opened")) {
        this.src = "/Images/rightArrow.png";
        row.removeClass("Opened");
    } else {
        this.src = "/Images/downArrow.png";
        row.addClass("Opened");
        // if not previously opened, then add the child HTML
        if (!row.hasClass("alreadyOpen")) {
            $.get("/Home/Child/" + this.id, function(date) {
                row.after(data);
                row.addClass("alreadyOpen");
            });
        }
    }

    // now close all the following rows up to .oneEvent
    row.nextUntil(".oneEvent", ".ChildEvent").slideUp();
});

这是我对您需要帮助的最初猜测...

将单击操作应用于发生单击的同一区域而不是文档中的所有区域的典型方法是使用以下算法:

$(this).closest("parent container selector").find("target selector").action()

您用于.closest()查找正确的父容器。您用于.find()查找与此容器中的选择器匹配的对象。

如果你想对容器中的所有项目应用一些东西,那么你选择一个更高的容器选择器(比如整个表)。如果您只想对这个区域应用一些东西,那么您选择一个容器选择器来.closest()调用仅上升到您的直接区域的调用。然后.find()识别您选择的任何区域中的目标。通过这种方式,您可以只针对您想要的任何范围的子对象。

例如,要将操作应用于与单击发生的同一行中的选择器匹配的所有项目,您可以这样做:

$(this).closest("tr").find("target selector").action()

有关更具体的代码,请将您的 HTML 添加到您的问题中。如您所知,您要求我们通过查看您的代码来尝试找出您的 HTML 必须是什么。这并不容易,有时也不可能,而且肯定永远不会导致最好的解决方案。

于 2012-10-15T15:45:15.093 回答
0

我想继续从这个开始工作会更容易,而不是我的主要问题是谁变得非常聚集......

$('.JSONArrow').on("click", function () {

    var image = $(this);
    var Row = image.closest("tr");

    Row.toggleClass("Opened");

    if (Row.hasClass("Opened")) {

        image.attr("src", "/Images/downArrow.png")

        if (!(Row.hasClass("alreadyOpen"))) {
            var id = image.attr("id");

            $.get("/Home/Child/" + id, function (data) {
                Row.after(data);
                Row.addClass("alreadyOpen");
            });
        }
    } else {
        image.attr("src", "/Images/rightArrow.png");
    }

    Row.nextUntil($(".oneEvent"), $(".ChildEvent")).slideToggle();
});

我让它像那样工作。但是我收到一个脚本错误,当我打开一个有很多 childEvent 的 oneEvent tr 时,我的浏览器会崩溃。chilldEvent 将出现,但之后如果我尝试单击其他任何内容,我会收到一个错误框,提示脚本已崩溃。

于 2012-10-15T18:11:35.410 回答