10 Replies Latest reply on Feb 26, 2015 4:46 PM by melanie-j

    How can I enable pinch zooming after calling preventDefault();?

    melanie-j

      I am creating a graph in Edge Animate that needs to work properly both on desktop computers and iPads. The html file I create will then be pulled into an iframe on a website as a portion of a larger page. I included both touch and mouse events for the interactive elements, and for the most part it works properly on both desktops and iPads - except for when it doesn't.

       

      I have found in my testing that sometimes a mouseEnter/mouseOver or even a click event will fire despite my use of e.preventDefault(); in my touchStart or touchEnd events (I've tried both). The behavior is not consistent enough for me to determine why it's happening so I have a workaround for the time being - I added preventDefault(); to touchStart in document.compositionReady:

       

      $(document).on('touchstart', function(e){

              e.preventDefault();

        });

       

      I understand that this is not ideal, but with deadlines and all that noise it's the best solution I have found so far.

       

      It works perfectly, however as expected, it also disables pinch zoom and pan. I don't care about panning, but zooming is necessary because the data points on the graph are on the small side. Can anyone help me with the code I would need to enable pinch zoom after calling preventDefault():? Or the conditional statement that would run preventDefault(); on a regular/single touch but not on a pinch-zoom touch?

       

      I am using Edge Animate CC v2014.1.1 on a Windows 7 machine, if that's helpful.

       

      I cannot share my code due to my company's confidentiality agreement although if necessary I can probably mock up a simple sample - I'm hoping that someone out there with more experience developing for touch devices can point me in the right direction.

       

      Thank you!!

      Melanie

        • 2. Re: How can I enable pinch zooming after calling preventDefault();?
          melanie-j Level 1

          Hi Joel,

           

          Thank you so much for taking the time to put that sample together for me! I really appreciate it. It does work on iOS and on my desktop.

          However, when I test in Safari on my iPad (iOS v8.1.1) and in Chrome's (most recent version, 40.0.2214.111) mobile emulator, the mouseDown event (changing BG to red) doesn't occur.

           

          So I set up a stripped-down sample project to show you what I am working on so you can see the issue I have. Basically the mouseOver/mouseEnter (I've tested with both) events create an extra tap when using on the iPad and on the iPhone (iOS v7). I placed a console.log in the mouseEnter/mouseOver events and the mouseLeave/mouseOut events to track them. The mouseLeave/mouseOut events do fire if you tap/click outside of an interactive element.

          Dropbox - sample_touchless.zip

           

          I am hoping you can take a look and suggest how I can re-work my touch and mouse events so that a single tap on an element performs just the click behavior on the iPad, while still maintaining the mouseOver effect for PCs.

           

          Thank you!

          Melanie

          • 3. Re: How can I enable pinch zooming after calling preventDefault();?
            joel_pau Level 5

            2 issues: my download link and your question.

             

            1) My download link was wrong.

            So, i downloaded my own sample and i saw i forgot to update the sample.

            The sample had no touch events.

            new link: calculator.zip - Box

             

            2) i look at your file.

            1 person found this helpful
            • 4. Re: How can I enable pinch zooming after calling preventDefault();?
              melanie-j Level 1

              Ah, that explains it. I thought you were subtly trying to tell me that I didn't need touch events if I set up the mouse events correctly :-)

               

              The updated sample works as expected. Although if you tap too quickly, the built-in delay in firing the click event causes it to miss numbers: if you tap, say, 1 2 3 4 5 in relatively quick succession, it only registers 1 3 5...putting the click behaviors on touchEnd could potentially fix that, but then of course you have to make sure the click event is not also fired.

               

              As you will see in my project, the mouseOver/mouseOut events are the ones causing the extra taps and undesired behavior. They are a requirement of the project. If there isn't a way to combine events so that both touch and mouse events can work together happily, I am open to a solution that tests for touching vs. mouse and then executes the associated events...

               

              Thanks again for all the assistance, I really appreciate it - I've been struggling with this for longer than I care to admit.

              • 5. Re: How can I enable pinch zooming after calling preventDefault();?
                joel_pau Level 5

                So i am rebuilding your code because....

                Here is the first step: Rebuilt dots.zip - Box

                Note: i changed your json file.

                Now, i will add events: step #2.

                See you soon

                1 person found this helpful
                • 6. Re: How can I enable pinch zooming after calling preventDefault();?
                  melanie-j Level 1

                  Hi joel_pau,

                   

                  Thank you for what you have done with this so far! It looks like a much better way to do what I was trying to do, even without the events.

                  Looking forward to step #2!

                  • 7. Re: How can I enable pinch zooming after calling preventDefault();?
                    joel_pau Level 5

                    Temporary version: Rebuilt dots.zip - Box

                    We have only mouse events.

                    It runs on latest versions: Safari, Chrome, Opera, Firefox and IE 11 (Windows 8.1 and 10).

                    Using latest iOS:

                    • First touch returns the mouseover effect.
                    • Second touch returns the click effet.

                     

                    Now, adding touch events: what do you want?

                    • touchstart ==> mouseover effect?
                    • touchend ==> click effect?
                    1 person found this helpful
                    • 8. Re: How can I enable pinch zooming after calling preventDefault();?
                      melanie-j Level 1

                      Thank you!!

                       

                      This is where I am struggling. The user should not tap twice to select a dot on touch screens.

                       

                      So:

                      On touch screens I want it to execute the click behavior on one tap, ignoring the mouseOver.

                      On desktops there should be a mouseOver effect and the click behavior.


                      mouseOver effect: label appears next to dot

                      click effect: loads associated text into text fields on the left, the label next to the dot remains, and the active dot highlights.


                      For the highlight the dot can just change to white for now - I will work on that, I have to change all the colors anyway so I wouldn't want you to spend time on it.

                       

                      The problem I keep having is the "ghost" click on touch screens: sometimes the mouseOver event will fire, causing the double tap or a label appearing for a dot that isn't the active dot. Again, I am super grateful for your help!

                      • 9. Re: How can I enable pinch zooming after calling preventDefault();?
                        joel_pau Level 5

                        This version Rebuilt dots.zip - Box manages iOS events. See private message.

                        Tested: iPad (iOS 8.1.3) and MacBook (Mac OS 10.10.2 and Safari 8.0.3)

                        I will post a latest version to improve the color change and the text box.

                        1 person found this helpful
                        • 10. Re: How can I enable pinch zooming after calling preventDefault();?
                          melanie-j Level 1

                          I haven't exactly found the answer to my original question, but it is more a result of the question itself rather than the fantastic community assistance provided here.

                           

                          My issue was that my project was firing mouseOver/mouseEnter/mouseLeave/mouseOut events on the iPad and iPhone (iOS 7.x and 8.x) when not desired. The interactive/clickable elements - dots - in my project are supposed to have mouseEnter/mouseOver behavior on the desktop but not on iOS touch devices.

                           

                          The mouseEnter events usually fired in a specific case: if a finger touched more than one dot at the same time. Due to the small size of the dots, this could happen frequently depending on the user.

                           

                          What I tried that didn't work:

                          • Calling e.preventDefault() on every possible touch event, on the dots and on the stage, but still mouse events fired occasionally.
                          • Using a timer to detect touches and subsequently ignore mouse events for a period of time, on the dots and on the stage, but sometimes touch events were not picked up by iOS so this was unreliable.
                          • Banging my head repeatedly against my desk and other hard surfaces.
                          • Multiple combinations of the above methods.

                           

                          The closest I could get to canceling out the occasionally-fired mouseEnter/mouseOver events was to call e.preventDefault() in document.compositionReady. But that introduced other unacceptable behaviors and resulted in my slightly misguided question.

                           

                          Joel_pau's help was instrumental in guiding me to my ultimate solution, so I am marking his response correct - I hope his sample proves useful to others as well. It also showed me how to streamline my code and make it more efficient and extensible.

                           

                          What eventually worked for me, using a combination of methods including some from joel_pau's sample:

                          • Check for iOS (iPhone, iPad, iPod) - in my particular situation this is sufficient to cover the user base's needs for the time being, although I may need to add checks for additional devices or features sometime in the future.
                          • Bind both touchstart and click events together; in my case they perform the same behavior.
                          • Use setTimeout() within the touchstart-click events to prevent them from firing twice.
                          • In mouseEnter/mouseOver events, perform iOS check and prevent mouse events if true - this also prevents the mouse event it is bound in, which was not a logical conclusion for me and why I hadn't already tried it

                           

                          var iOS = (navigator.userAgent.match(/(iPad|iPhone|iPod)/g) ? true : false);
                          
                          
                          // flag variable used in setTimeout(), initially set to false
                          var flag = false;
                          
                          
                          sym.$('mySymbol').bind('touchstart click', function () {
                            if (!flag) {
                                 flag = true;
                                 setTimeout(function () {
                                      flag = false;
                                 }, 300);
                                 // perform touchstart/click actions here
                            }
                            return false;
                          });
                          
                          
                          sym.$('mySymbol').bind('mouseenter', function () {
                            if (iOS) { // events for iOS devices only - prevent mouse events
                                 e.preventDefault();
                            } else { // events for everything else
                                 // perform mouseEnter actions here
                            }
                          });
                          

                           

                          This might not be a solution that works for anyone else, but hopefully at least one of you can learn from it and maybe even save yourself from actions resulting in head trauma.

                           

                          Thanks again joel_pau!! I owe you a beer.