点击事件仍在div下方触发。

3
这是我正在构建的PhoneGap应用程序,我使用PhoneGap cli在笔记本电脑上进行测试,然后在iphone上进行测试。我有一个openlayers 3地图记录其上的点击事件。当菜单显示时,我还有一个覆盖整个地图的div。想法是当点击/轻拍这个遮罩div时,它会隐藏自己,但下面的地图不会注册点击事件。但实际发生的是,地图正在注册点击事件,因此遮罩div被隐藏,但地图随后执行了其他操作,因为它已经被点击了,但实际上不应该! 我已将代码简化到了核心。以下是没有和有菜单以及遮罩div显示的两个屏幕截图。右下角的按钮是打开菜单(.layers_menu_button)。

enter image description hereenter image description here

这段代码监听遮罩层 (#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”,这是正确的。但是,如果您打开菜单,然后单击遮罩层(net curtain),它将关闭菜单并隐藏net curtain,这是正确的,但是然后会触发“net curtain hidden”,这是错误的!我需要它停止隐藏net curtain。
最令人沮丧的是,在我的笔记本电脑上可以正常工作,但手机上却不行。将map.on('click'...更改为map.on(interaction_type...意味着不会在地图上触发任何点击/轻拍事件。我感到困惑。

没有读取,似乎是事件冒泡错误。 - madalinivascu
可能是 event.stopPropogation(); - Rayon
我已经尝试过使用 event.stopPropagation 和 event.stopImmediatePropagation(在代码中被注释掉)但都没有阻止它。 - Helen Danger Burns
你尝试过使用 event.preventDefault(); 吗?否则,你可能遇到了一个 CSS 问题,其中一个 div 覆盖在另一个上面(z-index)。 - Aᴄʜᴇʀᴏɴғᴀɪʟ
1
@Cᴀʟʟᴏᴅᴀᴄɪᴛʏ 谢谢!这很有效,在我的代码片段的第4行hide_layers_menu();之前添加它。你能把这个作为回答发布一下吗?我会接受它的。不过,可以详细解释一下为什么这样做是有效的吗?因为我不太确定为什么它有效!如果这是一个冒泡问题,那么阻止传播显然更有意义?谢谢! - Helen Danger Burns
@HelenDangerBurns 当然可以!给我一分钟。 - Aᴄʜᴇʀᴏɴғᴀɪʟ
1个回答

2

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

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

尝试以下代码:

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

解释:

我认为你的问题在于移动浏览器模拟点击事件的方式。在开发移动浏览器应用时,需要记住一件事情,即如果没有明确阻止默认操作,它们会尝试模拟点击事件。事件的顺序如下:

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

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

这可能会让人感到困惑,因为调用event.stopPropagation()会停止事件从事件链上传播 - 这是人们自然而然会认为正在发生的事情。但是,你应该始终记住在touch事件处理程序中使用preventDefault(),以避免出现默认的鼠标模拟处理。

更详细的解释,请阅读这篇文章

可能相关的链接:链接


太棒了!谢谢你! - Helen Danger Burns

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接