###前提・実現したいこと
カレント切替について相談があります。
下記サイトのjqueryを参考にグロナビのリンクにカレントクラスをつけました。
参考URL:https://d-suga.com/1935
しかし、うまくカレントされない箇所があります。
それはパラメーターで制御しているページです。
システムの仕様上、一つのファイルをパラメーターで切り替えて利用しています。
###URLの後ろにパラメーターが付いているものはカレントしない
例)
スタンダード:hoge.html←どのページを開いてもこのリストにカレントが付く
Aタイプ :hoge.html?A=1
Bタイプ :hoge.html?B=1
Cタイプ :hoge.html?C=1
この場合Aタイプ、Bタイプ、Cタイプのページを表示してもスタンダードページのリンクにカレントが付いてしまいます。
###該当のソースコード
$(function(){ $('#gNav li a').each(function(){ var $href = $(this).attr('href'); if(location.href.match($href)) { $(this).addClass('current'); } else { $(this).removeClass('current'); } }); });
###試したこと
いろいろなカレントのスクリプトを探してみましたがパラメーターに対応しているものが無いので質問させていただきました。
気になる質問をクリップする
クリップした質問は、後からいつでもMYページで確認できます。
またクリップした質問に回答があった際、通知やメールを受け取ることができます。
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。

回答1件
0
ベストアンサー
スタンダード:hoge.html
Aタイプ :hoge.html?A=1
Bタイプ :hoge.html?B=1
Cタイプ :hoge.html?C=1
ちょっと質問を勘違いしていたみたなので、回答を書き直します。
下記のような場合で、「現在hoge.htmlの時」にすべてのナビゲーションリンクでMatchしてしまうのを解決したいということでしょうか?
■現在hoge.htmlの時
ナビリンク | match() | 結果 | 一致 |
---|---|---|---|
hoge.html | location.href.match($href) | Match | 完全一致 |
hoge.html?A=1 | location.href.match($href) | Match | 前方一致 |
hoge.html?B=1 | location.href.match($href) | Match | 前方一致 |
hoge.html?C=1 | location.href.match($href) | Match | 前方一致 |
■現在hoge.html?A=1の時
ナビリンク | match() | 結果 | 一致 |
---|---|---|---|
hoge.html | location.href.match($href) | × | |
hoge.html?A=1 | location.href.match($href) | Match | 完全一致 |
hoge.html?B=1 | location.href.match($href) | × | |
hoge.html?C=1 | location.href.match($href) | × |
■現在hoge.html?B=1の時
ナビリンク | match() | 結果 | 一致 |
---|---|---|---|
hoge.html | location.href.match($href) | × | |
hoge.html?A=1 | location.href.match($href) | × | |
hoge.html?B=1 | location.href.match($href) | Match | 完全一致 |
hoge.html?C=1 | location.href.match($href) | × |
■現在hoge.html?C=1の時
ナビリンク | match() | 結果 | 一致 |
---|---|---|---|
hoge.html | location.href.match($href) | × | |
hoge.html?A=1 | location.href.match($href) | × | |
hoge.html?B=1 | location.href.match($href) | × | |
hoge.html?C=1 | location.href.match($href) | Match | 完全一致 |
正規表現で完全一致するようにします。このとき、正規表現のメタ文字をエスケープしてからRegExp()
で正規表現オブジェクトを作成します。
もうちょっとかしこい方法があるかもしれませんが、とりあえず下記でいかがでしょうか。
正規表現のメタ文字エスケープ.replace()
部分は関数にしたほうがいいかもしれません。
js
1$(function(){ 2 $('#gNav li a').each(function(){ 3 var $href = new RegExp('^'+ $(this).attr('href').replace(/([.*+?^=!:${}()|[\]\/\\])/g, "\\$1") +'$', 'i'); 4 if(location.href.match($href)) { 5 $(this).addClass('current'); 6 } else { 7 $(this).removeClass('current'); 8 } 9 }); 10});
追記
hoge.html?A=1
などのクエリストリングありの時に、マッチしないというコメントを頂いたので追記しておきます。
多分考えられる原因は、他のクエリまたはハッシュが入っているということだと思います。下記の「&他のクエリ=1#ハッシュ」がなければ、普通に完全一致します。
■ページ
http://ドメイン/hoge.html?A=1&他のクエリ=1#ハッシュ
■ナビのリンク
http://ドメイン/hoge.html?A=1
JavaScriptでURLをパースしようとすると結構めんどくさいです。今回はクエリストリングをパースできる関数を作成してからクエリストリングを比較する方針にします。
下記コードはハッシュの違いを無視します。また、相対パスは考慮していません。
js
1$(function(){ 2 function getQueryString (url) 3 { 4 if (url !== undefined && url === '') { 5 return []; 6 } 7 8 var vars = [], hash; 9 var path = url === undefined ? window.location.href : $('<a href="'+ url +'"/>').get(0).href; 10 11 if (path.indexOf('?') >= 0 && path.length != path.indexOf('?') + 1) { 12 var hashes = path.indexOf('#') >= 0 13 ? path.slice(path.indexOf('?') + 1, path.indexOf('#')).split('&') 14 : path.slice(path.indexOf('?') + 1).split('&'); 15 16 for(var i = 0; i < hashes.length; i++) { 17 hash = hashes[i].split('='); 18 vars.push(hash[0]); 19 vars[hash[0]] = hash[1]; 20 } 21 } 22 23 return vars; 24 } 25 26 function escapeRegExp (str) 27 { 28 return str.replace(/([.*+?^=!:${}()|[\]\/\\])/g, "\\$1"); 29 } 30 31 32 //現在表示ページのURLのクエリストリングをパース 33 var currentURI = location.href; 34 35 // http://ドメイン/xxx.html? 最後が?のみのURI 36 if (currentURI.length == currentURI.indexOf('?') + 1) { 37 currentURI = currentURI.replace('?', ''); 38 } 39 40 var currentQueries = getQueryString(currentURI); 41 42 // http://ドメイン/xxx.html#hash 最後がハッシュのみのURI 43 if (currentQueries.length == 0 && currentURI.indexOf('#')) { 44 currentURI = currentURI.replace(/\#.*/, ''); 45 } 46 47 //console.log(currentURI, currentQueries); 48 49 //ナビゲーションリンクからすべての.currentクラスを削除してから.currentを追加 50 $('#gNav li a') 51 .removeClass('current') 52 .each(function(){ 53 var nav = $(this).attr('href'); 54 var navQueries = getQueryString(nav); //ナビゲーションhrefのクエリストリングをパース 55 56 if (currentQueries.length > 0) { 57 for (var i = 0; i < currentQueries.length; i++) { 58 //最初のクエリストリングのみ調査 59 if ($.inArray(currentQueries[i], navQueries) >= 0 && 60 currentQueries[currentQueries[i]] == navQueries[currentQueries[i]]) 61 { 62 $(this).addClass('current'); 63 return false; //break 64 } 65 } 66 } else { 67 if (currentURI.match(new RegExp('^'+ escapeRegExp(nav) +'$', 'i'))) { 68 $(this).addClass('current'); 69 return false; //break 70 } 71 } 72 }); 73});
すべてのクエリストリングがマッチしているかを調べる場合は下記にようにすれば調べられます。
js
1 var currentFlag = false; 2 3 //ナビゲーションリンクからすべての.currentクラスを削除してから.currentを追加 4 $('#gNav li a') 5 .removeClass('current') 6 .each(function(){ 7 var nav = $(this).attr('href'); 8 var navQueries = getQueryString(nav); //ナビゲーションhrefのクエリストリングをパース 9 10 if (currentQueries.length > 0) { 11 for (var i = 0; i < currentQueries.length; i++) { 12 //すべてのクエリストリングを調査 13 if ($.inArray(currentQueries[i], navQueries) >= 0 && 14 currentQueries[currentQueries[i]] == navQueries[currentQueries[i]]) 15 { 16 currentFlag = true; 17 } else { 18 return true; //continue 19 } 20 } 21 if (currentFlag) { 22 $(this).addClass('current'); 23 return false; //break 24 } 25 } else { 26 if (currentURI.match(new RegExp('^'+ escapeRegExp(nav) +'$', 'i'))) { 27 $(this).addClass('current'); 28 return false; //break 29 } 30 } 31 });
投稿2017/09/08 07:13
編集2017/09/12 08:27総合スコア1652
あなたの回答
tips
太字
斜体
打ち消し線
見出し
引用テキストの挿入
コードの挿入
リンクの挿入
リストの挿入
番号リストの挿入
表の挿入
水平線の挿入
プレビュー
質問の解決につながる回答をしましょう。 サンプルコードなど、より具体的な説明があると質問者の理解の助けになります。 また、読む側のことを考えた、分かりやすい文章を心がけましょう。
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2017/09/11 09:09
2017/09/12 01:06 編集
2017/09/12 09:31