编辑:跳到结尾以更好地解释我所追求的,谢谢
我大约有以下 html(这只是一个摘录),其中有一个嵌套的章节组织:
<span class="chapter Art" id="00034">
<li><span class="chapterheading">Art<span>some stuff</span></li>
<ul>
<span class="chapter" id="00035">
<li><span class="chapterheading selectednode">Sound</span><span>more stuff</span></li>
<div class="idea">even more stuff</div>
</span>
</ul>
</span>
现在我希望使用 javascript 仅显示紧接在下面的章节标题,以及紧接在类“idea”的 div 下方,这样要查看任何“idea”,您必须单击它的直接父章节。
花了大约三个小时后(因为我对 jquery 有点陌生,我花了一段时间才意识到子选择器的真正工作原理),我想出了一个非常复杂的查询,它在显示相关方面做了我想要的节点(假设它们在运行此代码之前是隐藏的):
t.find("li > *, ul > .chapter, ul > .chapter > li, ul > .chapter > li *, > .idea, > .idea *").show();
其中“t”是最近单击的具有“selectednode”类的节点(编辑:是该节点的父节点的父节点)。
那么有没有更短的方式来表达我在这里需要的东西?
编辑:以下是一个更大的代码片段,根据要求有很多行李。寻找评论“隐藏相同深度的兄弟章节的孩子”。
我已经对其进行了一些修剪,但它并没有达到我想要的效果:我不能让它只显示下面的直接章节和想法,它显示了一切。
function toggleNode(node, value) {
//_("setting " + nv(node) + " to " + value + "\n");
$(node).toggleClass("selectednode", value);
if($(node).hasClass("selectednode") == true)
selectednode = node;
if($(selectednode).hasClass("selectednode") == false) // is this check really necessary?
selectednode = 0;
}
function zoomTo(node, select) {
var zoom, oldzoom, depth, t;
//_("zoomTo(" + (node ? $(node).text() : "0") + ", " + select + ")");
oldzoom = zoomednode;
if(node != zoomednode) {
savedepth = t = depth = $(node).parents("ul").length;
if(!zoomednode)
zoomednode = topChapter;
if(!node)
node = topChapter;
/* capture values */
var sz;
var capp = cBaseSz.slice((sz = parseFloat(cBaseSz)).length);
/* end capture */
zoom = zoomnum = sz;
while(--t > 0) {
zoomnum = (zoom *= 1.15);
}
//_("zoom: " + zoomnum +"\ncapp: " +capp);
zoom += capp;
//_("zoom: " + zoomnum);
depth -= $(zoomednode).parents("ul").length;
if(depth < 0)
depth *= -1;
switch(select) {
case 0:
case false:
default:
break;
case true:
case 1:
toggleNode(zoomednode, false);
toggleNode(zoomednode = node, true);
break;
case 2:
toggleNode(zoomednode, false);
zoomednode = 0;
}
/* Handle showing/hiding */
if(1) {
var hide;
t = ($(selectednode) || $(".chapterheading:first"));
_("t.text():" + t.text());
t = t.parent().parent();
_("isclass: " + t.attr("class"));
var prs = $(t).parents(".chapter");
prs = $(prs)[0] || t;
hide = $(prs).siblings(".chapter");
_("topparent: " + $(prs).text().slice(0,80));
$(hide).each( function() { {
_(($(this).html()||$(this).text()).slice(0, 80));
}});
$("li *, > ul, > idea", t).show();
//t.siblings().show();
//t.siblings().find().hide();
//hide.children(".chapterheading").find().show();
//showall(t.find("li *, ul > .chapter > li *"));
// Hide deeper children of this chapter (t)
// $(t).find("ul *:not(ul > .chapter > li, ul > li *)").hide();
// t.find("li > *, ul > .chapter, ul > .chapter > li, ul > .chapter > li *, > .idea, > .idea *").show();
// Show immediate children of this chapter (t)
//$(t).find("> li *, ul > .chapter").show();
// t.find(".chapterheading, .ideacount").show();
//$(hide).children().find(":not(.chapterheading, .ideacount)").hide();
// Hide children of sibling chapters of the same depth.
$("ul > .chapter", t).hide();
// Hide children of siblings of the top-most parent chapter of the selected chapter.
$("ul > .chapter, ul > .chapter .chapter", hide).hide();
// Show the selected chapter
$("ul > .chapter, ul > chapter .chapter", t.parent()).show();
}
//////////////////////////////
// old version below, but keeping for reference
else {
var showzoom = 1, showselect = 1, showidea = 1, seldepth, zdepth, showlist, hidelist = {};
/* This is the 'brute force' way of doing it, horribly inefficient */
if(zoomednode)
zdepth = $(zoomednode).parents(".chapter").length;
if(selectednode)
seldepth = $(selectednode).parents(".chapter").length;
else
seldepth = zdepth;
if(!seldepth)
seldepth = zdepth = 0;
_("seldepth: " + seldepth + "\nzdepth: " + zdepth);
(showlist=$(".chapter").filter( function() {
if($(this).parents(".chapter").length < (zdepth+showzoom))
return true;
else {
hidelist = $(hidelist).add(this);
return false;
}
}));
// hidelist = $("all").not(showlist);
if(hidelist)
_("hidelist size: " + hidelist.length);
_("showlist size: " + showlist.length);
$(showlist).show()/*.not(hidelist)*/;
if(hidelist && hidelist.length) {
//_("Hiding " + $(hidelist).length + " elements.");
$(hidelist).hide();
}
}
/* End showing/hiding */
/* Begin animating */
$("#contents").animate({ fontSize: zoom }, {duration: 0, queue: false });
$("html").animate(
{ scrollTop: $(node).offset().top - topAdjust }, {duration: 60+60*depth, queue: false }, 0);
$(window).scrollLeft($(node).offset().left - leftAdjust);
} else {
zoomTo(0, 1 + (selectednode == zoomednode));
}
}
function setupEvents() {
$("#contents .chapterheading").click( function() { _("\n-- -- -- CLICK -- -- --\n-- -- -- -- -- -- -- --\n"), zoomTo(this, true); });
}
编辑:为了进一步参考,标记属于以下类型(递归表示):
<ul> <!-- A: chapter heading list -->
<span class="chapter">
<li><span class="chapterheading">Title</span></li>
<!-- 0 or more of the following --> <div class="idea"><!-- more stuff --></div>
<!-- 0 or more of A: chapter heading list -->
</span>
</ul>
并且,变量“t”指向一个类“selectednode”的地方也将被附加,这是我希望发生以下情况的地方:
- 显示所有直接子 'ul' 元素,这也意味着下面的章节标题。但不要在下面显示任何内容。
- 隐藏所有同级章节的选定章节的显示内容。
- 隐藏所有不属于所选章节祖先的最顶层章节的所选章节显示的内容。