创建自定义控件并关联到HTML元素

问题描述 投票:0回答:1

我使用OpenLayers 6。我尝试创建单击时触发的自定义地理位置控件。位于地图外部的HTML按钮。

这里是地图外部按钮位置按钮的定义:

   <div data-role="footer" data-position="fixed" class="centered-butons">
    <div data-role="controlgroup" id="footerControls" data-type="horizontal" style="text-align: center" data-theme="b">

        <a href="#streetsearchpage" data-role="button" data-mini="true" data-icon="search" data-transition="none">Search</a>
        <a href="#" id="locate" data-role="button" data-mini="true" data-icon="location" data-transition="none">Location</a>
    </div>
   </div>   

以及这里我如何尝试创建自定义控件:

 var LocateControl = /*@__PURE__*/(function (Control) {
    function LocateControl(opt_options) {

        var target = document.querySelector('#locate');

        Control.call(this, {
            //element: element
            target: target
        });

        element.addEventListener('click', this.handleLocateTo.bind(this), false);
    }

    //some logic

    return LocateControl;
}(ol.control.Control));

我不想动态创建按钮并在调用函数中使用element property相反,我想使用一个已经存在的按钮(id =“ locate”)。

所以我尝试了上面的代码,但出现此错误:

    Uncaught ReferenceError: element is not defined

是否有任何方法可以将自定义控件与地图之外的现有按钮相关联(在我的情况下为id =“ locate”)?

javascript gis openlayers
1个回答
0
投票

我认为您的错误是在call方法上创建控件时。您正在设置目标,但对于您而言,则不需要这样做,因为您不会在此放置任何东西。另外,您可能会遇到错误如果您没有在元素中提供Node,它可以工作,但您可能会在控制台中看到它。

这里以自定义控件OL示例为例,并对其进行了修改,以便它使用外部按钮。

<!doctype html>
<html lang="en">
  <head>
    <link rel="stylesheet" href="https://cdn.jsdelivr.net/gh/openlayers/openlayers.github.io@master/en/v6.1.1/css/ol.css" type="text/css">
    <style>
      .map {
        height: 400px;
        width: 100%;
      }
			#a { display: none; }
    </style>
    <script src="https://cdn.jsdelivr.net/gh/openlayers/openlayers.github.io@master/en/v6.1.1/build/ol.js"></script>
    <title>Custom Control</title>
  </head>
  <body>
    <div>Reset Rotation:
      <button id="b">N</button>
    </div>
    <div id="map" class="map"></div>
    <script type="text/javascript">
    var RotateNorthControl = /*@__PURE__*/(function (Control) {
      function RotateNorthControl(opt_options) {
        var options = opt_options || {};
        var button = document.getElementById('b');
        Control.call(this, {
          element: document.createElement('div'),
          target: options.target
        });
        button.addEventListener('click', this.handleRotateNorth.bind(this), false);
      }
      if ( Control ) RotateNorthControl.__proto__ = Control;
      RotateNorthControl.prototype = Object.create( Control && Control.prototype );
      RotateNorthControl.prototype.constructor = RotateNorthControl;
      RotateNorthControl.prototype.handleRotateNorth = function handleRotateNorth () {
        this.getMap().getView().setRotation(0);
      };

      return RotateNorthControl;
    }(ol.control.Control));
    var map = new ol.Map({
      controls: ol.control.defaults().extend([
        new RotateNorthControl()
      ]),
      layers: [
        new ol.layer.Tile({
          source: new ol.source.OSM()
        })
      ],
      target: 'map',
      view: new ol.View({
        center: [0, 0],
        zoom: 3,
        rotation: 1
      })
    });
    </script>
  </body>
</html>

更新

也许您问题的真正答案是您不需要案例中的自定义控件。事实是,基本上,您可以通过将按钮的onclick事件绑定到执行所需功能的某些函数来解决您的问题。不过,我可能看不到整个图片。

target属性可让您将控件绑定到地图控件之外的元素。而element属性是自定义控件的容器。

因此,基本上,在第一个解决方案中,我通过给它们提供空节点而作弊(我承认这可能不是最佳解决方案。

请检查我为您制作的有关此事的新示例,

<!doctype html>
<html lang="en">
  <head>
    <link rel="stylesheet" href="https://cdn.jsdelivr.net/gh/openlayers/openlayers.github.io@master/en/v6.1.1/css/ol.css" type="text/css">
    <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.4.1/css/bootstrap.min.css" integrity="sha384-Vkoo8x4CGsO3+Hhxv8T/Q5PaXtkKtu6ug5TOeNV6gBiFeWPGFN9MuhOf23Q9Ifjh" crossorigin="anonymous">
    <style>
      .map {
        height: 400px;
        width: 100%;
      }
			#ovmap { height: 150px; margin-top: 20px;}
    </style>
    <script src="https://code.jquery.com/jquery-3.4.1.slim.min.js" integrity="sha384-J6qa4849blE2+poT4WnyKhv5vZF5SrPo0iEjwBvKU7imGFAV0wwj1yYfoRSJoZ+n" crossorigin="anonymous"></script>
    <script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/umd/popper.min.js" integrity="sha384-Q6E9RHvbIyZFJoft+2mJbHaEWldlvI9IOYy5n3zV9zzTtmI3UksdQRVvoxMfooAo" crossorigin="anonymous"></script>
    <script src="https://stackpath.bootstrapcdn.com/bootstrap/4.4.1/js/bootstrap.min.js" integrity="sha384-wfSDF2E50Y2D1uUdj0O3uMBJnjuUD4Ih7YwaYd1iqfktj0Uod8GCExl3Og8ifwB6" crossorigin="anonymous"></script>
    <script src="https://cdn.jsdelivr.net/gh/openlayers/openlayers.github.io@master/en/v6.1.1/build/ol.js"></script>
    <title>Controls</title>
  </head>
  <body>
    <div class="container">
      <div class="row mt-2">
        <div class="col">
          <h3>Button</h3>
          <button id="b" type="button" class="btn btn-primary"
          onclick="handleRotateNorth()">N</button>
        </div>
        <div class="col">
          <h3>OverviewMap</h3>
          <div id="ovmap"></div>
        </div>
        <div class="col">
          <h3>Scaleline</h3>
          <div id="scale"></div>
        </div>
      </div>
      <div class="row mt-2">
        <div id="map" class="map"></div>
      </div>
    </div>
    <script type="text/javascript">
    var source = new ol.source.OSM();
    var overviewMapControl = new ol.control.OverviewMap({
      layers: [
        new ol.layer.Tile({
          source: source
        })
      ],
      target: document.getElementById('ovmap'),
      collapsed: false
    });
    var scalelineControl = new ol.control.ScaleLine({
      target: document.getElementById('scale')
    });
    var map = new ol.Map({
      controls: ol.control.defaults().extend([
        overviewMapControl,
        scalelineControl
      ]),
      layers: [
        new ol.layer.Tile({
          source: source
        })
      ],
      target: 'map',
      view: new ol.View({
        center: [0, 0],
        zoom: 3,
        rotation: 1
      })
    });
    function handleRotateNorth () {
        map.getView().setRotation(0);
    };
    </script>
  </body>
</html>
© www.soinside.com 2019 - 2024. All rights reserved.