Jquery 使用nextUntil函数切换特定表行

Jquery 使用nextUntil函数切换特定表行,jquery,Jquery,我有一个包含事件的表,点击它的图标(箭头),我会创建新行(称为子事件),然后将其添加到当前行下。我想,在同一个图标上单击,隐藏它的子事件,但只有他的。现在,如果我单击一个新事件(不同的行),它将切换每个隐藏行,即使它们与当前行不相关 简单地说,我试图强制获取某种类型的UntilNext,但我无法使该函数工作,并且使用我正在进行的简单循环,它跳过oneEvent,但触发每个子行,而不是我想要的 $('.JSONArrow').on("click", function () { var i

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

简单地说,我试图强制获取某种类型的UntilNext,但我无法使该函数工作,并且使用我正在进行的简单循环,它跳过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;
        }
    }
});
}

这就是我想要的,文本上:切换我单击的tr下的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>

单击新的oneEvent:

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

单击另一个新的oneEvent

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


是的。我们有足够的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中放置多个类名时,可以用空格而不是逗号分隔类名。请参见此处,以了解可用的演示:


由于您似乎遇到了性能问题,这里有一个特殊用途的nextUntil版本,它比此jsperf中的速度快3倍:

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

 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()
查找与此容器中的选择器匹配的对象

如果要将某些内容应用于容器中的所有项,则选择更高的容器选择器(可能与整个表类似)。如果您只想将某个内容应用于此区域,那么您可以为
.nestest()
调用选择一个容器选择器,该调用仅适用于您的直接区域。然后,
.find()
将在您选择的任何区域中标识目标。通过这种方式,您可以只针对任何范围的子对象

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

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

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

我想继续从这一点出发,而不是从我的主要问题开始,谁变得非常集中

$('.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将出现,但在此之后,如果我尝试单击任何其他内容,我会收到一个错误框,说明脚本已崩溃。

请向我们显示相关的HTML。我想,如果您向我们展示实际的HTML,我们可能会将代码缩减为几行,因为您的代码中似乎有很多冗余,但我们需要知道HTML和类的确切结构,才能知道最好的建议。我被这句话弄糊涂了:
“全选('tr”)这是我的行变量的直接子变量,而不是其他变量。“
您的
变量已经是父
tr
。那么,为什么要选择作为当前
tr
子对象的
tr
?你们有嵌入式表格吗?再说一次,你能明白为什么我们需要看你的HTML吗?我可以在几分钟内回答这个问题,如果你真的在这里回答问题,让它更清楚你想要什么。对不起,这是晚餐休息时间。我指的是逻辑子级,不是html子级(不是嵌入表,只是行变量)
Row.find(".ChildEvent").slideToggle();
 Row.nextUntil(".oneEvent", ".ChildEvent").slideUp();
$('.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()
$(this).closest("tr").find("target selector").action()
$('.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();
});