- ベストアンサー
JavaScriptで条件付きのコンテンツ絞り込み機能を実装する方法
- JavaScriptのみで地域やクラス、性別などの条件に基づいてコンテンツを絞り込む機能を実現する方法について説明します。
- 条件に合う絞り込みを実行するとコンテンツが表示され、該当しないものは非表示になります。条件を変更して再度実行することも可能です。
- 条件を指定しないで実行ボタンを押すと全てのコンテンツが表示されます。条件に合うコンテンツがない場合は「見つかりませんでした」と表示されます。
- みんなの回答 (6)
- 専門家の回答
質問者が選んだベストアンサー
こんばんは、ながいのでぶんかつします。 <!DOCTYPE html> <html lang="ja"> <title></title> <style> #NONE { display:none} </style> <body> <form> <ol> <li> 地域: <select name="a" onchange="find()"> <option value="">指定しない <option value="神奈川県">神奈川県 <option value="山梨県">山梨県 <option value="北海道">北海道 </select> </li> <li> クラス: <select name="b" onchange="find()"> <option value="">指定しない <option value="クラスA">クラスA <option value="クラスB">クラスB <option value="クラスC">クラスC </select> </li> <li> 性別: <select name="c" onchange="find()"> <option value="">指定しない <option value="男性">男性 <option value="女性">女性 </select> </li> <li> 年齢: <select name="d" onchange="find()"> <option value="">指定しない <option value="0,20">20歳未満 <option value="20,30">20歳以上30歳未満 <option value="30,40">30歳以上40歳未満 <option value="40,200">40歳以上 </select> </li> <li> 学校名: <select name="e" onchange="find()"> <option value="">指定しない <option value="あ">あ <option value="い">い <option value="う">う </select> </li> <li> 体重: <select name="f" onchange="find()"> <option value="">指定しない <option value="0,50">50kg未満 <option value="50,60">50kg以上60kg未満 <option value="60,70">60kg以上70kg未満 </select> </li> </ol> <img src="" onclick="" alt="検索の実行" onchange="find()"> </form> <!-- ↓コンテンツ↓ --> <ul id="HOGE"> <li> <ol> <li>地域:神奈川県</li> <li>クラスA</li> <li>性別:男性</li> <li>年齢:25歳</li> <li>学校名:あ</li> <li>体重:55kg</li> <li>名前:ジャバ スクリプト</li> </ol> </li> <li> <ol> <li>地域:神奈川県</li> <li>クラスC</li> <li>性別:女性</li> <li>年齢:33歳</li> <li>学校名:う</li> <li>体重:42kg</li> <li><em>名前:グー</em></li> </ol> </li> </ul> <div id="NONE"> <p>コンテンツがありません</p> </div> <script> (function () { var A = Array.prototype; var reg_data_format = /^\s*(.+):((\d+)?(.+))\s*$/; //ラベル,データ,数値,単位 var reg_trim = /^\s+|\s+$/g; function getTextContent (node) { return (3 === node.nodeType) ? node.data.replace (reg_trim, '') : (node.hasChildNodes ()) ? A.map.call (node.childNodes, arguments.callee).join ('') : ''; } function isLiTag (n) { return ('LI' === n.nodeName); } function isTdTag (n) { return ('TD' === n.nodeName); } function ListFinder (node, depth) { this.node = node; this.depth = depth; this.value = []; } function setSelected (state) { this.value.forEach (function (v) { v.selected = this.state; }, { state: !!state }); } function getSelectedNode () { return this.value.reduce ( function (a, v) { return (v.selected) ? a.concat(v.node): a; }, []); } function select (cond, logic) { if (0 === arguments.length || 'function' !== typeof cond) return null; return this.value.filter (function (v) { var result; switch (this.logic) { case 'and' : case '+' : if (v.selected) v.selected = result = !! this.cond (v); break; case 'or' : case '-' : if (! v.selected) { result = !! this.cond (v); if (result) { v.selected = result; } } break; default : v.selected = result = !! this.cond (v); break; } return result; }, { cond: cond, logic: logic }).map (function (v) { return v.node; }); } function getChildNodes (li) { var value = []; var data, ary, obj; for (var node = li.firstChild; node; node = node.nextSibling) { switch (node.nodeType) { case 1 : switch (node.tagName) { case 'IMG' : if (node.alt) value.push (node.alt); break; case 'UL' : case 'OL' : case 'TABLE' : case 'DL' : if (0 < this.depth) { obj = create (node, this.depth -1); value.push (obj.getData ()); } else { value.push (getTextContent (node)); } break; } break;
その他の回答 (5)
- babu_baboo
- ベストアンサー率51% (268/525)
むだにかいとうがおおいものです indexOf のかいしゃくがちがいます これには、2しゅるいあります。 String.indexOf https://developer.mozilla.org/ja/JavaScript/Reference/Global_Objects/String/indexOf Array.indexOf https://developer.mozilla.org/ja/JavaScript/Reference/Global_Objects/Array/indexOf こんかいは、はいれつでりようしています https://developer.mozilla.org/ja/JavaScript
- babu_baboo
- ベストアンサー率51% (268/525)
あ~、わたしからせいつめいをきいたりしてだいじょうぶ? -- >Array.prototype.filter.call(変数,実行させるもの) >Array.prototype.forEach.call ふだんならこうつかうはず。 var ary = [0,1,2,3,4,5,6,7,8,9].filter (function (n) { return !(n%2); });//ary=偶数 <ol id="hoge"> <li>0 <li>1 <li>2 <ol> しかし、のーどりすうとのばあいつかえない。 document.querySelectorAll ('#hoge > li') .filter (function (e) {return !((+e.textContent)%2));}); //だめ そんなときは、いかのようにするとつかえる Array.prototype.filter.call (document.querySelectorAll ('#hoge > li'), function (e) {return !((+e.textContent)%2));}); -- >.ownerDocument ここにでかいとうするひとも、ownerDocument をつかうひとはすくないですね。 document は、ぐろーばるです。なので、「グローバルへんすうをつかわないように」 といっているひとさえ、それをつかったりします。 「いべんとはんどら」などでよくつかいます。 document.addEventListener ('click', function (event) { var node = event.target; var doc = event.ownerDocumen; document.getElementById ('hoge').innerHTML = '<p>abc</p>'; }, false); でもフレームをつかったぺーじなどのばあい、doc === document でないときがあるので かくじつにいべんとがおこなわれた document をしるすべとしてつかったりします。 -- >.textContent.match これは、わけてかんがえてください node.textContent HTMLようそにふくまれるてきすと(もじれつ)をかえす。ie なら .innerText です。 string.match これは、せいきひょうげんにあります -- >this.style.display = 'none'; おそらくその this は、LI ようそのときのことだとおもいます。 すたいるしーとで、よくしていしますよね、。 すくりぷとからへんこうするばあいにつかいます。 <style> li { width:100px; display: none; } </style> -- >.parentNode.parentNode のーどのおやのおや。じいさんですね。def の liようそからみれば abc の liようそです。 ul からみれば ol。 げんじつせかいとちがい、「こ」はたくさんあっても「おや」は1つです。 <ol> <li>abc <ul> <li>def ところで、このせつめいはここだけのはなしにしてくださいね。 「出典」は、ごじぶんでさがしてください。 ぎょうしゃにいらいしたほうが、はるかによいこーどだと・・・。 それから、こんかいしつもんのしかたが、わるいとおもいます。 おもいっきり、さくせいいらいです。かいとうがつきにくいです。 がっつりかいてくれるひとは、すくないとおもいます。 しつもんは、こわけして、かいとうしゃのこころを、ゆさぶるようなしもんならくいつかも。 さすがに「23歳OLです。」みたいなのには、もうくいつきませんが。 おそわったことを、てきとうにつたえていると、芯のない画鋲をさされることもある?(笑)
- babu_baboo
- ベストアンサー率51% (268/525)
あちゃぁ~その2 var a = ListFinder.create (node1); var b = ListFinder.create (node2); に。 > <li>の中に:がなければ、もっと短くすんだのでしょうか。 きっとちょっとだけみじかくなるけど、そもそもその LI ようそのなかにある、まーくあっぷがへんなんだよ <li><label>年齢</label><span class="value">3</span><span class="unit">ちゅ</span></li> みたいになるのかな? でもそれをかいせきすると、おれのりきりょうじゃみじかくならないな。 むしろ、LI ようそでなく、table こうぞうからよみとり、ひょうじさせて、でーただけ、createElement をつかって、つくりだしてひょうじすればよい。つくりだすなら、たんいなんて、てーぶるだった、thようそに、年齢(歳)とかしておけるし。 まえのかいとうで、すくりぷとがわにでーたをもつと、すくりぷとがむこうだとなにもひょうじされないよ。 でーたをとりこんで、ひつようなものだけを、いろいろなかたちでひょうげんできるようになると、いいですよね。
- babu_baboo
- ベストアンサー率51% (268/525)
> 性別のところで あちゃぁ~ごめん。 > <li>の中の:を消すと機能しなくなってしまいます。 そうじゃないんだなぁ~ var reg_data_format = /^\s*(.+):((\d+)?(.+))\s*$/; //ラベル,データ,数値,単位 と、 value.push ({label: ary[1], text: ary[2], number: Number (ary[3]), unit: ary[4]}); せいきひょうげんで、もし、li ようそに ":" があるのならば、 value.label になり、それいこうが .text になり、 もし、.text のさいしょが、すうちならば、.number に、すうちのあとにもじれつがあれば、.unit にだいにゅうされる。 .value の、はいれつも1つなら、はいれつをはずしてるので、もくてきの value のあたいをみつけてね。 もし、":" がないときは、そのまま .value にないかな? > 意図的に欠陥を作ったということですか? べんきょうは、じぶんのためです。いとてきにではなく、ひつぜんてきにはいりこむのだ! >>>ListFinder.create でつくったおぶじぇくとのでーたをかいへん var a = ListFinder.create (node1); var b = ListFinder.create (node1); このようにすると、finder がふたつでき、それぞれをせいぎょできる。 そして、 a.value[1].value[4].number = 4; みたいにしても、でーたをへんこうすることはできない。 ぷろぐらむをつくるときは、じょうぶにつくるのだそうだ。そしてへんこうにもつよく。 なので、かってにでーたをいじられないようにつくる。 いまは、そのためのべんきょうちゅうでもあります。 > tableを入れて何をしようとしていたのか気になります。 でーたのならびは、りすとこうぞうだけではありません。 てーぶるだって、りっぱなでーたのりすとこうぞうです。 とりこんでしまえれば、おなじようにせいぎょできます。 もし、できたならべんりではありませんか? そうそう、IE7 とか IE8 とかでうごかすのなら if(!Array.prototype.filter)Array.prototype.filter=function(b,e){var f=this.length;if(typeof b!="function")throw new TypeError;for(var c=[],a=0;a<f;a++)if(a in this){var d=this[a];b.call(e,d,a,this)&&c.push(d)}return c}; if(!Array.prototype.forEach)Array.prototype.forEach=function(b,c){var d=this.length;if(typeof b!="function")throw new TypeError;for(var a=0;a<d;a++)a in this&&b.call(c,this[a],a,this)}; if(!Array.prototype.every)Array.prototype.every=function(b,c){var d=this.length;if(typeof b!="function")throw new TypeError;for(var a=0;a<d;a++)if(a in this&&!b.call(c,this[a],a,this))return false;return true}; if(!Array.prototype.map)Array.prototype.map=function(b,e){var c=this.length;if(typeof b!="function")throw new TypeError;for(var d=Array(c),a=0;a<c;a++)a in this&&(d[a]=b.call(e,this[a],a,this));return d}; if(!Array.prototype.some)Array.prototype.some=function(b,c){var d=this.length;if(typeof b!="function")throw new TypeError;for(var a=0;a<d;a++)if(a in this&&b.call(c,this[a],a,this))return true;return false}; if(!Array.prototype.reduce)Array.prototype.reduce=function(d){var c=this.length;if(typeof d!="function")throw new TypeError;if(c==0&&arguments.length==1)throw new TypeError;var a=0;if(arguments.length>=2)var b=arguments[1];else{do{if(a in this){b=this[a++];break}if(++a>=c)throw new TypeError;}while(1)}for(;a<c;a++)a in this&&(b=d.call(null,b,this[a],a,this));return b}; if(!Array.prototype.reduceRight)Array.prototype.reduceRight=function(d){var c=this.length;if(typeof d!="function")throw new TypeError;if(c==0&&arguments.length==1)throw new TypeError;var a=c-1;if(arguments.length>=2)var b=arguments[1];else{do{if(a in this){b=this[a--];break}if(--a>=c)throw new TypeError;}while(1)}for(;a>=0;a--)a in this&&(b=d.call(null,b,this[a],a,this));return b}; とか。
- babu_baboo
- ベストアンサー率51% (268/525)
case 3 : data = node.data.replace (/^\s+|\s+$/g, ''); if (ary = data.match (reg_data_format)) value.push ({label: ary[1], text: ary[2], number: Number (ary[3]), unit: ary[4]}); else if (data) value.push (data); break; } } // return {node: li, value: value }; return {node: li, value: (value.length == 1) ? value[0]: value, selected: false }; } //__ function convertByList () { this.value = A.filter.call (this.node.childNodes, isLiTag).map (getChildNodes, this); } function convertByDl () {;} function convertByTable () {;} //__ function convert () { switch (this.node.tagName) { case 'UL' : case 'OL' : convertByList.call (this); break; case 'DL' : convertByDl.call (this); break; case 'TABLE' : convertByTable.call (this); break; } } function create (node, depth) { if (0 === arguments.length) return null; var obj = new ListFinder (node, depth); var func = new Function; convert.call (obj); func.convert = (function () { convert.apply (obj, arguments); }); func.setSelected = (function () { setSelected.apply (obj, arguments); }); func.getData = (function () { return obj.value.slice (0); }); func.select = (function () { return select.apply (obj, arguments); }); func.getSelectedNode = (function () { return getSelectedNode.apply (obj, arguments); }); return func; } ListFinder.create = create; this.ListFinder = ListFinder; })(); var finder = ListFinder.create (document.getElementById ('HOGE'),2); function find () { var doc = document; var select = doc.getElementsByTagName ('select'); var cond, value; var max, min; var mess = doc.getElementById ('NONE'); var contents = doc.getElementById ('HOGE'); finder.setSelected (true); if (value = select[0].value) finder.select ((function (v) { return (v.value[0].value.text === value); }), 'and'); if (value = select[1].value) finder.select ((function (v) { return (v.value[1].value === value); }), 'and'); if (value = select[2].value) finder.select ((function (v) { return (v.value[2].value === value); }), 'and'); if (value = select[3].value) { value = value.split (','); min = +value[0]; max = +value[1]; finder.select ((function (v) {var v = v.value[3].value.number; return (min<=v && v <max); }), 'and'); } if (value = select[4].value) finder.select ((function (v) { return (v.value[4].value.text === value); }), 'and'); if (value = select[5].value) { value = value.split (','); min = +value[0]; max = +value[1]; finder.select ((function (v) {var v = v.value[5].value.number; return (min<=v && v <max); }), 'and'); } var disp = finder.getSelectedNode (); var all = finder.getData (); all.forEach (function (d) { d.node.style.display = (this.indexOf (d.node) < 0) ? 'none': 'list-item'; }, disp); if (disp.length) { mess.style.display = 'none'; } else { mess.style.display = 'block'; } } </script> もう、めでおうだけではたいへんかもしれませんね。じぶんでもたいへん。 りすとこうぞうを、いったんおぶじぇくとにします。もんだいなのは、liようその、':' でくぎっているところ。 かってに、せいきひょうげんでぶんかつ。 find かんすうで、つくられたおぶじぇくとをそうさしています。 なんでこんなめんどうにかいているかは、もちろんべんきょうのためです。 ListFinder.create でつくったおぶじぇくとのでーたをかいへんできないようにとか・・・ table ようそとかは、つかれたのでしょうりゃくしました。
お礼
また詳しいコードを作って頂きありがとうございます。 ボタンを押して実行のみとい形ではなかったので select属性のonchange="find()"を削除し、 <img src="" alt="検索の実行" onchange="find()"> のonchangeをonclickに変更して機能しました。 性別のところで男性を選択して実行すると 男性があるのに「コンテンツがありません」とでてしまうので、 function find ()の return (v.value[2].value. === value) を return (v.value[2].value.text === value) として機能するようになりました。 >りすとこうぞうを、いったんおぶじぇくとにします。 >もんだいなのは、liようその、':' でくぎっているところ。 >かってに、せいきひょうげんでぶんかつ。 find かんすうで、 >つくられたおぶじぇくとをそうさしています。 何を言いたいのか分かりませんでしたが、 <li>の中の:を消すと機能しなくなってしまいます。 クラスの検索を除いて、他の選択では「文字:文字」を付けないと機能しないです。 2時間ほどかけてあれこれやりましたが、ダメでした。 <li>の:がプログラムを作るときに問題になるので <li>も含め中身をコード化してそれを操作する という意味だったのですね。 もちろん、その方法は勉強&活用させて頂くのですが、 もし<li>の中に:がなければ、もっと短くすんだのでしょうか。 全ての<li>に:を入れないとした場合、 find ()の中の一部を変えて、find (){~~~}だけにすれば動きますか? ヒントだけでも教えて頂きたいです。 >なんでこんなめんどうにかいているかは、もちろんべんきょうのためです。 「べんきょうのため」・・・意図的に欠陥を作ったということですか??? もしそうなら、きっちり勉強に使わせて頂くつもりなのでそうしなくても大丈夫です。 >ListFinder.create でつくったおぶじぇくとのでーたをかいへんできないようにとか・・・ これは、調べてみたのですが分かりませんでした。 これを入れると何が起きるのですか? >table ようそとかは、つかれたのでしょうりゃくしました。 tableを入れて何をしようとしていたのか気になります。
お礼
ありがとうございます。 <ul id="HOGE"> <li> <ol> <li><label>地域</label><span class="value">神奈川県</span></li> <li><label>クラス</label><span class="value">C</span></li> <li><label>性別</label><span class="value">女性</span></li> <li><label>年齢</label><span class="value">33歳</span></li> <li><label>学校名</label><span class="value">う</span></li> <li><label>体重</label><span class="value">42kg</span></li> <li><label>名前</label><span class="value">グー</span></li> </ol> </li> <li> <ol> <li><label>地域</label><span class="value">神奈川県</span></li> こんな感じにした場合に作り変えてみようと思い。 まずは、作って頂いたコードの意味を理解して、それを活用しよう。 そんなふうに意気込んで4時間、 英語を翻訳するように1つ1つの単語をネットで調べました。 任意で指定した変数名なのかどうかをコード全てを検索し変数でなければ、 ネットでその単語の使い方を調べるというやり方でやり、 部分的なことが分かったら全体的な動きを把握するつもりですが、 部分的な意味を調べるところで行き詰っています。 <span class="unit">ちゅ</span>は何だろうと思い消しちゃいました。 .querySelectorAll http://www.softel.co.jp/blogs/tech/archives/2085 .test http://www.scollabo.com/banban/jsindex/sample/sample_291.html .RegExp http://www.tohoho-web.com/js/regexp.htm#newRegExp .split (',') .splitの説明はあるが、(',')の部分の説明なし .indexOf http://www.scollabo.com/banban/jsindex/sample/sample_113.html これらはネットに説明がありましたが、 Array.prototype.filter.call(変数,実行させるもの) .ownerDocument .textContent.match Array.prototype.forEach.call this.style.display .parentNode.parentNode は見つかりませんでした。 コードの全部を作って頂けるのが一番ですが・・・ 用語辞書的なサイトはありませんか?