Leaflet. js всплывающее окно не позволяет вводить фокус ввода текста в определенной ситуации - PullRequest
0 голосов
/ 10 февраля 2020

Я установил Leaflet. js карта с гео json, показывающая набор улиц по соседству, и включил ссылку на демонстрацию ниже. Щелчок по любому сегменту улицы открывает всплывающее окно с формой, содержащей несколько элементов ввода и кнопку отправки, и кодируется так, чтобы фокусировать первый элемент ввода. Если вы щелкнете по сегменту улицы, когда всплывающее окно уже не открыто, все работает нормально - первый элемент фокусируется, а кнопка отправки работает.

Однако, если вы щелкнете по сегменту улицы, когда всплывающее окно уже при открытии код кажется сломанным - функция фокуса и кнопка отправки не работают.

Я некоторое время пытался выяснить, почему это происходит, и не смог сузить это вниз. Я думаю, что это может быть как-то связано с конфликтами в DOM где-то или временем, но я пока не смог их решить - надеялся, что кто-то здесь заметит проблему.

Демонстрация: https://spotcheck.s3.amazonaws.com/leaflet_popup_bug.html

Соответствующие части кода:


      var map = L.map('map', {zoomControl: false, almostOnMouseMove: false, zoomSnap: 0.25});
      map.setView([41.485, -81.705], 17);

      var myStyle = {
          "weight": 1
      };

      var myStyle_clicked = {
        "weight": 4
      };

      function layerClickHandler (e) {
        var marker = e.target,
            properties = e.target.feature.properties;

        function findMinMax(arr) {
          let maxLat = arr[0][1];
          let maxLng = arr[0][0];

          for (let i = 1, len=arr.length; i < len; i++) {
            let v = arr[i][1];
            if (v > maxLat) { maxLat = v; maxLng = arr[i][0];}
          }

          return [maxLng,maxLat];
        }

        var coordArray = marker.feature.geometry.coordinates[0];
        maxLatPt = findMinMax(coordArray);
        var latlng1 = new L.LatLng(maxLatPt[1], maxLatPt[0]);
        var popup1 = new L.Popup({keepInView:true, offset: new L.Point(0, -3)}).setLatLng(latlng1);
        popupContent = "<strong>segment_id: "+properties.segment_id+'<br>'+properties.description+'</strong><br><form id="test-form"><input name="parked" placeholder="Parked spaces" type="number" id="parked"><br><input name="open" placeholder="Open spaces" type="number" id="open"><br><input name="bad" placeholder="Bad park" type="number" id="bad"><br><input name="illegal" placeholder="Illegal park" type="number" id="illegal"><input type="hidden" id="street_name" name="street_name" value="'+properties.description+'"><input type="hidden" id="street_id" name="street_id" value="'+properties.segment_id+'"><input type="hidden" id="timestamp" name="timestamp"><input type="hidden" id="timestamp_time" name="timestamp_time"><input type="hidden" id="timestamp_day" name="timestamp_day"><input type="hidden" id="timestamp_month" name="timestamp_month"><input type="hidden" id="timestamp_date" name="timestamp_date"><button type="button" id="submit-form">Submit</button></form>'

        popup1.setContent(popupContent);

        function openPopupFeature(callback) {
          popup1.openOn(map);
          callback();
        }

        function focusFirstInput() {
          document.getElementById( 'parked' ).focus();
        }

        openPopupFeature(focusFirstInput);

        // does this function need to be in the L.DomUtil class?
        var buttonSubmit = document.getElementById('submit-form');
        L.DomEvent.addListener(buttonSubmit, 'click', function (e) {
          e.preventDefault();
          buttonSubmit.innerHTML="Wait";
          alert('OK success!');
          popup1.remove();
        });
      }

      var streets = L.layerGroup();
      var streetsJSON = L.geoJson(ohiocity_streets_network, {
        interactive: false,
        onEachFeature: function (feature, layer) {
          layer.on('click', layerClickHandler);
        }
      });

      streets.addLayer(streetsJSON);

      map.addLayer(streets);
      streetsJSON.setStyle({color:"#3388ff", weight:1});

      map.almostOver.addLayer(streets);

      map.on('almost:click', function(e) {
        streets.eachLayer(function(layer) {
          layer.setStyle({color:"#3388ff", weight:1});
        });

        var layer = e.layer;
        layer.setStyle({color:"red", weight:5});

        if (layer.openPopup) {
          layer.fire('click', e);
        }
      });

1 Ответ

0 голосов
/ 10 февраля 2020

Похоже, DOM не готов, когда я пытаюсь сфокусировать элемент ввода, и это вызывает код, который ломается (но не выдает ошибку в консоли).

Я переместил слушатель в функцию .focus с интервалом setTimeout. Я борюсь с обратными вызовами, поэтому, если кто-нибудь может предложить более чистый способ написания этой логики c, я был бы признателен за это!

popup1.setContent(popupContent);

        function openPopupFeature(callback) {
          popup1.openOn(map);
          callback();
        }

        function focusFirstInput() {
          //document.getElementById( 'parked' ).focus();
          setTimeout(function(){
              document.getElementById("parked").focus();
              var buttonSubmit = document.getElementById('submit-form');
              L.DomEvent.addListener(buttonSubmit, 'click', function (e) {
                e.preventDefault();
                buttonSubmit.innerHTML="Wait";
                alert('OK success!');
                popup1.remove();
              });
          }, 500);
        }

        openPopupFeature(focusFirstInput);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...