【问题标题】:How to change the cursor on hover in openlayers 3?如何在openlayers 3中更改悬停光标?
【发布时间】:2014-09-24 16:31:12
【问题描述】:

我设法为从远程 GeoJSON 资源添加的要素图层添加了交互性。当我点击一个功能时,我会得到它的 ID,触发一个 AJAX 请求并在地图区域之外的页面上显示有关该功能的一些相关信息。

我使用了Select 交互。

我想让用户更清楚地知道他可以点击地图上的功能。当鼠标悬停在 ol.layer.Vector 中包含的功能时,有什么方法可以将鼠标光标更改为“手”的“光标”?

我在文档、本网站或谷歌搜索中找不到任何内容。

【问题讨论】:

  • 有一个例子:openlayers.org/en/v3.0.0/examples/icon.html。老实说,我试图在我的地图中使用相同的方法但没有成功:Uncaught TypeError: Cannot set property 'cursor' of undefined
  • 感谢您的链接。我稍后再试试。
  • @Azathoth getTarget 为您提供给地图目标的内容:字符串或 HTMLElement。应该是 HTMLElement,就像在示例中一样,如果你想改变它的样式。
  • @tonio 我想我复制了示例中使用的所有代码,但 console.log(map.getTarget()); 打印了一个包含“map”的字符串
  • @Azathoth :请参阅我的回答,了解如何处理您获得的字符串值

标签: javascript openlayers-3


【解决方案1】:

不用jQuery也可以做到:

map.on("pointermove", function (evt) {
    var hit = this.forEachFeatureAtPixel(evt.pixel, function(feature, layer) {
        return true;
    }); 
    if (hit) {
        this.getTargetElement().style.cursor = 'pointer';
    } else {
        this.getTargetElement().style.cursor = '';
    }
});

【讨论】:

  • 在 3.17.1 中,此代码有效。但不是用this.getTarget(),用this.getTargetElement()
【解决方案2】:

这是另一种方法:

map.on('pointermove', function(e){
  var pixel = map.getEventPixel(e.originalEvent);
  var hit = map.hasFeatureAtPixel(pixel);
  map.getViewport().style.cursor = hit ? 'pointer' : '';
});

【讨论】:

  • 旁注,您应该添加缺少的括号“);”最后方便复制粘贴
【解决方案3】:

如果这不起作用,请尝试 2​​ 的组合,这似乎适用于我的矢量弹出窗口...

var target = map.getTarget();
var jTarget = typeof target === "string" ? $("#" + target) : $(target);
// change mouse cursor when over marker
$(map.getViewport()).on('mousemove', function (e) {
    var pixel = map.getEventPixel(e.originalEvent);
    var hit = map.forEachFeatureAtPixel(pixel, function (feature, layer) {
        return true;
    });
    if (hit) {
        jTarget.css("cursor", "pointer");
    } else {
        jTarget.css("cursor", "");
    }
});

【讨论】:

  • 这个对我有用,其他的不行。 OL3 // 版本:v3.1.0-pre.2-179-gca3dfe2
【解决方案4】:

感谢 Azathoth 在 cmets 中提供的示例链接,我找到了解决方案:

  • 使用 OL3 pointermove 事件
  • 使用jQuery获取目标元素并改变其光标样式

代码如下:

var cursorHoverStyle = "pointer";
var target = map.getTarget();

//target returned might be the DOM element or the ID of this element dependeing on how the map was initialized
//either way get a jQuery object for it
var jTarget = typeof target === "string" ? $("#"+target) : $(target);

map.on("pointermove", function (event) {
    var mouseCoordInMapPixels = [event.originalEvent.offsetX, event.originalEvent.offsetY];

    //detect feature at mouse coords
    var hit = map.forEachFeatureAtPixel(mouseCoordInMapPixels, function (feature, layer) {
        return true;
    });

    if (hit) {
        jTarget.css("cursor", cursorHoverStyle);
    } else {
        jTarget.css("cursor", "");
    }
});

这里是 OpenLayers 网站上示例的链接:http://openlayers.org/en/v3.0.0/examples/icon.html

【讨论】:

    【解决方案5】:

    对我来说是这样的:

    map.on('pointermove', function(e) {
              if (e.dragging) return;
              var pixel = e.map.getEventPixel(e.originalEvent);
              var hit = e.map.forEachFeatureAtPixel(pixel, function (feature, layer) {
                  return true;
              });
              e.map.getTargetElement().style.cursor = hit ? 'pointer' : '';
            });
    

    我还添加了一个图层过滤器:

    map.on('pointermove', function(e) {
          if (e.dragging) return;
          var pixel = e.map.getEventPixel(e.originalEvent);
          var hit = e.map.forEachFeatureAtPixel(pixel, function (feature, layer) {
              return layer.get('name') === 'myLayer';
          });
          e.map.getTargetElement().style.cursor = hit ? 'pointer' : '';
        });
    

    我不得不选择一个新的解决方案,因为我之前用于图层过滤器的旧解决方案不再起作用:

    var hit = e.map.hasFeatureAtPixel(e.pixel, function(layer){
                 return layer.get('name') === 'myLayer';
              });
    

    【讨论】:

    • 有趣的想法,但不要忘记提及图层没有原生“名称”属性,必须设置(此处,在图层创建时)。 var myLayer = new ol.layer.Vector({ source: mySource, style: myStyle, name: "myLayerName" });
    【解决方案6】:

    我用下面的代码做到了:

    var target = $(map.getTargetElement()); //getTargetElement is experimental as of 01.10.2015
    map.on('pointermove', function (evt) {
        if (map.hasFeatureAtPixel(evt.pixel)) { //hasFeatureAtPixel is experimental as of 01.10.2015
            target.css('cursor', 'pointer');
        } else {
            target.css('cursor', '');
        }
    });
    

    【讨论】:

      【解决方案7】:

      另一种方式(结合上述部分答案,但更简单):

      map.on("pointermove", function (evt) {
          var hit = map.hasFeatureAtPixel(evt.pixel);
          map.getTargetElement().style.cursor = (hit ? 'pointer' : '');
      });
      

      【讨论】:

      • 这是使用 OpenLayers 5 的正确方法。
      【解决方案8】:

      Uncaught TypeError: Cannot set property 'cursor' of undefined.

      固定为:map.getTargetElement()s.style.cursor = hit ? 'pointer' : ''; 而不是 map.getTarget().style.cursor = hit ? 'pointer' : '';

      【讨论】:

        【解决方案9】:

        获取目标元素的简单方法

        var target = map.getTarget();
        
        target = typeof target === "string" ?
            document.getElementById(target) : target;
        
        target.style.cursor = features.length > 0) ? 'pointer' : '';
        

        【讨论】:

        【解决方案10】:

        如果你们使用 Angular 2,则必须使用以下代码:

        this.map.on("pointermove", function (evt) {
            var hit = evt.map.hasFeatureAtPixel(evt.pixel);
            this.getTargetElement().style.cursor = hit ? 'pointer' : '';
        });
        

        如果 map 变量是成员类,您将其称为“this.map”,如果它在当前函数中声明,则可以将其称为“map”。但最重要的是,你不会写

        map.getTargetElement()
        

        但是你写

        this.getTargetElement()
        

        【讨论】:

          【解决方案11】:

          尝试尽量减少 pointermove 事件关闭,避免在不必要时更新样式,因为它经常调用:

          示例 1:使用 jQuery

          var cursorStyle = "";
          map.on("pointermove", function (e) {
              let newStyle = this.hasFeatureAtPixel(e.pixel) ? "pointer" : "";
              newStyle !== cursorStyle && $(this.getTargetElement()).css("cursor", cursorStyle = newStyle);
          });
          

          示例 2: jQuery:

          var cursorStyle = "";
          map.on("pointermove", function (e) {
              let newStyle = this.hasFeatureAtPixel(e.pixel) ? "pointer" : "";
              if (newStyle !== cursorStyle) {
                  this.getTargetElement().style.cursor = cursorStyle = newStyle;
              }
          });
          

          【讨论】:

            【解决方案12】:

            简单的方法

            map.on('pointermove', (e) => {
                  const pixel = map.getEventPixel(e.originalEvent);
                  const hit = map.hasFeatureAtPixel(pixel);
                  document.getElementById('map').style.cursor = hit ? 'pointer' : '';
                });
            }
            

            【讨论】: