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

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

新規登録して質問してみよう
ただいま回答率
85.48%
PHP

PHPは、Webサイト構築に特化して開発されたプログラミング言語です。大きな特徴のひとつは、HTMLに直接プログラムを埋め込むことができるという点です。PHPを用いることで、HTMLを動的コンテンツとして出力できます。HTMLがそのままブラウザに表示されるのに対し、PHPプログラムはサーバ側で実行された結果がブラウザに表示されるため、PHPスクリプトは「サーバサイドスクリプト」と呼ばれています。

JavaScript

JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。

jQuery

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

Ajax

Ajaxとは、Webブラウザ内で搭載されているJavaScriptのHTTP通信機能を使って非同期通信を利用し、インターフェイスの構築などを行う技術の総称です。XMLドキュメントを指定したURLから読み込み、画面描画やユーザの操作などと並行してサーバと非同期に通信するWebアプリケーションを実現することができます。

HTML

HTMLとは、ウェブ上の文書を記述・作成するためのマークアップ言語のことです。文章の中に記述することで、文書の論理構造などを設定することができます。ハイパーリンクを設定できるハイパーテキストであり、画像・リスト・表などのデータファイルをリンクする情報に結びつけて情報を整理します。現在あるネットワーク上のほとんどのウェブページはHTMLで作成されています。

Q&A

解決済

3回答

6532閲覧

Ajaxを使うとsetTimeout処理がうまくいかない

k499778

総合スコア599

PHP

PHPは、Webサイト構築に特化して開発されたプログラミング言語です。大きな特徴のひとつは、HTMLに直接プログラムを埋め込むことができるという点です。PHPを用いることで、HTMLを動的コンテンツとして出力できます。HTMLがそのままブラウザに表示されるのに対し、PHPプログラムはサーバ側で実行された結果がブラウザに表示されるため、PHPスクリプトは「サーバサイドスクリプト」と呼ばれています。

JavaScript

JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。

jQuery

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

Ajax

Ajaxとは、Webブラウザ内で搭載されているJavaScriptのHTTP通信機能を使って非同期通信を利用し、インターフェイスの構築などを行う技術の総称です。XMLドキュメントを指定したURLから読み込み、画面描画やユーザの操作などと並行してサーバと非同期に通信するWebアプリケーションを実現することができます。

HTML

HTMLとは、ウェブ上の文書を記述・作成するためのマークアップ言語のことです。文章の中に記述することで、文書の論理構造などを設定することができます。ハイパーリンクを設定できるハイパーテキストであり、画像・リスト・表などのデータファイルをリンクする情報に結びつけて情報を整理します。現在あるネットワーク上のほとんどのウェブページはHTMLで作成されています。

0グッド

0クリップ

投稿2016/04/22 20:24

編集2016/04/22 20:31

前回の投稿の続きになります。
setTimeoutとボタン押下の処理がうまくいかない
ajaxがうまくいかない

現在cakePHP3,PHP,HTML(ctp),JavaScript(jQuery)を使ってアプリ開発をしています。

テキストボックスに入力すると、その0.5秒後に赤になり、ボタン押下時に必ずBoxが青になるというものです。
ボタン押下時はテキストボックスをクリアしているので、テキストボックスが空の時は必ず青になる想定です。

画面 テキストボックス入力時↓
イメージ説明

画面 ボタン押下時↓
イメージ説明

前回の投稿では、「青を表示」ボタン押下時にclearTimeoutをすることで、ボタン押下時は必ず青にすることができました。

ただ今回Ajax処理を導入したことで、ときどきボタン押下後に赤になるケースが出てきました。
テキストボックス入力後、0.5秒経つギリギリ前のタイミングでボタン押下するとなりやすいです。

質問内容としては、
この赤になるケースの原因を解決し、ボタン押下時に必ず青にするにはどうしたらいいか知りたい。
というものです。

コードは以下になります。

settimeout.ctp

HTML

1 2<!DOCTYPE html> 3<html> 4<head> 5<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script> 6<style> 7.box1{ 8 width: 150px; 9 height: 150px; 10 background-color: aqua; 11 margin-top: 20px; 12} 13.box2{ 14 width: 150px; 15 height: 150px; 16 background-color: red; 17 margin-top: 20px; 18 display: none; 19} 20</style> 21</head> 22<body> 23<br> 24<input type="text" id="text" oninput="red(this)"> 25<input type="button" id="aqua" value="青を表示"> 26<div class="box1"></div> 27<div class="box2"></div> 28</body> 29<script> 30// ボタン押下時、「青」に変える 31var timer = false; 32$("#aqua").click(function(){ 33 if (timer !== false) { 34 clearTimeout(timer); 35 } 36 $('div.box1').show(); 37 $('div.box2').hide(); 38 $('#text').val(''); 39 40}); 41 42// 「赤」に変える。oninput処理を何度も走らせないため1秒後に実行 43function red(_this){ 44 if (timer !== false) { 45 clearTimeout(timer); 46 } 47 timer = setTimeout(function(){ 48 49 $.ajax({ 50 url: "http://localhost/cakephp3/Sample/blue", 51 }).done(function(){ 52 53 $('div.box1').hide(); 54 $('div.box2').show(); 55 console.log(_this.value); 56 57 }).fail(function(){ 58 console.log('error!!!'); 59 }); 60 },500); 61} 62 63// ボタンを押した時、常に「青」になるようにしたい。 64// 現状テキストボックス入力後、0.5秒経つギリギリ前のタイミングでボタンを押すと、「赤」になるケースが出てくる 65// 秒数やsetTimeoutの処理は維持し、ただボタン押下時は常に青になるようにしたい 66 67</script> 68</html> 69

SampleController.php

PHP

1<?php 2namespace App\Controller; 3 4use App\Controller\AppController; 5 6class SampleController extends AppController 7{ 8 9 //初期表示で呼ばれるアクション 10 public function setTimeout() 11 { 12 13 } 14 15 //Ajaxで呼ばれるアクション 16 public function blue() 17 { 18 $this->autoRender =false; 19 20 } 21}

ボタン押下時にclearTimeout(timer);で赤にするsetTimeoutの処理を止めているつもりなのですが、
Ajaxが非同期だからかなのか原因は明確にはわかっていませんが、赤にする処理も走ってしまうことがあるようです。

AjaxsetTimeout処理内に書いているので、ボタン押下時のclearTimeout(timer);でAjax処理も防げると思っていたのですが。

もしこの問題の原因や解決策がわかる方がいらっしゃいましたら教えていただけるとありがたいです。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

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

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

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

guest

回答3

0

ベストアンサー

oninput処理を何度も走らせないため

という目的のために setTimeout を使っていること自体が、ちょっとスジがよくないな、と思うのですが、「入力があって 0.5 秒後に ajax のリクエストを飛ばしたい」というの目的なのであれば、それはそれで仕方がありませんが、それは「スジの悪さ」が実装から設計に移っただけかな、という気もします。

というのは余計なお世話ですかね。
さて、原因については、推察されているように、
0. タイマーの設定で ajax リクエストが飛ぶ
0. ボタン押下してタイマー解除して「青」にする
0. ajax のレスポンスが戻ってきて「赤」にする

ということかと思います。「テキストボックスが空のときには青にしておく」ということをやりたいのであれば、とりあえずの work around として ajax のレスポンスが戻ってきたときにテキストボックスが空かどうか調べ、空じゃないときに「赤」にする、というのはどうでしょうか。私の感覚ではあくまでも work around であり、setTimeout を使わない設計がいいんじゃないかとは思いますが(しつこいですね)。

投稿2016/04/22 23:28

unau

総合スコア2468

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

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

k499778

2016/04/23 02:59

回答ありがとうございます。 できました! ajaxの成功時条件分岐をいれると、期待通りに動きにすることができました! 実際の現場のコードでもしていたのですが、 Ajaxが実行される前のテキストボックスの値で条件分岐をかけていました。 そうすると今回のようなときに齟齬が生じ、結果として不具合が発生するのですね。 自身0.5秒遅延させる仕様でsetTimeoutしかやり方が思いつかなかったため、その方法でしています。もし他の方法でスジが違わない方法があれば全然それを使います。
k499778

2016/04/23 03:48

setTimeoutとAjaxの動きをもう少し深く理解したいと思い、こちらに投稿をあげましたのでもしよろしればお答えいただけたらと思います。 よろしくお願い致します。 https://teratail.com/questions/33150
guest

0

ajaxを実行する前にボタンを押せなくするのはどうでしょうか?

javascript

1$("#aqua").prop("disabled", true);

投稿2016/04/22 23:33

退会済みユーザー

退会済みユーザー

総合スコア0

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

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

k499778

2016/04/23 02:53

回答ありがとうございます。 そうですね、その方法は期待している動きではないので できれば違うやり方で実現したいですね。 ただ回答していただいた気持ち、感謝しています。
guest

0

結果的に以下のようなコードになりましたので一応載せておきます。

HTML

1 2<!DOCTYPE html> 3<html> 4<head> 5<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script> 6<style> 7.box1{ 8 width: 150px; 9 height: 150px; 10 background-color: aqua; 11 margin-top: 20px; 12} 13.box2{ 14 width: 150px; 15 height: 150px; 16 background-color: red; 17 margin-top: 20px; 18 display: none; 19} 20</style> 21</head> 22<body> 23<br> 24<input type="text" id="text" oninput="red(this)"> 25<input type="button" id="aqua" value="青を表示"> 26<div class="box1"></div> 27<div class="box2"></div> 28</body> 29<script> 30// ボタン押下時、「青」に変える 31var timer = false; 32$("#aqua").click(function(){ 33 if (timer !== false) { 34 clearTimeout(timer); 35 } 36 $('div.box1').show(); 37 $('div.box2').hide(); 38 $('#text').val(''); 39 40}); 41 42// 「赤」に変える。oninput処理を何度も走らせないため1秒後に実行 43function red(_this){ 44 if (timer !== false) { 45 clearTimeout(timer); 46 } 47 timer = setTimeout(function(){ 48 49 $.ajax({ 50 url: "http://localhost/cakephp3/Sample/blue", 51 }).done(function(){ 52 var str = $('#text').val(); //今回増やした部分 53 if(str !== ''){ 54 $('div.box1').hide(); 55 $('div.box2').show(); 56 console.log(_this.value); 57 } 58 }).fail(function(){ 59 console.log('error!!!'); 60 }); 61 },500); 62} 63 64// ボタンを押した時、常に「青」になるようにしたい。 65// 現状テキストボックス入力後、すぐにボタンを押すと最後「赤」になる 66// 秒数やsetTimeoutの処理は維持し、ただボタン押下時は常に青になるようにしたい 67 68</script> 69</html> 70

投稿2016/04/23 03:50

k499778

総合スコア599

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

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

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問