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

标签 javascript jquery cordova openlayers-3

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

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

enter image description here enter image description here

这会监听屏蔽 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);
}

如果您在菜单未显示时单击 map ,那么会发生什么情况,控制台会注销“net curtain hidden”,这是正确的。但是,如果您打开菜单,然后单击屏蔽 div(网幕),它会关闭菜单并隐藏网幕,这是正确的,但随后会触发“隐藏网幕”,这是错误的!我需要它停止隐藏网帘。

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

最佳答案

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

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

尝试代码:

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

解释:

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

  1. 触摸启动
  2. 触摸移动
  3. 触摸
  4. 鼠标悬停
  5. 鼠标移动
  6. 鼠标按下
  7. 鼠标弹起
  8. 点击

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

这可能会造成混淆,因为调用 event.stopPropagation() 会阻止事件在事件链中冒泡 - 这是人们自然会假设正在发生的事情。但是您应该始终记住在触摸事件处理程序中使用 preventDefault(),这样默认的鼠标模拟处理就不会发生。

如需更深入的解释,read this .

可能相关:link

关于javascript - 点击事件仍然在div下面触发,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39508472/

相关文章:

javascript - 如何从 jQuery DataTables 单元格内的 <input type=date> 获取值?

jQuery ajax 加载的 html 在动画后没有正确的 css 样式

javascript - PHP Javascript - 无法将选择器 onclick 更改为删除预览文件

ios - Phonegap Barcodescanner 插件 - 适用于 iPad 和 iPhone 的定制 XIB

Javascript 加权概率数组

javascript - 联系表格 - 仅在 html 中包含的 Html 和 Javascript (tumblr)

android - 将 "useLibrary"添加到 android cordova 插件中的 build.gradle

android - 无法让我的 meteor 应用程序连接到我的服务器。短暂显示 "connected",转到 "connecting"和 "waiting"

javascript - 检测是否存在具有属性 [itemtype ='http://schema.org/Offer' ] 的标签的最快方法

JQuery Mobile 对话框字段清除问题