- ベストアンサー
input値をボタンでoutput表示する方法
- 現在公開しているホームページで、うまく作動しない箇所が見つかり対応に苦慮しています。
- 問題点を分かりやすくするために、inputした値をGoボタンでoutputに出力表示する簡単なサンプルに落とし込んでみました。
- output2の要件として、htmlが開かれた時にはinputの初期値を、Goボタンでinputを更新した時はその値を表示したいのですが、初期値のまま更新できません。
- みんなの回答 (11)
- 専門家の回答
質問者が選んだベストアンサー
一応クエリーの取り込み方を書いたサイトは 紹介しておきます。 https://www-creators.com/archives/4463 なのですが、そもそもリロードしたのに 値を維持したい?ってのが、 そもそもの間違いだと思います。 いうなればDISKをフォーマット(初期化)しても 値(データ)を維持したいと言ってるようなものなので、 なぜそれが必要なのかわかりませんが、 その地点で何かおかしい(プログラム以前)事を 感じてもらえたら、もしかしたら、無駄な努力を しなくても済むかもしれません (今回のがなぜ必要なのかが伝わってないので、どうにも判断ができないが)
その他の回答 (10)
- AsarKingChang
- ベストアンサー率46% (3467/7474)
> input1に更新値が表示される > input2は更新されず初期値が表示されたままになる ← × >ここが問題点でした。 これは、一番最初に書いた通りです。 Goでは、input2を書き換えてないので、書き変わらないのは当然です。 Goはgo() { ここの間しか実行はされない } その後に続く命令は、起動時に一度しか見られてません。 書き換えたいならGoに含むことで、治ります。 ただし、それでは、input1とinput2が完全に同じタイミングでしか 更新されないフローになるため、2個ある意味がなくなりますね。 なので、1個にしたのが、一番最初の投稿でした。
お礼
なんだか頭の中が堂々巡りになって申し訳ないです。 結局のところ、解決策はhtml自体を書き換えるクエリーストリングのような方法しかないということでしょうか。 せっかくご提案いただいた内容なのでその方法を理解しようとしていますが難航しています。 この方法はサンプルモデルinput-output.htmlのinput値とするvの値を別のabc.htmlのクリエ文字列から読み出してオーバーライドすることと理解しましたがそれで合っていますでしょうか。 また「INPUTの初期値としてオーバーライド」とありますが、これはいわゆる初期値valueのことでしょうか、それともinput値とする変数でしょうか。 といった感じで、input-output.htmlとabc.htmlの基本的な関係が理解できていませんので、まずそこから教えていただけないでしょうか。 まずそこを理解しないと、トンチンカンな質問ばかりになってしまうと思います。 お手数をお掛けしますがよろしくお願い致します。
- AsarKingChang
- ベストアンサー率46% (3467/7474)
どうしても?ということなら、手はあると思います。 reloadではなく、「同じページ」にパラメーター付きで 再読み込み(リロードではない)をする手はあるかもです。 なので、 abc.html?v=ここに値を入れたURLへジャンプ =JavaScriptでv=?ここを読み出す(クエリーストリングと言います) それを、INPUTの初期値としてオーバーライド。 これで、行けると思います。 ただ、そこまでする必要がある要件なのかは、 わかりませんが。
お礼
ご回答ありがとうございます。 reloadの話を持ち出してしまったのが問題を複雑にしたようで申し訳ありません。 原点に返って最初のサンプルで問題点を整理すると、 html読み込み go()が呼び出される input1に初期値が表示される input2に初期値が表示される 更新値を入力する Goボタンをクリックする go()が呼び出される input1に更新値が表示される input2は更新されず初期値が表示されたままになる ← × ここが問題点でした。 やはり基本的な部分で問題を解決しないといけませんよね。 なんだか、問題の焦点がぼやけてしまったようです。 一旦、この質問は締め切って、別質問として挙げ直した方がいいでしょうか。 ただ、その場合には、なぜoutput2が必要かという説明にまた苦慮しそうですが・・・
補足
クエリーストリングの内容を理解しようとしていますが、難航しています。 もう少し考えてみて質問事項をまとめてお送りします。 申し訳ありませんがよろしくお願いします。
- AsarKingChang
- ベストアンサー率46% (3467/7474)
>これって、input要素の入力値がreloadにより消えることと同じでは・・・ >PHPとなると使用したこともないのでさらに敷居が高くなりますが、解決策のヒントにはならないでしょうか。 reloadで、消えるのは正常です。 むしろ消えない方がおかしいほどです。 受け渡しを目的としてるなら、GET/POSTを取り込んで、 <input type="number" id="input" value="100"> これの、100を置き換えなければなりません。 なぜなら、これは、「初期値を100にしろ」 なので、100以外になる方が、以上動作という事なので。 なので、Edge(というかChromium)が正しい動作 かもしれませんね。 なおPHPの場合は value="<?= $_GET["waa"]; ?>" value="<?= $_POST["waa"]; ?>" <?=は<?php echo の略式 これだけで、初期値の動的配置はできます。 やっぱり、何か前提となる条件が違う可能性がありますね。
お礼
参照した記事の中ではinputの初期値valueが例になっていますが、本件の場合は初期値ではなくgo()で入力したinput値そのものを残しておき、reloadの際にその値で再描画するイメージです。 記事にも「普通にHTMLのinput要素などを書くと・・・」とあるのでinput要素に関する情報がreloadで消えるのは正常だと思います。 今回は普通ではできないことをやっている、つまり前提となる条件が普通ではないということではないでしょうか。 それにしてもなぜFirefoxではできるのでしょうかね。 サンプルのscriptで言うと//の部分の追加になり、これをPHPなどで記述できないかと考えています。 私の環境でPHPをインストールしてみましたが、どこかやり方が間違っているらしくまだ動かすことができません。 また明日(日曜日)落ち着いてやってみることにします。 <script> var input; go(); function go() { input= document.getElementById("input").value; var output = document.getElementById("output1"); output.value = input; //送信した値をinput値として残す(PHP等で書く部分) //var element = document.getElementById("input"); //element.value = input; } var output = document.getElementById("output2"); output.value = input; </script>
補足
PHPは私には手に負えないようですし、最終的にサーバーの仕様にも依存しそうなので、やはりjavascriptの範囲で考えたいと思います。 (早々に匙を投げました) ひとつ、location.reload()に関して、以下の記事を見つけました。 https://developer.mozilla.org/ja/docs/Web/API/Location/reload やはり、Firefoxだけが特別のようなようですね。 「Firefox は標準外の論理値の forceGet 引数 を location.reload() で対応しており、 Firefox にキャッシュをバイパスして現在の文書を強制的に再読み込みするように指示することができます。・・・・」 なんとなく言っていることは分かりますが、問題解決のヒントになるのでしょうか。 それとも、諦めろということですかね。
- AsarKingChang
- ベストアンサー率46% (3467/7474)
>その場合ホームページ内のカレンダーがうまく表示されなくなることが分かっています。詳しい理由は分かりません。 恐らく、それ以外の書かれてない条件が、 何か悪さしている気がしますよ。 という事で、何か前提条件があるというか、 書かれていることと何か違うことをしているのか? 本日も検証してみましたが。。 <script> function getInput() { return document.getElementById("input").value; } function setOutput1(val) { document.getElementById("output1").value = val; } function setOutput2(val) { document.getElementById("output2").value = val; } function updateOutput1() { setOutput1(getInput()); } function updateOutput2() { setOutput2(getInput()); } onload = function() { updateOutput1(); updateOutput2(); } </script></head> <body> <p> <label for="input">input</label> <input type="number" id="input" value="100"> </p> <p> <input type="button" onclick="updateOutput1();" value="Go"> </p> <p> <label for="output1">output1</label> <input type="text" id="output1"> </p> <p> <label for="output2">output2</label> <input type="text" id="output2"> </p> </body> こんな短いソースで問題が出るとは、思えず。。。 (全部1行のみで記載→デバッガーで調査しやすくするため) ちゃんと動いてますね。。 これ以外の要素が絡んでいるとしか思えませんで。
お礼
ご確認いただきありがとうございます。 ところで、そちらで使用されているブラウザと私のサンプルを流した場合の結果はどうなっていますでしょうか。 やはりoutput2の出力表示はうまくいかないのでしょうか。 あと、ググっていたらこのような記事がありました。 http://taustation.com/php-template-keeping-form-inputs/ 「普通にHTMLのinput要素などを書くと、GETやPOSTのたびにそれらがvalueなしで描きなおされるので、内容が空になる。」 これって、input要素の入力値がreloadにより消えることと同じでは・・・ PHPとなると使用したこともないのでさらに敷居が高くなりますが、解決策のヒントにはならないでしょうか。
- AsarKingChang
- ベストアンサー率46% (3467/7474)
う~ん、あってる気がするな~。。 書き方的には、あってる気がしますね(実際には試してないが) いきなり、onloadって書いてるものの、 この時点でのthisポインタは、windowなので、 window.onload=。。。になってるので、 間違ってない気が。。 後で、こっちでも、試してはみますが、 なんとなく、依存性が高い部分を別のやり方に変えたほうが、 解決自体は早いかもしれないですね。 問題点は別にあったことは分かったものの。
お礼
ありがとうございます。 あと、この方法だと最終的にホームページ本体のjsをfunction(){}内に記述することになり、その場合ホームページ内のカレンダーがうまく表示されなくなることが分かっています。詳しい理由は分かりません。 なので、output2はあくまでfunctionの外にある必要があり、それが今回の質問の前提要件になっています。 output2の領域ではホームページが正常に表示、作動します。Firefoxの場合になりますが。 お手数をお掛けしますが、引き続きアドバイスいただけると助かります。
- AsarKingChang
- ベストアンサー率46% (3467/7474)
”onloadにフックする” これいろいろな、用語がありますが、 主にリスナーと言われて、イベントが発生したら 例えば、マウスを動かした、ボタンを押した! などで、割り込まれる場所を登録しておくことで、 タイミングが関係するものを解決する機能になります。 イベントを設定するだとか、フックするだとか、 リスナーを配置とか、いろいろ言い回しがありますが。 今書かれているソースを、onload=このパラメータが関数です。 <input type="button" onclick="go();" value="Go"> ちなみこれも、 IDがないので、その時点でセットされてますが。 <input type="button" onclick="go();" value="Go" id=aiueo> だとすると、 document.getElementById("aiueo").ここ!! ってのを、IDなしでやっただけ。 document.getElementById("aiueo").onclick="go();" document.getElementById("aiueo").onmouseover="waaa();" なんてかけば、その要素をマウスが通過するだけで、 waaa()が呼ばれます。 (今の質問者さんの質問とはあまり関係はないのですが、 それをやってるだけですよ!ってだけのことでして) なぜそれを言うかというと、そのうちハマる日が来るでしょうから DOMで動的にHTMLを作ると、動かなくなるソースに いずれぶつかるので、そういう時は、↑で書いたみたいな、 プログラム側でリスナーを設定するのを思い出してくださいね!。 (いつか、必ず役に立ちます) あと、THISポインターを継承したいとき、それ自体が 別のTHISポインターだったとか、内包メソッドだった場合 (つまり外から見えないメンバーなどがある場合) HTMLでの on????? が設定できないのですよ!。 そんなときも、メソッド直接の代入に、bind..するだけで、 別のメモリ空間でリスナーを作れて、結構便利! (ここまで、やるかは、別ですが^^) ひとまず、 onload に反応して発火する(実行するという意味)に 変更してみてください!。 恐らくは解決すると思いますよ。 ブラウザによって、HTMLが先かJSが先か?って 依存性を確実にするなら、それが一番ですので。
お礼
いろいろとアドバイスをいただきありがとうございます。 本来なら基礎から学ばないといけないことは分かっていますが、今となっては遅い気がします。 とりあえず、scriptを以下のように書き換えて実行してみましたが、やはりFirefoxはOK、EdgeはNGとなり結果は変わりませんでした。 これでは"onloadにフック"したことになっていないのでしょうか。 <script> onload = function() { var input; go(); function go() { input= document.getElementById("input").value; var output = document.getElementById("output1"); output.value = input; } var output = document.getElementById("output2"); output.value = input; } </script>
- AsarKingChang
- ベストアンサー率46% (3467/7474)
>reload時のことではなくonload時のことをおっしゃっているという理解でよろしいですか。 ある意味似てます。 reloadでページが読み直されて、 読み直しが終わった瞬間のタイミングが、onloadですね。 HTMLなどを読み込んでる最中に、実行されると まずいケースで、よく使いますよ。 (実際のところほぼ全部のサイトがそうなってると思っていいです) Jqueryなどでは、専用の書き方がありますが、 生のJavaScriptでは、onloadで記載するのが、普通ですね。
お礼
ご回答ありがとうございます。 自分でも少し考えてみました。 検討に使用したのは、 <input type="button" onclick="go();" value="Go"> の一行のみを <input type="button" onclick="location.reload();" value="Go"> に変更したサンプルです。 このサンプルを実行すると、 Firefoxでは読み込み時には初期値が表示され、数値を変更してGoボタンをクリックした時には変更値が表示されます。 Edgeでは読み込み時には初期値が表示されますが、数値を変更してGoボタンをクリックした時には初期値が表示されてしまいます。 alert文などを入れて処理状況を確認すると、Edgeの場合Goボタンを押してreloadを行なう際に画面が一瞬真っ白になりその後初期値のままの画面が再表示されます。 これが、reloadからonloadの際に起こっている現象と理解しました。 また、ホームページ自体のjsには関係のない問題で、このサンプルの範囲でEdgeでも正常に作動するように”onloadにフックする”ことを考えればよいということでしょうか。 また、それはhtmlの要素や値を保持するといったイメージで合っていますか。 よろしくお願いします。 <html> <head> <title>input-output</title> </head> <body> <p> <label for="input">input</label> <input type="number" id="input" value="100"> </p> <p> <input type="button" onclick="location.reload();" value="Go"> </p> <p> <label for="output1">output1</label> <input type="text" id="output1"> </p> <p> <label for="output2">output2</label> <input type="text" id="output2"> </p> <script> var input; go(); function go() { input= document.getElementById("input").value; var output = document.getElementById("output1"); output.value = input; } var output = document.getElementById("output2"); output.value = input; </script> </body> </html>
- AsarKingChang
- ベストアンサー率46% (3467/7474)
思うに、onloadにフックすれば治ると思います。 JavaScriptがページの読み込み中に実行されたりすると、 妙な動作をすることがあり、裏でElement分解してる最中に JSが流れたりすると、おかしい?ってことはあるかもしれません。 https://www.sejuku.net/blog/19754 ↑今回書いた件の関連記事
お礼
アドバイスいただきありがとうございます。 ただ、参照記事も見てみましたが素人の私には"onloadにフックする"の意味が分かりそうにありません。 reload時のことではなくonload時のことをおっしゃっているという理解でよろしいですか。 いずれにしましてももう少し詳しく教えていただけると助かります。
- AsarKingChang
- ベストアンサー率46% (3467/7474)
1つ修正、1回目にoutput2は、確かに値が入りますね。 inputがgo()の外スコープだったようです。 ただ、回答としては、それほど違いはなくて、Goを押すたびに 変わるなら、そもそも、output2は、いらないと思いますがね。 output1とoutput2に用途的な違いがないので、 どっちかだけにするだけで、基本的に問題解決すると 思いますがね。 (ソース書いてみればわかりますよ。結局、同じになるはずですから)
- AsarKingChang
- ベストアンサー率46% (3467/7474)
2つの問題。 まず1つ目「呼ばれてない」 <script> 先命令→この位置はページが起動した瞬間1回しか呼ばれない function go() { } 後命令→この位置はページが起動した瞬間1回しか呼ばれない var output = document.getElementById("output2"); output.value = input; なので、この記載は事実上意味がない。 </script> 2つ目の問題 input= document.getElementById("input").value; この変数の代入はgoでしか行われていないので、 先に実行してしまう、output2への代入時は、 値が不定「var input;」ここに値がないため。 なので、この2つを治せばOK <script> function go() { let input= document.getElementById("input").value; let output = document.getElementById("output2"); output.value = input; ↑面倒なら、 document.getElementById("output2").value=document.getElementById("input").value; のみでもOK } /* 最初の1回目は、今現在inputの値をoutput2に入れる */ go(); </script> output1がなくなっているが、 そもそも、呼ばれなければ変わらないので、 記載する意味はほぼない
お礼
ご回答ありがとうございます。 じつは現状のホームページの中では、 <input type="button" onclick="go();" value="Go"> の一行が、 <input type="button" onclick="location.reload();" value="Go"> となっています。 ページが起動した瞬間に1回しか呼ばれない先命令や後命令の部分(output2の領域)にホームページ用のjsが記述されていて、Goボタンが押された時もその部分が実行されるようにreloadで再表示させているということになります。 Firefoxで確認したところ初期表示もGoボタンクリック時の表示もうまくいったので素人考えでそのようにしていたのですが、最近になってEdgeだとうまくいかないことが判明しました。 そこで、今回のような質問をしているというのが経緯になります。 ブラウザ依存のあるreloadという方法をとらずに何かいい解決策はありますでしょうか。
お礼
おそらくホームページのカレンダーの表示機能に関するjs記述部をfunction内に括れないことが原因で、それが前提要件となっているためにこのようなreloadの問題が生じるものと理解しています。 切り出したサンプルモデルでご理解いただくのは難しいと思います。 クエリーに関しては自信で努力してみます。 いろいろとアドバイスいただきありがとうございました。