Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
204 views
in Technique[技术] by (71.8m points)

javascript - onclick event is occuring two times in iPhone hybrid app

I am developing a iPhone Hybrid App. In that I have inserted a link using Javascript and defined the function that should be called on onclick event.

When I click the link function is called and required action is performed but after that if I click anywhere in the body of the app the same function is called again.

This is happening for both the two links present in my App.

Can anyone tell what wrong is happening ?

I have written a function to add an image as a link. Code is given below:

// 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;
See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

Ok, so you're setting the onclick attribute. Now this works perfectly well on "traditional" platforms (that have a mouse-like device with buttons that can be used to click on objects). A touch device (clue is in the name) doesn't have this, instead it is operated by touching the screen. Allright, you knew that, so I take it you can understand that the touch event is extremely overloaded (multi-touch).

Touching the screen for a second means something completely different than touching the screen for a split second. You can also touch the screen with 1, 2, 3 or 4 fingers. Each time this is to be processed differently.
To make things even more complex, you can drag or swipe accross the screen, which needs to be handled differently, too.

As luck would have it, I've recently written some code to map certain touch events to a click handler, using closures, binding listeners and setting timeouts all over the place. So this might help you on your way:

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);
}

What this does, basically, is register all touchstart events. The first thing that is being checked is did the user touch on an element of interest, one which I want to handle with my custom event handler. If not, the event is returned, nothing changes.
If the element touches is of interest, I create a listener for a touchend event on that target. I also set a timeout, which will remove that listener after .3 seconds (to prevent leaks). If the touchend event fires, check if the user was released on the original element, if not, interpret this as a swipe, and stop.
If the targets match, invoke the click handler, in the target's context and pass the event object! so you can invoke stopPropagation() and/or preventDefault() methods. The touchhandler also kicks off by clearing the timer and removes itself, too (again: to prevent mem leaks).
As ever, this is a really, really basic snippet that can do with a lot more work

The touch events contain a lot more info (you can check how many fingers are touching the screen, for instance). I omitted a bit of my original code, too because that would have made it very complex and messy (and I don't have it here with me, and I can't really remember how I dealt with certain situations). I can tell you, however, that I tend to check the e.clientX and e.clientY coordinates, and if the touchend event was within 50px of the touchstart target I map it to the click handler anyway: to provide some soft focus for people who are cold and trembling ;) so even Inuit can browse the page.

Anyhow, see what works for you. A couple of useful links though:
Touch table
some history
some touch libs


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...