在mapbox gl js中的图层上注册点击事件时如何处理事件冒泡

Ami*_*ore 6 mapbox-gl-js

如何停止层单击事件的事件传播。

mapBox.on('click', layerId, function (e) {
        console.log(e);
        //e.stopPropagation(); which is not working 
        //e.originalEvent.stopPropagation(); which is not working 
        var popupHtml = getPopupHtmlWrapper(e.features[0]);
        new mapboxgl.Popup({closeButton:false})
                .setLngLat(e.lngLat)
                .setHTML(popupHtml)
                .addTo(mapBox);
    });
Run Code Online (Sandbox Code Playgroud)

And*_*hiu 8

Mapbox 提供对原始事件的访问。这意味着每当我们想将 a 限制为click仅单击的最顶层时,我们需要做的就是调用e.originalEvent.preventDefault()第一层并检查e.originalEvent.defaultPrevented下面的层:

this.map
  .on('click', 'layer_1', function(e) { // topmost layer
    e.originalEvent.preventDefault();
    // layer_1 functionality
  })
  .on('click', 'layer_2', function(e) { // second topmost layer
    if(!e.originalEvent.defaultPrevented) {
      // click was performed outside of layer_1
      e.originalEvent.preventDefault();
      // layer_2 exclusive functionality
    }
  })
  .on('click', 'layer_3', function(e) {
    if(!e.originalEvent.defaultPrevented) {
      // click was performed outside of layer_1 and layer_2
      e.originalEvent.preventDefault();
      // layer_3 exclusive functionality here...
    }
...
  })
Run Code Online (Sandbox Code Playgroud)


小智 7

也许我们不需要全局变量,我遇到了和你一样的问题,我用解决方案修复了它:

mapbox.on('click', 'layer1', function(e){  
   e.originalEvent.cancelBubble = true;
   /*
    //or you can add an attr
    e['bubble'] = 'no';
   
   */
   console.log('layer1');

}
mapbox.on('click', 'layer2', function(e){  
   if(e.originalEvent.cancelBubble){
     return;
   }
   /*
     if(e['bubble] && e['bubble'] == 'no'){
       return;
     }   
   */
   console.log('layer2');
}
Run Code Online (Sandbox Code Playgroud)


mat*_*sad 5

根据@Stophface的建议,我使用了

e => {
  const features = map.queryRenderedFeatures(e.point)
  if (features[0].layer.id === myLayerName ) {
    doMyClickAction(e)
  }
}
Run Code Online (Sandbox Code Playgroud)

以便仅当我在本例中关心的图层是第一个被单击的图层时才对事件执行某些操作。


Rap*_*ier 0

我不知道有任何简单的方法来处理这个问题。我假设您正在尝试阻止单击事件传播到其他层。您可以做的是使用全局变量来存储刚刚在这些坐标处发生的单击。然后在其他点击处理程序中检查这种情况。

var recentClicks = {layer1 : null}

mapBox.on('click', "layer1", function (e) {
    console.log(e);
    recentClicks["layer1"] = e.lngLat
    // Proceed to creating pop-up
});

mapBox.on('click', "layer2", function (e) {
    console.log(e);
    if(recentClicks["layer1"] && recentClicks["layer1"][0] == e.lngLat[0] && recentClicks["layer1"][1] == e.lngLat[1]){
        recentClicks["layer1"] = null
        return
    } else {
      // Proceed to treating layer 2 click event
    }
});
Run Code Online (Sandbox Code Playgroud)

通过一些工作,您可以将其应用到无限多个层。