onclick 事件在 iPhone 混合应用程序中发生了两次

Posted

技术标签:

【中文标题】onclick 事件在 iPhone 混合应用程序中发生了两次【英文标题】:onclick event is occuring two times in iPhone hybrid app 【发布时间】:2012-10-23 12:15:28 【问题描述】:

我正在开发一个 iPhone 混合应用程序。我使用 javascript 插入了一个链接,并定义了应该在 onclick 事件上调用的函数。

当我单击链接函数时,会调用并执行所需的操作,但之后如果我单击应用程序主体中的任何位置,则会再次调用相同的函数。

这发生在我的应用程序中的两个链接上。

谁能告诉我发生了什么错误?

我编写了一个函数来添加图像作为链接。代码如下:

// create a link for delete enquiry
var DelLink = document.createElement("a");

// setting the name of the link.
DelLink.setAttribute("name" , "DelButton"+pCurrentEnquiryID);

// image for the delete and its properties.
var DelImage = document.createElement("img");
DelImage.setAttribute("src","images/delete.png");
DelImage.setAttribute("height","30px");
DelImage.setAttribute("width","30px");

// append image to the link
DelLink.appendChild(DelImage);

//specifying onclick event of the link
DelLink.setAttribute("onclick","DeleteEnquiry(this)");
//DelLink.onclick = "DeleteEnquiry(this)";

return DelLink;

【问题讨论】:

我对这里发生的事情有几个想法(touch 设备本身没有 click 事件,但有一个 touchstarttouchend 事件),但你要 显示一些代码 你可以认为它是一个网页,我使用的javascript代码是这样的...... link.setAttribute("onclick","Somefuncton(this)"); 我认为您在使用降价时遇到了麻烦:在段落的每一行之前插入四个空格(复制和粘贴的代码)以将该段落显示为文字代码。如果你想显示一些代码,用反引号转义。 我可以随心所欲,但除非我能查看导致您的问题的代码,否则我无能为力。例如,我可以假设您的代码如下所示:document.getElementById('foo').onclick = function(e) console.log('bar');document.body.addEventListener('click',function(e)console.log('foo'),false);<a href="#" onclick="javascript:return console.log(this);">Foo</a> 或... 到 Infinity。请,一些代码可能有助于缩小范围 请注意,您应该编辑问题以添加更多详细信息,您不需要依赖评论部分。 【参考方案1】:

好的,您正在设置onclick 属性。现在,这在 “传统” 平台上运行良好(具有类似鼠标的设备,带有可用于单击对象的按钮)。触摸设备(名字里有线索)没有这个,而是通过触摸屏幕来操作的。好吧,您知道这一点,所以我认为您可以理解touch 事件极度 过载(多点触控)。

触摸一秒钟与触摸一秒钟完全不同。您也可以用 1、2、3 或 4 根手指触摸屏幕。每次都要以不同的方式处理。 为了使事情变得更加复杂,您可以在屏幕上拖动滑动,这也需要以不同的方式处理。

幸运的是,我最近编写了一些代码来将某些触摸事件映射到单击处理程序,使用闭包、绑定侦听器并在各处设置超时。因此,这可能会对您有所帮助:

if ('ontouchstart' in window)
//we have a touch device
    document.body.addEventListener('touchstart',function(e)
    //handle all touch events on the body
        e = e || window.event;
        //not sure about all mobile browsers (win mobile)
        //so I'm playing it safe
        var target = e.target || e.srcElement;
        if (target.tagName.toLowerCase() !== 'a')
        //didn't touch on a link
            return e;//stop
        
        //touch must end after .3 seconds, otherwise user is zooming or something
        var timer = setTimeout(function()
        
            target.removeEventListener('touchend',endHandler,false);//unbind after .3 seconds
            clearTimeout(timer);
        ,300);
        var endHandler = function(e)
        
            e = e || window.event;
            var endTarget = e.target || e.srcElement;//get element on which the touch ended
            clearTimeout(timer);//stop timer
            target.removeEventListener('touchend',endHandler,false);//remove listener
            if (endTarget !== target)
            //user "swiped"
                return e;
            
            //touch ended within .3 seconds, and ended on the same element, interpret this as click
            return clickHandlerFunction.apply(target,[e]);//invoke click handler with the target as context
        ;
        target.addEventListener('touchend',endHandler,false);//bind touchend listener
    ,false);

这基本上是注册所有 touchstart 事件。首先要检查的是用户是否触摸了感兴趣的元素,我想用我的自定义事件处理程序来处理它。如果不是,则返回事件,没有任何变化。 如果对元素的触摸感兴趣,我会为该目标上的touchend 事件创建一个侦听器。我还设置了一个超时,它将在 0.3 秒后删除该侦听器(以防止泄漏)。如果touchend 事件触发,请检查用户是否在原始元素上被释放,如果没有,则将其解释为滑动并停止。如果目标匹配,则在目标的上下文中调用点击处理程序并 传递事件对象! 这样您就可以调用stopPropagation() 和/或preventDefault() 方法。 touchhandler 还通过清除计时器启动并自行删除(再次:防止内存泄漏)。与以往一样,这是一个非常非常基本的 sn-p,可以做更多的工作

触摸事件包含更多信息(例如,您可以检查有多少手指正在触摸屏幕)。我也省略了一些原始代码,因为那会使它非常复杂和混乱(我这里没有它,我真的不记得我是如何处理的某些情况)。然而,我可以告诉你,我倾向于检查e.clientXe.clientY 坐标,如果touchend 事件在touchstart 目标的50px 范围内,我还是将其映射到点击处理程序:提供一些柔焦适合冷酷颤抖的人 ;) 这样即使因纽特人也可以浏览页面。

不管怎样,看看什么对你有用。不过有几个有用的链接:Touch tablesome historysome touch libs

【讨论】:

我使用了 'touchup' 事件而不是 'click' 这解决了其中一个链接的问题,但对于其他链接,它给出了奇怪的行为,即在页面加载之前调用函数 touchup 不靠谱(查看第一个链接:touch table),主要是为了注册“longer touches”,需要注册 “标签” 事件。在这种情况下,我会说 touchstarttouchend 是更可靠且与 X-mobile-browser 兼容的事件

以上是关于onclick 事件在 iPhone 混合应用程序中发生了两次的主要内容,如果未能解决你的问题,请参考以下文章

如何在 IOS 6.0(Iphone) 中通过 jquery 为混合应用程序关闭选择器的 onchange 事件下拉列表

如何使用 OnClick 事件设置 Jquery Mobile 导航

jQuery对话框上的Onclick事件不适用于IOS

混合式App开发 Apicloud 官方iPhone X 适配

如何为 iphone6/6+ 优化混合应用程序

如何在 iPhone 上以调试/开发模式运行我的混合移动应用程序?