点击事件仍然在div下触发 [英] click event still triggered underneath div

查看:175
本文介绍了点击事件仍然在div下触发的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

This is a PhoneGap app I'm building that I am testing on my laptop and then on an iphone using PhoneGap cli. I have an openlayers 3 map that records click events on it. I also have a div that masks the whole map when a menu shows. The idea being that when this masking div is clicked/tapped it hides itself but the map below DOES NOT register the click event. What is happening is that the map IS registering the click event so the masking div is hidden but the map then does something else because its been clicked, except it shouldn't have!

我已经把我的代码简化到了nitty gritty。这里有两个screenhote没有和与菜单和蒙版div显示。按钮右下角是打开菜单的按钮( .layers_menu_button )。

I've simplified my code down to the nitty gritty. Here is two screenshote of without and with the menu and masking div showing. The button bottom right is the one that opens the menu (.layers_menu_button).

这会侦听遮罩div( #net_curtain2 ),然后隐藏它(注意,注释传播的东西是我试图停止点击/敲击事件在这里,但它没有任何区别)。 interaction_type 定义为点击 touchend

This listens for clicks/taps on the masking div (#net_curtain2), and then hides it (note the commented out propagation thing is my attempt to stop the click/tap event here, but it doesn't make any difference). interaction_type is defined as click or touchend depending on what I'm testing on.

$(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(净窗帘),它关闭菜单和隐藏网幕,这是正确的,但然后它会触发网帘隐藏,这是错误的!我需要它只是停下来隐藏网帘。

So what happens is that if you click on the map when the menu is not showing, the console logs out 'net curtain hidden', which is correct. But if you open the menu and then click on the masking div (net curtain) it closes the menu and hide the net curtain, which is correct, but then it THEN triggers 'net curtain hidden' which is wrong! I need it to just stop at hiding the net curtain.

最令人沮丧的是,它在我的笔记本电脑上工作,但不是在手机上。更改 map.on('click'... map.on(interaction_type ...

What the most frustrating is that it works on my laptop but not on the phone. And changing map.on('click'... to map.on(interaction_type... mean it doesn't trigger any click/tap events on the map. I'm baffled.

推荐答案

您的移动浏览器正在尝试模拟点击

Your mobile browser is attempting to emulate click events I believe.

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

Calling event.preventDefault(); should solve your problem.

尝试代码:

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

说明:

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

I believe your issue is the way mobile browsers emulate click events. One thing to always remember when developing for mobile browsers is that they attempt to emulate click events if nothing has explicitly prevented the default action. The order of events goes like this:


  1. touchstart

  2. touchmove

  3. touchend


  4. mousemove

  5. mousedown

  6. mouseup


  1. touchstart
  2. touchmove
  3. touchend
  4. mouseover
  5. mousemove
  6. mousedown
  7. mouseup
  8. click

因此,通过在任何中调用 event.preventDefault()触摸事件,您的移动浏览器假设您希望它继续通过该事件链,直到它触发点击事件(这是

So, by not calling event.preventDefault() in any touch event your mobile browser assumes you want it to continue through that event chain, until it fires a click event (it's this click event that's giving you issues).

这会引起混乱,因为调用 event.stopPropagation()阻止事件从事件链冒泡 - 这是人们自然认为发生的事情。但是你应该始终记住在touch事件处理程序中使用preventDefault(),因此不会发生默认的鼠标仿真处理。

This can be confusing since calling event.stopPropagation() stops the event from bubbling up the event chain - which is what one would naturally assume is happening. But you should always remember to use preventDefault() inside touch event handlers, so the default mouse-emulation handling doesn’t occur.

有关更深入的解释, 阅读此

For a more in-depth explanation, read this.

可能相关:链接

这篇关于点击事件仍然在div下触发的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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