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

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

ただいまの
回答率

88.92%

Leaflet.jsで、すべてのマーカーのポップアップを最初からopenPopup()にしたい。

解決済

回答 1

投稿 編集

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

yows

score 11

Leaflet.jsを使って、webに地図を表示させて、複数の地点をマーキングすることができました。
それで、ここからポップアップを最初から表示されるようにしたいのですが、うまく行きません。

実際のコード

<!DOCTYPE html>
<html>
   <head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <title></title>
    <link rel="stylesheet" href="https://unpkg.com/leaflet@1.6.0/dist/leaflet.css"
   integrity="sha512-xwE/Az9zrjBIphAcBb3F6JVqxf46+CDLwfLMHloNu6KEQCAWi6HcDUbeOfBIptF7tcCzusKFjFw2yuvEpDL9wQ=="
   crossorigin=""/>
    <link rel="stylesheet" href="main.css">
  </head>
  <body class="container">
    <header></header>
    <main>
        <div id="app">
            <div id="map"></div>
        </div>

    </main>
    <footer></footer>

    <script src="https://unpkg.com/leaflet@1.6.0/dist/leaflet.js"
   integrity="sha512-gZwIG9x3wUXg2hdXF6+rVkLF/0Vi9U8D2Ntg4Ga5I5BZpVkVxlJWbSQtXPSiUTtC0TjtGOmxa1AJPuV0CPthew=="
   crossorigin=""></script>
    <script src="https://code.jquery.com/jquery-3.3.1.js"></script>
    <script src="main.js"></script>
  </body>
</html>
'use strict'

{
    var map = L.map('map').setView([38.4316, 141.3094], 12);

    var geojsonFeature = [];
    var test_popupContents = ['sampleA', 'sampleB', 'sampleC', 'sampleD'];
    var lat = [38.4316, 38.4306, 38.4299, 38.4327];
    var lon = [141.3094, 141.3076, 141.3070, 141.3087];

    var customClassName = ['.btn_SampleA', '.btn_SampleB', '.btn_SampleC', '.btn_SampleD'];

    var tileLayer = L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png',{
        attribution: '© <a href="http://osm.org/copyright">OpenStreetMap</a> contributors, <a href="http://creativecommons.org/licenses/by-sa/2.0/">CC-BY-SA</a>',
        maxZoom: 21
        });
tileLayer.addTo(map);

for (var i = 0; i < test_popupContents.length; i++) {
    geojsonFeature.push({
        "type": "Feature",
        "properties": {
        "popupContent": test_popupContents[i],
        "className": customClassName[i]
    },
    "geometry": {
      "type": "Point",
      "coordinates": [lon[i], lat[i]] 
  },
    });

}
    L.geoJson(geojsonFeature,
        {
            onEachFeature: function(feature, layer){
                if(feature.properties && feature.properties.popupContent){
                    layer.bindPopup(feature.properties.popupContent, {className: feature.properties.className});
                }
            }
        }).addTo(map).openPopup();

}

現状と質問

これで試してみますと、test_popupContentssampleAのみが、webページが読み込まれた時に最初からポップアップが表示されています。

これを、すべてのtest_popupContentsの配列のすべてをopenPopup()にするためにはどうしたらよいでしょうか?

2/3 追記

いただいたコメントを参考に次のコードを書いてみました。

'use strict'

{
    var map = L.map('map').setView([38.4316, 141.3094], 12);

    var geojsonFeature = [];
    var test_popupContents = ['sampleA', 'sampleB', 'sampleC', 'sampleD'];
    var lat = [38.4316, 38.4306, 38.4299, 38.4327];
    var lon = [141.3094, 141.3076, 141.3070, 141.3087];

    var tileLayer = L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png',{
        attribution: '© <a href="http://osm.org/copyright">OpenStreetMap</a> contributors, <a href="http://creativecommons.org/licenses/by-sa/2.0/">CC-BY-SA</a>',
        maxZoom: 20,
        autoClose:false
        });
        tileLayer.addTo(map);

for (var i = 0; i < test_popupContents.length; i++) {
    geojsonFeature.push({
        "type": "Feature",
        "properties": {
        "popupContent": test_popupContents[i],
    },
    "geometry": {
      "type": "Point",
      "coordinates": [lon[i], lat[i]] 
    },
    });
}

    L.geoJson(geojsonFeature,
        {
            onEachFeature: function(feature, layer){
                if(feature.properties && feature.properties.popupContent){
                    // layer.bindPopup(feature.properties.popupContent, {className: feature.properties.className});
                    layer.bindPopup(feature.properties.popupContent);
                    geojsonFeature.push(layer);
                }
            },
            pointToLayer: function (feature, latlng) {
                var m = L.marker( latlng, { title : feature.properties.popupContent } );
                geojsonFeature.push( m );
                return m;
            }
        }).addTo(map);

        function markerFunction( id ) {
            for ( var i in geojsonFeature ) {
                var geoJsonFeatureID = geojsonFeature[i].options.title;
                if ( geoJsonFeatureID == id ) {
                    geojsonFeature[i].openPopup();
                }
            }
        }

        markerFunction();

}

これでも、うまく行きません。
consoleには
main.js:52 Uncaught TypeError: Cannot read property 'title' of undefinedとでています。

追記2

単純に開かせる方法で、試してみたのですがうまく行きませんでした。

'use strict'

{
    var map = L.map('map').setView([38.4316, 141.3094], 12);

    var geojsonFeature = [];
    var test_popupContents = ['sampleA', 'sampleB', 'sampleC', 'sampleD'];
    var lat = [38.4316, 38.4306, 38.4299, 38.4327];
    var lon = [141.3094, 141.3076, 141.3070, 141.3087];

    var tileLayer = L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png',{
        attribution: '© <a href="http://osm.org/copyright">OpenStreetMap</a> contributors, <a href="http://creativecommons.org/licenses/by-sa/2.0/">CC-BY-SA</a>',
        maxZoom: 20,
        autoClose:false
        });
        tileLayer.addTo(map);

for (var i = 0; i < test_popupContents.length; i++) {
    geojsonFeature.push({
        "type": "Feature",
        "properties": {
        "popupContent": test_popupContents[i],
    },
    "geometry": {
      "type": "Point",
      "coordinates": [lon[i], lat[i]] 
    },
    });
}

    L.geoJson(geojsonFeature,
        {
            onEachFeature: function(feature, layer){
                if(feature.properties && feature.properties.popupContent){
                    // layer.bindPopup(feature.properties.popupContent, {className: feature.properties.className});
                    layer.bindPopup(feature.properties.popupContent);
                    geojsonFeature.push(layer);
                }
            },
            pointToLayer: function (feature, latlng) {
                var m = L.marker( latlng, { title : feature.properties.popupContent } );
                geojsonFeature.push( m );
                return m;
            }
        }).addTo(map);

        function markerFunction() {
            for (var i in geojsonFeature) {
                geojsonFeature[i].openPopup();
            }
        }

        markerFunction();

}


これをしますと、consoleが
Uncaught TypeError: geojsonFeature[i].openPopup is not a functionになります。

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

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

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

    クリップを取り消します

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

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

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

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

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

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

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

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

    質問の評価を下げる

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

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

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

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

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

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

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

    詳細な説明はこちら

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

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

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

回答 1

checkベストアンサー

0

bindPopup(/*略*/).openPopup();とかは試されていますか?

【Documentation - Leaflet - a JavaScript library for interactive maps】
https://leafletjs.com/reference-1.6.0.html#popup

marker.bindPopup(popupContent).openPopup();

過去に似た質問に回答していました。(過去質問の要件に沿って)個別にポップアップしていますが、そこを書き換えれば全ポップアップも可能だと思います。

【JavaScript - Leaflet.jsでマーカーをaタグで呼び出しポップアップしたい|teratail】
https://teratail.com/questions/59625


追記:

単純に全部開くならこうでは?

function markerFunction(id) {
    for (var i in geojsonFeature) {
        geojsonFeature[i].openPopup();
    }
}

投稿

編集

  • 回答の評価を上げる

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

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

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

  • 回答の評価を下げる

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

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

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

  • 2020/02/03 16:50

    geoJsonが非同期処理を前提に作られている場合、マーカーの登録がmarkerFunctionの実行より後になっているかもしれませんね。
    setTimeout(markerFunction,100);
    とかにしてみても同じでしょうか?(レイヤー自体のイベントを拾うほうが確実だとは思いますが)

    キャンセル

  • 2020/02/03 17:09

    あ、geojsonFeature.push( m );とgeojsonFeature.push(layer);で同じ変数使ってるじゃないですか。そりゃopenPopupなんて無いですよ。
    あと、bindPopupにオプションを指定する必要がありました。
    layer.bindPopup(feature.properties.popupContent,{autoClose:false});

    【Documentation - Leaflet - a JavaScript library for interactive maps】
    https://leafletjs.com/reference-1.6.0.html#popup-autoclose
    【動くサンプル】
    https://jsfiddle.net/dw1tznx3/

    キャンセル

  • 2020/02/03 22:09

    kei344様
    問題解決しました。
    サンプルコード、ありがとうございます。setTimeoutの件、autoCloseの件勉強になりました。
    深く感謝いたします。

    キャンセル

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

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

関連した質問

同じタグがついた質問を見る