0

編集:私が求めていることのより良い説明のために最後までスキップしてください、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」を指す場所にも追加されます。これは、次のようにしたい場所です。

  1. すべての直接の子 'ul' 要素を表示します。これは、その下にある章の見出しも意味します。ただし、それ以下は表示しないでください。
  2. すべての兄弟チャプターの選択したチャプターに表示されているものを非表示にします。
  3. 選択したチャプターの祖先にないすべての最上位のチャプターについて、選択したチャプターの表示内容を非表示にします。
4

3 に答える 3

2

HTML を再構成して有効にします。私のおすすめ:

<div id="toc">
   <h2>Table of Contents</h2>
   <ul>
      <li id="00034" class="art">
         <span class="chapterheading">Title</span>
         <!-- more stuff -->
         <div class="idea"> ... </div>
         ...
         <ul>
            <li id="00035">
               <span class="chapterheading selected">Subtitle</span>
            </li>
            ...
         </ul>
      </li>
      <li>
         <span class="chapterheading">Second Title</span>
         ...
      </li>
      ...
   </ul>
</div>

これはクラスを使用せず、内のすべての要素が章を表すchapterと想定しているだけです。li#toc

この構造により、構築された DOM (すべてのセレクターなどが適用され、開発者コンソールで調べることができます) は、HTML マークアップとまったく同じように見えます。コードでは、要素span内のタグがアイテムulのどこかに移動される可能性がありliます。

ここで、章見出しの後に続くすべての要素を非表示にするために、次のコード CSS コードを使用します。

#toc li > * {
    display: none;
}

ただし、li が選択されている場合は表示します。

#toc li > span.chapterheading, #toc li.selected > * {
    display: block;
}

selectedJavascript を使用すると、クリックに応じてクラスを移動するだけで済みます。

$(document).ready(function() {
    $("#toc").on("click", "span.chapterheading", function(ev) {
        $(this).closest("li")
          .addClass("selected")
          .siblings().removeClass("selected");
    });
});
于 2012-08-05T06:28:07.007 に答える
1

十分なコードを示していないため、何を操作しているのかわかりにくいです。

あなたのマークアップ パターンと、JavaScript の 1 行以外で何をしていると思うかに基づいて、次のことがうまくいくと思います。

$( '.chapterheading' ).click( function(){
  var t = $( this );
  //I assume you are doing other stuff with t...
  t.parent().next().show();
});

デモ: http://jsfiddle.net/US4Nr/

于 2012-08-05T05:00:35.873 に答える
0

<dl>このタイプの問題には、別のタイプのリスト、つまり、定義用語<dt>と定義の説明を組み合わせた定義リストが適してい<dd>ます。

HTML :

<div id="toc">
    <h2>Table of Contents</h2>
    <dl>
        <dt id="00034">Title 00034</dt>
        <dd class="text">text 00034</dd>
        <dd class="idea">idea 00034</dd>
        <dd class="sub">
            <dl>
                <dt id="00035">Subtitle 0035</dt>
                <dd class="text">text 00035</dd>
                <dd class="idea">idea 00035</dd> 
            </dl>
        </dd>
    </dl>
    <dl>
        <dt id="00036">Title 00036</dt>
        <dd class="text">text 00036</dd>
        <dd class="idea">idea 00036</dd> 
    </dl>
</div>

そしてJavaScript:

$("#toc dt").on('click', function() {
    $(this).closest("dl")
        .children(".idea").hide().end()
        .children(".text, .sub").toggle().end()
        .siblings().find("dd").hide();
});

$("#toc dd.text").on('click', function() {
    $(this).closest("dl").children(".idea").toggle();
});

デモ

すべての制御は、javascript によって直接実行されます。DEMO のすべての CSS は表示用であり、非表示/表示用ではありません。

特にイベント ハンドラーのアタッチ方法に関しては、希望どおりではない可能性がありますが、これにアプローチする方法についての良いアイデアが得られるはずです。

于 2012-08-05T22:00:31.903 に答える