質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.50%
パラメータ

関数やプログラム実行時に与える設定値をパラメータと呼びます。

jQuery

jQueryは、JavaScriptライブラリのひとつです。 簡単な記述で、JavaScriptコードを実行できるように設計されています。 2006年1月に、ジョン・レシグが発表しました。 jQueryは独特の記述法を用いており、機能のほとんどは「$関数」や「jQueryオブジェクト」のメソッドとして定義されています。

Q&A

解決済

1回答

6826閲覧

グロナビのリンクがパラメーター付きURLの場合にクラスカレントを正常に動作させたい

hogeta

総合スコア5

パラメータ

関数やプログラム実行時に与える設定値をパラメータと呼びます。

jQuery

jQueryは、JavaScriptライブラリのひとつです。 簡単な記述で、JavaScriptコードを実行できるように設計されています。 2006年1月に、ジョン・レシグが発表しました。 jQueryは独特の記述法を用いており、機能のほとんどは「$関数」や「jQueryオブジェクト」のメソッドとして定義されています。

0グッド

0クリップ

投稿2017/09/08 06:24

###前提・実現したいこと
カレント切替について相談があります。
下記サイトの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ページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答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.htmllocation.href.match($href)Match完全一致
hoge.html?A=1location.href.match($href)Match前方一致
hoge.html?B=1location.href.match($href)Match前方一致
hoge.html?C=1location.href.match($href)Match前方一致

■現在hoge.html?A=1の時

ナビリンクmatch()結果一致
hoge.htmllocation.href.match($href)× 
hoge.html?A=1location.href.match($href)Match完全一致
hoge.html?B=1location.href.match($href)× 
hoge.html?C=1location.href.match($href)× 

■現在hoge.html?B=1の時

ナビリンクmatch()結果一致
hoge.htmllocation.href.match($href)× 
hoge.html?A=1location.href.match($href)× 
hoge.html?B=1location.href.match($href)Match完全一致
hoge.html?C=1location.href.match($href)× 

■現在hoge.html?C=1の時

ナビリンクmatch()結果一致
hoge.htmllocation.href.match($href)× 
hoge.html?A=1location.href.match($href)× 
hoge.html?B=1location.href.match($href)× 
hoge.html?C=1location.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
Tomak

総合スコア1652

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

hogeta

2017/09/11 09:09

お返事が遅くなり申し訳ありません。こちらのプログラムを試させていただきましたが、うまくいきませんでした。もう少し私の方でも調べてみたいと思います。 ご回答ありがとうございました。
hogeta

2017/09/12 01:06 編集

追加のお回答ありがとうございます。 >>「現在hoge.htmlの時」にすべてのナビゲーションリンクでMatchしてしまうのを解決したいということでしょうか? そのとおりです!今まではhoge.htmlにアクセスした時に他ページのリンクもカレントされてしまいました。このスクリプトを導入したらこの現象は解決できました。ありがとうございます。 あとは ・現在hoge.html?A=1の時 ・現在hoge.html?B=1の時 ・現在hoge.html?C=1の時 に各リンクがカレントすると完璧なんですが・・・。 パラメータが付いた部分はif文を使い分岐処理した方がいいのでしょうか。 if(document.URL.match("A=1")) { $('#gNav li a[href*="A=1"]').addClass('current'); } 初心者の私にもわかりやすく教えていただきありがとうございます。 正規表現などまだまだ勉強しなければいけないことが多いので大変勉強になりました。 丁寧なご回答ありがとうございます。
hogeta

2017/09/12 09:31

ありがとうございます。無事に実装することができました。 プログラムはおくが深いです。 何度も修正していただきありがとうございます。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.50%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問