0

I have put together a website and using javascript to run a script that allows you to move between one image and another to see the before and after of an image. The javascript works fine on a desktop but on a mobile and tablet I can't get the same effect to run properly. Do I need to include something to enable to this work on mobile & tablet?

This is one of the pages that I am on about where the effect is active. Here

You will need to view this on a mobile and tablet to see it not working as it should.

Also here is the javascript that I am using if it helps. Let me know if you require anything else.

$(document).ready(function(){
    var wrapper = $("div.reveal-visible");

    wrapper.mousedown(function(e) {
        $(this).data("sliding", true);
        var offs = e.pageX - $(this).offset().left
        $(this).find('div').width(offs);
    }).mousemove(function(e) {
        if ($(this).data("sliding")) {
            var offs = e.pageX - $(this).offset().left
            $(this).find('div').width(offs);
        }
    });

    $(document).mouseup(function(e) {
        wrapper.data("sliding", false);
    });
});
Jonathan Hall
  • 75,165
  • 16
  • 143
  • 189

1 Answers1

0

Take a look at this answer to a similar question. The premise is to use JQuery's bind method which attaches a handler to an event for an element it is applied to. The bind method takes an eventType argument, which is a String containing one or more DOM events. The method also takes a function, which it should execute when the event has occurred, as an argument.

Then for mobile devices (which have touchscreens) use the touch equivalents of the mouse events: touchstart, touchmove, touchend.

So, change your code to the following:

$(document).ready(function(){
    var wrapper = $("div.reveal-visible");

    wrapper.bind("mousedown touchstart", function(e){
        $(this).data("sliding", true);
        var offs = e.pageX - $(this).offset().left
        $(this).find('div').width(offs);
    });

    wrapper.bind("mousemove touchmove", function(e){
        if ($(this).data("sliding")) {
            var offs = e.pageX - $(this).offset().left
            $(this).find('div').width(offs);
        }
    });

    $(document).bind("mouseup touchend", function(e){
        wrapper.data("sliding", false);
    });

});

Edit: Okay, so the reason it didn't work this time is because when it's a touch screen we have to get the touch point from the touch event. Instead of using e.pageX for the touchscreen, use e.changedTouches[0].pageX. So here's the updated code:

$(document).ready(function(){
    var wrapper = $("div.reveal-visible");

    wrapper.bind("mousedown touchstart", function(e){
        var offs;
        $(this).data("sliding", true);
        if(typeof e.changedTouches === "undefined" || e.changedTouches == null){
            offs = e.pageX - $(this).offset().left;
        }else{
            offs = e.changedTouches[0].pageX - $(this).offset().left;
        }
        $(this).find("div").width(offs);
    });

    wrapper.bind("mousemove touchmove", function(e){
        if($(this).data("sliding")){
            var offs;
            if(typeof e.changedTouches === "undefined" || e.changedTouches == null){
                offs = e.pageX - $(this).offset().left;
            }else{
                offs = e.changedTouches[0].pageX - $(this).offset().left;
            }
            $(this).find("div").width(offs);
        }
    });

    $(document).bind("mouseup touchend", function(e){
        wrapper.data("sliding", false);
    });

});

Edit: So, the code was correct but the problem was with the JQuery Event Object. The JQuery event object only supports certain types of events and the touch events are not included. There is JQuery Mobile, which including a link to that library should fix your problem. But I chose to intermingle more "plain" JavaScript into the code to not have to rely on another resource. The below code is tested and works:

$(document).ready(function(){
        var wrapper = $("div.reveal-visible");
        var w = document.getElementsByClassName("reveal-visible")[0];

        w.addEventListener("touchstart", start);
        w.addEventListener("touchmove", move);
        wrapper.bind("mousedown", start);
        wrapper.bind("mousemove", move);

        function start(e){
            var offs;
            $(this).data("sliding", true);
            if(typeof e.changedTouches === "undefined" || e.changedTouches == null){
                offs = e.pageX - $(this).offset().left;
            }else{
                offs = e.changedTouches[0].pageX - $(this).offset().left;
            }
            $(this).find("div").width(offs);
        }

        function move(e){
             if($(this).data("sliding")){
                 var offs;
                 if(typeof e.changedTouches === "undefined" || e.changedTouches == null){
                     offs = e.pageX - $(this).offset().left;
                 }else{
                     offs = e.changedTouches[0].pageX - $(this).offset().left;
                 }
                 $(this).find("div").width(offs);
             }
        }

        $(document).bind("mouseup touchend", function(e){
            wrapper.data("sliding", false);
        });

    });
Community
  • 1
  • 1
chRyNaN
  • 3,592
  • 5
  • 46
  • 74
  • Ok I added this to my code but it still doesn't work on mobile or tablet. You can see here with the above code added to the website. http://www.ryankerswell.co.uk/design/visible-me.html – Ryan Kerswell Apr 28 '15 at 18:46
  • Ok tried that code and still not working. This new code is now on the webpage for you to see. – Ryan Kerswell Apr 29 '15 at 07:57
  • Here is a Jsfiddle of the code in action if it helps :) http://jsfiddle.net/bfccbxg8/ – Ryan Kerswell Apr 29 '15 at 08:13
  • Also again if it helps this is where I got the inspiration from and this one works on mobile and tablet exactly as I want it to. :) http://www.theguardian.com/uk/interactive/2011/aug/09/london-riots-before-after-photographs – Ryan Kerswell Apr 29 '15 at 09:29
  • Hi this works on mobile and tablet now but im getting a javascript error on the 2 pages where this javascript is placed. The error is "Uncaught TypeError: Cannot read property 'addEventListener' of undefined" on this piece of code `w.addEventListener("touchmove", move);` Also because of this my hamburger menu has stopped working because of this error. Got any ideas :) – Ryan Kerswell Apr 29 '15 at 20:32
  • I have no errors in the JavaScript code using the HTML and CSS you provided in the jsfiddle. Therefore the error is caused by something else unless you altered the code. Make sure that you are placing the code in `$(document).ready();` as I have done in the code provided. Try putting an id on the div and use `document.getElementById("id")` instead of `document.getElementsByClassName("reveal-visible")[0]`. If you do use getElementsByClassName, make sure to put the index at the end, ex: `[0]`. Use logging to locate your exact problem: `console.log("place these strategically")`. – chRyNaN Apr 29 '15 at 20:50
  • Ok found the problem. The code you supplied was correct but if I duplicate it inside the same JS file this is where the error "Uncaught TypeError: Cannot read property 'addEventListener' of undefined" comes up. By separating the code to a separate JS file it solves the problem. Thank you ;) – Ryan Kerswell Apr 29 '15 at 21:21
  • Glad to hear you figured it out. – chRyNaN Apr 29 '15 at 21:26