人力検索はてな
モバイル版を表示しています。PC版はこちら
i-mobile

javascriptで反転スイッチを作りました。
スイッチを押すと、true・falseが入れ替わります。
試しに、alertで文字を表示させてみて、それぞれちゃんとスイッチが切り替わっているのを書くにできたのですが trueと、falseのときに、それぞれ別のURLに飛ばしたいのですが
うまいきません。 (URLの後に?をつけてオプションを切り替えたい)
原因を教えて下さい。

以下はサンプルコード
//フラグ入れ替え
flag1 = false;
function toggle(){
flag1 = !flag1;
document.getElementById("switch").value = flag1;
if(flag1 == true){location.href='index.html?1'};
if(flag1 == false){location.href='index.html?2'};
}

●質問者: kajironpu
●カテゴリ:ウェブ制作
○ 状態 :終了
└ 回答数 : 1/1件

▽最新の回答へ

1 ● a-kuma3
ベストアンサー

この javascript が書かれているのが index.html なのですよね?
location.href を入れ替えるとページを再読み込みします。
javascript は、もう一度 先頭から解釈されて

flag1 = false;

この処理も実行されます。

  1. index.html を読み込む
  2. flag1 は false
  3. ボタンを押す
  4. toggle 関数が呼ばれて flag1 が反転し、flag1 は true になる
  5. location.href に 'index.html?1' が代入され、index.html が再表示される
  6. javascript が、また解釈されるので flag1 は false になる

という感じになってます。
ページが遷移する前のことは、覚えていられないんです。

flag1 が true で表示されたか、false で表示されたかは URL の末尾が "?1" か "?2" かで判定できます。
この部分は location.search で取得できます。

元のコードをなるべくそのままにして、期待通りの動作をするようにしたのがこちらです。


flag1 = location.search == "?1"; // ★パラメータから、呼び出し元の flag1 を判断する

//フラグ入れ替え
function toggle(){
 flag1 = !flag1;
 document.getElementById("switch").value = flag1;
 if(flag1 == true){location.href='aah.html?1'};
 if(flag1 == false){location.href='aah.html?2'};
} 

id="switch" の要素は、flag1 の値が入ってる、という想定でしょうか。
上記のままだと、切り替えボタンを押さないと値が入りません。
後、論理型の変数の値を調べるのに、false と比較するのは気持ち悪い、とか思ったりします。

あまり変わってませんが、こんな感じになるかと。


var flag1 = location.search == "?1"; // ★パラメータから、呼び出し元の flag1 を判断する
window.onload = function() {
 document.getElementById("switch").value = flag1;
};

//フラグ入れ替え
function toggle(){
 flag1 = !flag1;
 document.getElementById("switch").value = flag1;
 if (flag1) {
 location.href='aah.html?1';
 } else {
 location.href='aah.html?2';
 };
} 




追記です。

回答のコメントで聞かれていることは、二つの課題があります。

  1. 画面の読み直しをせずに、ボタンの内容を書き換えたい
  2. 画面の再読み込みをしても、前の状態を反映させたい

まず、ひとつめの課題。
2回目の質問のときに、配列の内容をボタンとして表示することはできていました。
これの応用です。
あのときは、何もないところにボタンを追加していましたが、書き換えるときには、一旦 ボタンを消してからボタンを追加すれば良いんです。
日本語と英語の切り替えも含めて、こんな感じになります。

<script>
function displayButton(labelArray) {
 var dest = document.getElementById("button-area");

 // clear button
 dest.innerHTML = "";

 // draw button
 for (var i = 0 ; i < labelArray.length ; ++i) {
 var b = document.createElement("button");
 b.id = "word_option_" + i;
 b.innerHTML = labelArray[i];
 dest.appendChild(b);
 }
}

var isEnglish = false;
var englishArray = ["car" , "apple", "box", "dinner", "eagle", "fox"];
var japaneseArray = ["自動車" , "りんご", "箱", "夕食", "鷹", "狐"];
var answerArray = isEnglish ? englishArray : japaneseArray;

window.onload = function() {
 displayButton(answerArray);
};

function toggle() {
 isEnglish = ! isEnglish;
 answerArray = isEnglish ? englishArray : japaneseArray;
 displayButton(answerArray);
}

</script>

<body>
<div id="button-area"></div>
<button onclick="toggle()">切り替え</button>
</body>



次。ふたつ目の課題です。
ページの reload をしても前の値を使いたいときがあります。
例えば、前にログインしていた状態を覚えておくとか。

そういうときに使うのは cookie(クッキー)です。

さっきのコードで、英語かどうかの初期値をソースに埋め込むのではなくて、cookie から読みだすようにしたのが以下のコードです。

<script>
function displayButton(labelArray) {
 var dest = document.getElementById("button-area");

 // clear button
 dest.innerHTML = "";

 // draw button
 for (var i = 0 ; i < labelArray.length ; ++i) {
 var b = document.createElement("button");
 b.id = "word_option_" + i;
 b.innerHTML = labelArray[i];
 dest.appendChild(b);
 }
}

// ★cookie に保存
function saveMode(mode) {
 document.cookie = "isEnglish=" + (mode ? "Yes" : "No");
}

// ★cookie から読み出し
function loadMode() {
 var mode = false; // cookie に保存されてなかったら、日本語モード
 var matches = /isEnglish=(Yes|No)/.exec(document.cookie);
 if (matches) {
 mode = matches[1] == "Yes";
 }
 return mode;
}

var isEnglish = loadMode(); // ★cookie から初期値を取得
var englishArray = ["car" , "apple", "box", "dinner", "eagle", "fox"];
var japaneseArray = ["自動車" , "りんご", "箱", "夕食", "鷹", "狐"];
var answerArray = isEnglish ? englishArray : japaneseArray;

window.onload = function() {
 displayButton(answerArray);
};

function toggle() {
 isEnglish = ! isEnglish;
 saveMode(isEnglish); // ★cookie に保存しておく
 answerArray = isEnglish ? englishArray : japaneseArray;
 displayButton(answerArray);
}

</script>

<body>
<div id="button-area"></div>
<button onclick="toggle()">切り替え</button>
</body>


cookie に関するリファレンスです。気が向いたら読んでみてください。
document.cookie - Web API インターフェイス | MDN


kajironpuさんのコメント
さっそくありがとうございます。ページが遷移すると、データが空になるのですね。おかげ様で無事成功しました。 また1つ問題がありまして(この場で追加で質問しても問題ないでしょうか?もしくは別の質問枠で出すべきでしょうか?) 今、 var englishArray =["apple","orange","tomato"] var japaneseArray =["りんご","オレンジ","トマト"] と定義しているのですが、このトグルスイッチを押すと 画面を読み込みなおして、スクリプトの最初に戻って日本語と英語を逆に切り替えたいと模索中です。 if (flag1) {var englishArray =["apple","orange","tomato"] var japaneseArray =["りんご","オレンジ","トマト"]} else { var japaneseArray =["apple","orange","tomato"] var englishArray =["りんご","オレンジ","トマト"] } とも考えたのですが、ちょっとイレギュラーな感じがします。 あるいは、先ほどの location.href='aah.html?1'; のかわりに、この場所に if (flag1) {ここにenglishArrayとjapaneseArrayを入れ替えるコードを入れる} このようなやり方は正しいでしょうか? englishArrayと japaneseArrayの変数を入れ替える方法は // 作業用変数を使った交換 tmp = a; a = b; b = tmp; このやり方がオーソドックスでしょうか?

a-kuma3さんのコメント
見た目の英語と日本語が切り替わるのではなく、英語の値が入った配列と日本語の配列を入れ替えるのですか? 入れ替えるだけであれば >|| tmp = a; a = b; b = tmp; ||< で良いと思いますが、englishArray の中身が日本語になってるのはちょっと気持ち悪い感じはしますね。 変数の命名だけではあるんですが。

kajironpuさんのコメント
ありがとうございます。そうなんです。englishArrayとjapaneseArrayを入れ替えたいのですが、英語から日本語をスイッチを押して、そっくりそのまま逆にして、日本語から英語というふうにしたいと考えています。 URLプションにenglishの文字があるときは、englishArrayで、URLにjapaneseがあるときはenglishArrayの中身がそっくりjapaneseArrayになれば、そのままプログラムを変えないでもそっくり使えるかなと考えました。

a-kuma3さんのコメント
英訳もしくは和訳クイズみたいな感じ、ってことですよね。 入れ替えるんじゃなくて、値を使っているところでは<span style="color:red;">値の意味</span>を表す変数名にしておいて、その初期化を日本語でするか、英語でするか、というふうにするのが良いんじゃないでしょうか。 例えば、質問と答えという意味で使うのであれば... >|javascript| var isEnglish = location.search == "?english"; var japaneseArray = [ ... ]; // 日本語の単語 var englishArray = [ ... ]; // 英語の単語 var questionArray, answerArray; if (isEnglish) { questionArray = englishArray; answerArray = japaneseArray; } else { questionArray = japaneseArray; answerArray = englishArray; } // これ以降は、questionArray と answerArray を使う ||<

kajironpuさんのコメント
ありがとうございます! 完璧です。とても分かりやすいです。 おかげ様で、なんとか出来上がりそうです。m(__)m 英単語<ー>日本語 を切り替えて選択問題クイズを作成中です

kajironpuさんのコメント
いつもありがとうございます。質問ばかりで申し訳ありません。 その後、いろいろ検討してURLの切り替えなしで、そのままflagの判定で、englisharray とquestionarrayを切り替えることを考えました。 トグルスイッチは、true/falseの切り替えとしてそのまま使いたいのですがURLの変更なしいく場合のフラグの使い方のアイデアが思い浮かびません。 スイッチ切り替え(toggle)でフラグ条件を変えるとしたら、再度画面をreloadさせてしまうとやはりフラグの中身が消えてしまうし、URLの変更なしでいくにはどうしたらいいのでしょうか? if文で、englisharrayとjapanesearrayを入れ替えたあと、新しい設定を有効にするために再度 画面を読み込み直す(reload()などで)やはりデフォルトのフラグ設定(true)に戻ってしまうので、englisharrayとjapanesearrayが切り替わりません。URLから文字を読み取ってflagを変更するやり方以外で、トグルスイッチと組み合わせるアイデアはどのようなものがありますでしょうか。

a-kuma3さんのコメント
長い文章は、回答のコメントだとプレビューがなくて辛いので、回答に追記しました。 >> 質問ばかりで申し訳ありません。 << Q &amp; A サイトなのですから、質問者は質問するのが普通です <tt>:-)</tt>

kajironpuさんのコメント
ありがとうございます。なんとかうまくいきました。 クッキーははじめて使いました。じっくり勉強したいと思います。 最終的には、ボタンの書き換えは行わず、クッキーを読み込んでenglisharray とjapanesearrayをフラグ判定してquestionとanswerarrayにそれぞれを分けました。そしてトグルを押したときに、一度reloadさせて再度データを読み込ませ成功。 ただ、ボタンにランダムに単語をいれたあとに、なぜかボタンを押したときの解答と一致しない問題が発生し、かなりはまりましたが、結局クッキーにデータが保存されて、配列がバラバラになったままだったのが問題のようでしたので、フラグがtrue/falseで区別して、毎回新しいデータを読み込むようにしたら無事成功しました。自分でやっているうちに、どんどん複雑になり、途中何がなんだかわからなくなりましたが、おかげ様とても勉強になりました。どうもありがとうございました。
関連質問

●質問をもっと探す●



0.人力検索はてなトップ
8.このページを友達に紹介
9.このページの先頭へ
対応機種一覧
お問い合わせ
ヘルプ/お知らせ
ログイン
無料ユーザー登録
はてなトップ