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

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

ただいまの
回答率

89.24%

googlemapのinfowindowでの表示について

解決済

回答 2

投稿 編集

  • 評価
  • クリップ 0
  • VIEW 846

◆前提
スマホで取得した位置情報をgooglemapで可視化。近隣店舗の情報を提示するサイトを制作しています。使用言語はhtml/css/javascript/php/mysqlです。

◆やりたいこと
①複数の位置情報(配列化した緯度経度)を読み込み、map上にマーカーを配置。
②マーカーをタップするとinfowindowが開き、都市名とボタンを表示。
③ボタンをタップすると都市名をphpにget送信。
④php側で処理した情報(近隣店舗)を返却し、当該infowindow内に表示。

◆現状
近隣店舗の情報生成は後回しで、ステップとして試験的に「③で都市名ではなく数値(緯度)を送信。phpで緯度に文字列(return)を足して返却する」という動きを作っている中で、問題にあたりました。

◆問題点と発生手順
最初に開いたinfowindowだけ「緯度+return」が表示されない(③の送信または④の返却がされない)

  1. 初期状態でマーカーを複数個表示。infowindowはどれも開いていない。
  2. どのマーカーをタップしてもinfowindowは開き正しい情報とボタンが表示される。
  3. しかしボタンをタップしてもなにも表示されない。
  4. そのまま別のマーカーをタップするとinfowindowが開き、同時に手順2のinfowindowは閉じる。開いているinfowindow内のボタンをタップすると、都市名が返却され、表示される。つまり想定通りに挙動する。
  5. そのまま、さっきうまくいかなかったマーカーをもう一度試すと、手順4の動きになる。どのマーカーを試しても同じように手順4の動きになる。
  6. しかしいったんinfowindowを閉じる(×をタップする)と、以降は同じ問題が発生する。つまり状態として手順1に戻り、次に開いたinfowindowは手順3の状態になる。

◆以下コードから、問題点の原因についてご指摘いただけると幸いです。
最初に開いたinfowindowでも滞りなく数値を送信し返却された情報を表示できるようにしたいです。

locations[i][0]:緯度
locations[i][1]:経度
locations[i][2]:都市名

function initialize() {

    //位置情報の配列
     var locations = <?php echo json_encode($result); ?>;

    //Map
    var map = new google.maps.Map(document.getElementById('map_canvas'));
    var bounds = new google.maps.LatLngBounds();
    var infoWindow = new google.maps.InfoWindow({
        maxWidth: 200
    });
    var marker;

    //位置情報の配列からマーカー表示
    for (var i = 0; i < <?php echo $row_count;?>; i++) {
      marker = new google.maps.Marker({
        position: new google.maps.LatLng(locations[i][0], locations[i][1]),
        map: map,
            animation: google.maps.Animation.BOUNCE
      });

  // 地図表示領域をマーカー位置に合わせて拡大
  bounds.extend (marker.position);

    //マーカーをクリックしたらinfowindowを表示
      google.maps.event.addListener(marker, 'click', (function(marker, i) {
        return function() {
                //infowindowの中身
          infoWindow.setContent(
                    '<div style="text-decoration:none;"><input type="text" id="request_lat" value="'+locations[i][0]+'" hidden><img id="request" src="./img/heart.png" width="40" height="40" align="right"></img>'
                    +
                    locations[i][2]
                    +
                    '<div id="return"></div>'
                );//end_infoWindow.setContent(


                $('#request').click(function(){    //id属性requestの要素がclickされたら
                        $.get('request.php', {         //GETでrequest.phpに対して
                             position:$('#request_lat').val()     //id属性request_latの要素を
                                }, function(data){      //コールバック関数functionの引数として渡す。
                                $('#return').html(data.return_position);   //戻り値はid属性resultにhtml表示
                        });
                });

          infoWindow.open(map, marker);

        }//end_return function...
      }) (marker, i));//end_google.maps.event...end_(function(marker...
    }//end_for (var i = 0...

    // 引数に指定した矩形領域を地図に収める
    map.fitBounds(bounds);
};


request.php

<?php
session_start();
header('Content-Type: application/json; charset=utf-8');

$rp=array(
    "return_position" => $_GET['position']."return",
);
echo json_encode($rp);
?>
  • 気になる質問をクリップする

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

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

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 過去に投稿した質問と同じ内容の質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

質問への追記・修正、ベストアンサー選択の依頼

  • shozi3

    2018/11/17 11:45

    request.phpのログを出してみれば何か分かるかも。

    キャンセル

  • yoshiomurakami

    2018/11/17 14:08

    ありがとうございます。エラーログには何も出てなかったのですが、それ以外の詳細なログを見る方法を調べて見ようと思います。

    キャンセル

  • shozi3

    2018/11/17 15:07

    error_log()使って引数と戻り値を出してみるとか。http://php.net/manual/ja/function.error-log.php

    キャンセル

  • yoshiomurakami

    2018/11/17 15:15

    こういうエラーログの吐き出し方があるのですね。うまく使えるようにいろいろ試してみます。なお本質問についてはjavascript側に問題があったようで、解決することができました。ありがとうございました。

    キャンセル

回答 2

checkベストアンサー

+1

最初にinfowindowが開くまで、$('#request').click(function(){ }#requestを見つけれていません。
一度閉じてしまった場合も同じ理由で見失っています。

なので、
$('#request').click(function(){   }の中身を別のfunctionとして外に出して、<img>の中でonclick=として呼び出します。

全体としてはこんな感じ

function initialize() {

  //位置情報の配列
  var locations = <?php echo json_encode($result); ?>;

  //Map
  var map = new google.maps.Map(document.getElementById('map_canvas'));
  var bounds = new google.maps.LatLngBounds();
  var infoWindow = new google.maps.InfoWindow({
    maxWidth: 200
  });
  var marker;

  //位置情報の配列からマーカー表示
  for (var i = 0; i < 3; i++) {
    marker = new google.maps.Marker({
      position: new google.maps.LatLng(locations[i][0], locations[i][1]),
      map: map,
      animation: google.maps.Animation.BOUNCE
    });

    // 地図表示領域をマーカー位置に合わせて拡大
    bounds.extend (marker.position);

    //マーカーをクリックしたらinfowindowを表示
    google.maps.event.addListener(marker, 'click', (function(marker, i) {

      return function() {
        //infowindowの中身
        infoWindow.setContent(
          //<img> タグに onclick 追加
          '<div style="text-decoration:none;"><input type="text" id="request_lat" value="'+locations[i][0]+'" hidden><img onclick ="req()" id="request" src="./img/heart.png" width="40" height="40" align="right"></img>'
          +
          locations[i][2]
          +
          '<div id="return"></div>'
        );//end_infoWindow.setContent(

          infoWindow.open(map, marker);

        }//end_return function...
      }) (marker, i));//end_google.maps.event...end_(function(marker...
    }//end_for (var i = 0...

      // 引数に指定した矩形領域を地図に収める
      map.fitBounds(bounds);
  };

//--- これ追加 initialize()の外に出します。
function req(){
  $.get('request.php', {         //GETでrequest.phpに対して
    position:$('#request_lat').val()     //id属性request_latの要素を
  }, function(data){      //コールバック関数functionの引数として渡す。
    $('#return').html(data.return_position);   //戻り値はid属性resultにhtml表示
  });
}

投稿

編集

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2018/11/17 15:36

    だから、img onclick ="req()"ではじめて「チェックしろ」と命令するわけですね。

    キャンセル

  • 2018/11/17 15:38

    プログラムの流れをセリフで表現するとイメージが湧いてきますね。面白いものです。いろいろご教示いただきありがとうございました!

    キャンセル

  • 2018/11/17 15:44

    onclick ="req()"は、オレをclickでreq()を発動せるぜ!って感じの素直な命令になります。

    キャンセル

0

私の勘違いならすみません。

どんなときも想像通りに動作しないのがプログラミングというものではないでしょうか。

もし可能なら、事前にインフォウィンドウをポップアップで開いておきます。
マーカーをタップしたらフォーカスを切り替えて表示させたものを可視化する。
インフォウィンドウにはマップで見るボタンを用意すると共に、
<input type="hidden"
で緯度けいどの値を保持させる。
そうすれば事前にインフォウィンドウは表示されているので、
とりあえず実装したい機能は実装可能になるのではないでしょうか?

こんな考え方は不良だと思いますが、王道がいつもうまくいく手立てとは、私は限らないと思っていますが、いかがでしょうか?

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2018/11/17 10:10

    ご回答ありがとうございます。勘違いはされてないと思います。
    おっしゃるように、他のアプローチを検討することも解決手段の一つかもしれませんね…。自分のイメージに固執して前に進めないというのも非効率だし、よりよいインターフェースが考えつくかもしれないので、別の表現を考えてもみようと思います。

    ありがとうございました。

    キャンセル

  • 2018/11/17 11:18

    私はスマートフォン関連の最新技術はあまり詳しくなくて、こんな回答しか出せなくてもどかしいです。

    キャンセル

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

  • ただいまの回答率 89.24%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる