Google Maps OverlayView:仅使SVG可点击 [英] Google Maps OverlayView: make only SVG clickable

查看:117
本文介绍了Google Maps OverlayView:仅使SVG可点击的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个带有多个SVG叠加层的Google地图.但是,当我在这些SVG上添加click事件时,所有叠加层都是可点击的,并且我希望它仅适用于SVG路径.

这是一个小提琴 https://jsfiddle.net/gmkfhr9s/1/

我正在使用自定义叠加层文档作为基础 https://developers.google.com/maps/documentation/javascript/customoverlays

USGSOverlay.prototype.onAdd = function() {
  var div = document.createElement('div');
  div.style.borderStyle = 'dotted';
  div.style.borderWidth = '2px';
  div.style.borderColor = 'white';
  div.style.position = 'absolute';

  // Create the img element and attach it to the div.
  var img = document.createElement('img');
  img.src = this.image_;
  img.style.width = '100%';
  img.style.height = '100%';
  img.style.position = 'absolute';
  div.appendChild(img);

  this.div_ = div;

  // Add the element to the "overlayLayer" pane.
  var panes = this.getPanes();
  panes.overlayLayer.appendChild(div);

  //add element to clickable layer
  this.getPanes().overlayMouseTarget.appendChild(div);

  google.maps.event.addDomListener(img, 'mouseover', function() {
    img.style.opacity = '0.5';
  });
  google.maps.event.addDomListener(img, 'mouseout', function() {
    img.style.opacity = '1';
  });
};

您可以看到,由于发生鼠标悬停事件,所有叠加层(带边框的框)均被选中,并且仅位于SVG上.

是否可以仅使SVG可点击?

线程是一个类似的问题,如果它可以帮助您./p>


@Sphinxxx的答案很好.

我只想补充一点,如果您有多个SVG,并且其中一些位于其他之上,则必须添加此CSS才能单击它们.

svg {
  pointer-events: none;
}
path {
  pointer-events: all;
}

解决方案

首先,要控制SVG的内部<path>,您需要SVG元素本身,您无法通过带有外部SVG的图像访问它们网址.

一旦有了SVG元素(最简单的方法就是在HTML中包含SVG标记),本文就提供了一个很好的示例,说明如何将SVG用作地图叠加层: http://serversideguy.com/2017/10/31/如何在自定义叠加层上将svgs放置在Google地图上

我在这里做了一个完整的例子: https://codepen.io/Sphinxxxx/pen/wjEyMm

/**
    Will be called when the map is ready for the overlay to be attached.
*/
onAdd() {
    const svg = this.svg;
    svg.style.position = 'absolute';

    //Add the SVG element to a map pane/layer that is able to receive mouse events:
    const panes = super.getPanes();
    panes.overlayMouseTarget.appendChild(svg);
}

/**
    Whenever we need to (re)draw the overlay on the map, including when first added.
*/
draw() {
    //Here, we need to find the correct on-screen position for our image.
    //To achieve that, we simply ask the map's projection to calculate viewport pixels from the image's lat/lng bounds:
    const projection = super.getProjection(),
          bounds = this.bounds,
          sw = projection.fromLatLngToDivPixel(bounds.getSouthWest()),
          ne = projection.fromLatLngToDivPixel(bounds.getNorthEast());

    //Place/resize the SVG element:
    const s = this.svg.style;
    s.left = sw.x + 'px';
    s.top  = ne.y + 'px';
    s.width  = (ne.x - sw.x) + 'px';
    s.height = (sw.y - ne.y) + 'px';
}

I have a Google Map with multiple SVG overlays. But when I add a click event on these SVG, all the overlay is clickable and I want it to work only for the SVG path.

Here's a fiddle https://jsfiddle.net/gmkfhr9s/1/

I'm using the Custom overlays documentation as a base https://developers.google.com/maps/documentation/javascript/customoverlays

USGSOverlay.prototype.onAdd = function() {
  var div = document.createElement('div');
  div.style.borderStyle = 'dotted';
  div.style.borderWidth = '2px';
  div.style.borderColor = 'white';
  div.style.position = 'absolute';

  // Create the img element and attach it to the div.
  var img = document.createElement('img');
  img.src = this.image_;
  img.style.width = '100%';
  img.style.height = '100%';
  img.style.position = 'absolute';
  div.appendChild(img);

  this.div_ = div;

  // Add the element to the "overlayLayer" pane.
  var panes = this.getPanes();
  panes.overlayLayer.appendChild(div);

  //add element to clickable layer
  this.getPanes().overlayMouseTarget.appendChild(div);

  google.maps.event.addDomListener(img, 'mouseover', function() {
    img.style.opacity = '0.5';
  });
  google.maps.event.addDomListener(img, 'mouseout', function() {
    img.style.opacity = '1';
  });
};

You can see that, with the mouseover event, all the overlay (the bordered box) is selected and ont only the SVG.

Is it possible to make only the SVG clickable ?

This thread is a similar problem if this can help you.


EDIT :

@Sphinxxx's answer works well.

I just want to add that, if you have multiple SVGs with some of them above others, you'll have to add this CSS to be able to click on them.

svg {
  pointer-events: none;
}
path {
  pointer-events: all;
}

解决方案

First of all, to control the SVG's inner <path>s you need the SVG element itself, you can't access them through an image with an external SVG url.

Once you have your SVG element (the easiest is to include the SVG markup in your HTML), this article has a good example on how to use that SVG as a map overlay: http://serversideguy.com/2017/10/31/how-do-i-place-svgs-on-a-google-map-using-custom-overlays/

I have made a complete example here: https://codepen.io/Sphinxxxx/pen/wjEyMm

/**
    Will be called when the map is ready for the overlay to be attached.
*/
onAdd() {
    const svg = this.svg;
    svg.style.position = 'absolute';

    //Add the SVG element to a map pane/layer that is able to receive mouse events:
    const panes = super.getPanes();
    panes.overlayMouseTarget.appendChild(svg);
}

/**
    Whenever we need to (re)draw the overlay on the map, including when first added.
*/
draw() {
    //Here, we need to find the correct on-screen position for our image.
    //To achieve that, we simply ask the map's projection to calculate viewport pixels from the image's lat/lng bounds:
    const projection = super.getProjection(),
          bounds = this.bounds,
          sw = projection.fromLatLngToDivPixel(bounds.getSouthWest()),
          ne = projection.fromLatLngToDivPixel(bounds.getNorthEast());

    //Place/resize the SVG element:
    const s = this.svg.style;
    s.left = sw.x + 'px';
    s.top  = ne.y + 'px';
    s.width  = (ne.x - sw.x) + 'px';
    s.height = (sw.y - ne.y) + 'px';
}

这篇关于Google Maps OverlayView:仅使SVG可点击的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆