使用"下一步直到"函数切换特定的表行



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

只是我试图强制获取某种 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;
}
}
});

下一步必须简单,直到只在子行上工作,但到目前为止我还没有管理它,根据 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,我只想隐藏单击的(事件)下的那些。

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

儿童事件只能添加到其相关事件下。

重新编辑 :

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>

点击 第一个事件 :

<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 中放置多个类名时,可以用空格分隔类名,而不是用逗号分隔类名。 有关工作演示,请参见此处:

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


由于您似乎遇到了性能问题,因此这是NextTil的特殊用途版本,在此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 必须是什么。 这并不容易,有时是不可能的,当然永远不会带来最好的解决方案。

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

$('.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();
});

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

最新更新