点击事件仍在div下面触发

时间:2016-09-15 10:12:18

标签: javascript jquery cordova openlayers-3

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

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

enter image description here enter image description here

这会侦听屏蔽div(#net_curtain2)上的点击/点按,然后隐藏它(请注意注释掉的传播内容是我尝试在此处停止点击/点击事件,但它没有' t做出​​任何改变)。 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);
}

所以会发生的情况是,如果您在菜单未显示时点击地图,控制台会退出“隐藏的网帘”,这是正确的。但是如果你打开菜单,然后点击屏蔽div(网幕)它关闭菜单并隐藏网幕,这是正确的,但然后它然后触发隐藏的网帘#39;这是错的!我需要它才能停下来隐藏网帘。

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

1 个答案:

答案 0 :(得分:2)

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

致电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. 点击
  9. 因此,在任何event.preventDefault()事件中都没有调用touch,您的移动浏览器会假定您希望它继续通过该事件链,直到它触发click事件(就是这个click 1}}给你问题的事件。)

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

    有关更深入的解释,read this

    可能相关:link