点击事件仍然在div下面触发

这是我正在构建的PhoneGap应用程序,我正在我的笔记本电脑上测试,然后在使用PhoneGap cli的iphone上测试。 我有一个openlayers 3地图,记录了点击事件。 我还有一个div,当菜单显示时屏蔽整个地图。 这个想法是,当点击/点击这个屏蔽div时,它会隐藏自己,但下面的地图不会注册点击事件。 发生的事情是地图IS注册了click事件,因此隐藏了屏蔽div,但是地图然后做了其他事情,因为它被点击了,除了它不应该!

我把我的代码简化为细节。 这是两个截图,没有和菜单和屏蔽div显示。 右下角的按钮是打开菜单的按钮( .layers_menu_button )。

在此处输入图像描述 在此处输入图像描述

这会侦听屏蔽div( #net_curtain2 )上的点击/点击,然后隐藏它(请注意注释掉的传播事物是我尝试在此停止点击/点击事件,但它没有任何区别)。 interaction_type被定义为clicktouchend具体取决于我正在测试的内容。

 $(window).on("load", function() { $(document).on(interaction_type, "#net_curtain2", function(event) { // event.stopImmediatePropagation(); hide_layers_menu(); }); setup_map(); }); ... function hide_layers_menu() { $('.layers_menu_button').fadeIn("fast", function() { // Animation complete }); // remove hide class, add show class $('.layers_menu_button').removeClass('hide_layers_menu'); $('.layers_menu_button').addClass('show_layers_menu'); $('.layers_menu_content').hide(); $("#net_curtain2").fadeOut("fast", function() { // Animation complete }); var layers_menu_width = parseInt($(window).width()-60); $("#layers_menu").animate({ bottom: "30px", right:"30px", width: "20px", height: "20px" }, 'fast', function() { // Animation complete }); } function setup_map() { // create view view = new ol.View({ center: ol.proj.transform([0.153733491897583, 52.655333117999774], 'EPSG:4326', 'EPSG:3857'), zoom: 17 }); // create layers of map types road = new ol.layer.Tile({ source: new ol.source.BingMaps({ imagerySet: 'Road', key: 'my_key_here', disableZooming: true, maxZoom: 19 }) }); map = new ol.Map({ target: $('#map')[0], layers: [ road ], view: view, controls : ol.control.defaults({ attribution:false, zoom:false, rotate: false }) }); // check if net_curtain is visible and only act if NOT map.on('click', function(evt) { if($('#net_curtain2').is(':hidden')) { console.log("net curtain hidden"); } else { console.log("net curtain showing"); } }); var interactions = map.getInteractions().getArray(); var pinchRotateInteraction = interactions.filter(function(interaction) { return interaction instanceof ol.interaction.PinchRotate; })[0]; pinchRotateInteraction.setActive(false); } 

那么如果你在菜单没有显示的时候点击地图,控制台就会注销“net curtain hidden”,这是正确的。 但是如果你打开菜单,然后点击屏蔽div(网幕)它关闭菜单并隐藏网幕,这是正确的,但然后它然后触发’网帘隐藏’这是错误的! 我需要它才能停下来隐藏网帘。

最令人沮丧的是它可以在我的笔记本电脑上运行但不能在手机上运行。 并改变map.on('click'... to map.on(interaction_type...意味着它不会触发地图上的任何点击/点击事件。我很困惑。

您的移动浏览器正在尝试模拟我认为的点击事件。

调用event.preventDefault(); 应该解决你的问题。

试试代码:

 $(document).on(interaction_type, "#net_curtain2", function(event) { event.preventDefault(); hide_layers_menu(); }); 

说明:

我相信您的问题是移动浏览器模拟点击事件的方式。 在开发移动浏览器时要始终记住的一件事是, 如果没有明确阻止默认操作 ,他们会尝试模拟点击事件 。 事件的顺序如下:

  1. touchstart
  2. touchmove
  3. touchend
  4. 鼠标移到
  5. 鼠标移动
  6. 鼠标按下
  7. 鼠标松开
  8. 点击

因此,通过不在任何touch事件中调用event.preventDefault() ,您的移动浏览器会假定您希望它继续通过该事件链,直到它触发click事件(这是一个给您发出问题的click事件)。

这可能令人困惑,因为调用event.stopPropagation()阻止事件冒泡事件链 – 这是人们自然会想到的事情。 但是你应该总是记得在触摸事件处理程序中使用preventDefault(),因此不会发生默认的鼠标仿真处理。

有关更深入的解释, 请阅读此内容 。

可能相关: 链接