編集:私が求めていることのより良い説明のために最後までスキップしてください、thx
章のネストされた組織があるほぼ次の 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 を使用して、チャプターの見出しのすぐ下とクラス「アイデア」の div のすぐ下のみを表示して、「アイデア」を表示するには、そのすぐ上の親の章をクリックする必要があります。
約3時間費やした後(私は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); });
}
EDIT:さらに参考のために、マークアップは次のようなものです(再帰的に表現されます):
<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' 要素を表示します。これは、その下にある章の見出しも意味します。ただし、それ以下は表示しないでください。
- すべての兄弟チャプターの選択したチャプターに表示されているものを非表示にします。
- 選択したチャプターの祖先にないすべての最上位のチャプターについて、選択したチャプターの表示内容を非表示にします。