javascript - 将 HTML 元素与 Leaflet 的 bindPopup 的 HTML 字符串连接起来

标签 javascript jquery html leaflet

我正在尝试通过 layer.bindPopup 为 Leaflet 功能编写用于编辑功能属性的功能。在这一点上,我几乎拥有我需要的一切,除了最后一件事:Documentation是说 layer.bindPopup 采用 HTML 字符串或 HTML 元素,所以我需要将我的 HTMLString 与两个元素连接起来:saveChanges 按钮和 speed_input 输入,然后用它提供给 layer.bindPopup。对 $.append 的任何操作都没有帮助。关于如何解决这个问题有什么建议吗?

function onEachArc(feature, layer) {
            // Create an input
            var speed_input = L.DomUtil.create('input', 'speed');

            // Set a feature property as value
            speed_input.value = feature.properties.speed;

            // Add a listener to watch for change on time input
            L.DomEvent.addListener(speed_input, 'change', function(){
                // Change the value of speed
                feature.properties.speed = speed_input.value;
            });

            // Bind popup to layer with input
            HTMLString = '<table style="width:100%">\
                <tr style="background-color:grey">\
                <th><b>Arc Numer: </b>' + feature.properties.linkstr + '</br></th>\
                </tr>\
                <tr>\
                <td><b>Speed: </b> ' + feature.properties.speed + '.</div></td>\
                </tr>\
                </table>';

            var saveChanges = document.createElement('button');
            saveChanges.innerHTML = 'Save Changes';
            saveChanges.onclick = function(){
                $.ajax({
                        type:"POST",
                        url:"php/updateFeature.php",
                        data: {feature: feature},
                        success: function(data){
                                $('#test').html(data);
                            }
                    });
                    //return false;
                    }
                };   

                /*
                This did not help
                var box =  document.createElement("div");
                    box.style.width = "100px";
                    box.style.height = "100px";
                $("#box").append("#saveChanges");
                layer.bindPopup(box);
                */

                layer.bindPopup(saveChanges);
            };

最佳答案

你可以使用 innerHTML:

The Element.innerHTML property sets or gets the HTML syntax describing the element's descendants.

var form = L.DomUtil.create('form', 'my-form');

form.innerHTML = '<input type="text" class="my-input" />';

var button = L.DomUtil.create('button', 'my-button', form);
button.textContent = 'Ok!';

http://plnkr.co/edit/DiK1zj?p=info

或使用 outerHTML:

On return, content contains the serialized HTML fragment describing the element and its descendants.

var inputHTML = '<input type="text" class="my-input" />';

var button = L.DomUtil.create('button', 'my-button', form);
button.textContent = 'Ok!';

var buttonHTML = button.outerHTML;

var form = '<form class="my-form">' + inputHTML + buttonHTML + '</form>';

http://plnkr.co/edit/Z6rADJ?p=preview

话虽如此(并且在阅读了您的评论之后),我必须说:这有效但非常 hacky。我不建议以这种方式做这种事情。您要么使用 HTML 元素构建表单,要么使用模板/字符串并将其转换为 HTML 元素,以便您可以附加处理程序和处理内容。把事情搞混会给你带来麻烦。我会这样处理:

模板:

var template = '<form id="popup-form">\
  <label for="input-speed">New speed:</label>\
  <input id="input-speed" class="popup-input" type="number" />\
  <table class="popup-table">\
    <tr class="popup-table-row">\
      <th class="popup-table-header">Arc numer:</th>\
      <td id="value-arc" class="popup-table-data"></td>\
    </tr>\
    <tr class="popup-table-row">\
      <th class="popup-table-header">Current speed:</th>\
      <td id="value-speed" class="popup-table-data"></td>\
    </tr>\
  </table>\
  <button id="button-submit" type="button">Save Changes</button>\
</form>';

使用样式表,保持模板干净整洁:

.popup-table {
  width: 100%;
}

.popup-table-row {
  background-color: grey;
}

onEachFeature 函数中,附加一个点击处理程序:

L.geoJson(collection, {
  onEachFeature: function (feature, layer) {
    layer.on('click', layerClickHandler);
  }
});

并处理它:

function layerClickHandler (e) {

  var marker = e.target,
      properties = e.target.feature.properties;

  // Check if a popup was previously set if so, unbind  
  if (marker.hasOwnProperty('_popup')) {
    marker.unbindPopup();
  }

  // Create new popup from template and open it
  marker.bindPopup(template);
  marker.openPopup();

  // Now that the popup is open and the template converted to HTML and
  // attached to the DOM you can query for elements by their ID

  L.DomUtil.get('value-arc').textContent = properties.arc;
  L.DomUtil.get('value-speed').textContent = properties.speed;

  var inputSpeed = L.DomUtil.get('input-speed');
  inputSpeed.value = properties.speed;
  L.DomEvent.addListener(inputSpeed, 'change', function (e) {
    properties.speed = e.target.value;
  });

  var buttonSubmit = L.DomUtil.get('button-submit');
  L.DomEvent.addListener(buttonSubmit, 'click', function (e) {
    // Do fancy ajax stuff then close popup
    marker.closePopup();
  });

}

Plunker 示例:http://plnkr.co/edit/8qVoW5?p=preview

这更干净、更快,它不会将弹出窗口绑定(bind)到每个标记。它更具可读性、可扩展性并且不易出错。希望对您有所帮助,祝您好运!

关于javascript - 将 HTML 元素与 Leaflet 的 bindPopup 的 HTML 字符串连接起来,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32940123/

相关文章:

javascript - 从 restify 获取正确的 json 输出

jquery - 将引导弹出窗口输入值绑定(bind)到拥有弹出窗口的元素

javascript - 如何使用 EaselJS 在位图上绘制/绘制线条?

javascript - 表单重置按钮与 jquery 重置冲突

javascript - 如何在 JavaScript 中阻塞异步函数

javascript - 为什么我的表格在单击一行时没有响应

php - AJAX 设置间隔

javascript - 如何使用 CKEditor 为 <table> 添加悬停效果?

html - 根据状态更改按钮颜色

javascript - AngularJS 默认缓存 JSONP