cubiq/SwipeView

Not compatible with JQuery Mobile 1.20

jvence opened this issue · 17 comments

When I add <script type="text/javascript" src="./js/jquery.mobile-1.2.0.js"></script> to the demo index.html, it starts throwing the following javascript exceptions:

TypeError: 'undefined' is not an object (evaluating 'this.masterPages[this.currentMasterPage].className')

TypeError: 'undefined' is not an object (evaluating 'gallery.masterPages[gallery.currentMasterPage].className')

It work fine if JQM is disabled.

I wrapped the SwipeView demo in a jQuery Mobile page and it doesn't work either. I don't get any errors in the console.

swipeview works inside our JQM 1.3 app, see here
not without some glitches, but without JS errors

That link shows a blank page... Can you show some code of how you got JQM working with SwipeView?

sorry @jtoth55, we upgraded the server and had some problem with this sample app. Fixed, pls try again. Btw, since the last post we moved to jqm 1.3.1

I have tested on Jquery mobile 1.3.1. It doesn't work. If it possible can you show me working example on JM 1.3.1?

@Splintex can you try to look at my friends list
It is using SwipeView with jqm 1.3.1
Make the window narrow or look at it on mobile.
Let me know how this works for you, it is not smooth but should work.

I had the same problem. The problem was that the clientWidth of the wrapper is 0 until the page is shown. I fixed by initializing the SwipeView when the first "pageshow" event is fired :

(viewChoixPhotos is the jquery mobile page which contains the SwipeView)

    $("#viewChoixPhotos").on("pageshow", function (event) {
        if (typeof (wrapper) == "undefined") {
            document.addEventListener('touchmove', function (e) { e.preventDefault(); }, false);

            var el,
            i,
            page,
            dots = document.querySelectorAll('#nav li'),
            slides = [
                {
                    img: 'img/photo_vide.png',
                    desc: 'Photo 1'
                },
                {
                    img: 'img/photo_vide.png',
                    desc: 'Photo 2'
                },
            ];

            wrapper = new SwipeView('#wrapperCarouselPhotos', { numberOfPages: slides.length });
            ...

Hope that helps.

@pierreandreline Where did you end the check for the if (typeof (wrapper))? Did you have an else?

@ejimenez93 : no, I have no "else" code, because the wrapper is instanciated just once, the fisrt time the page is shown. The "if (typeof (wrapper) == "undefined")" in the "pageshow" event checks if the wrapper has been already instanciated. If not, then do it, if yes then nothing else to do :


the HTML code of the jquery page in which I add the SwipeView :


        <div data-role="page" id="viewChoixPhotos" data-theme="a">
            <div data-role="header">
                <a href="#viewChoixStade" data-role="button" data-icon="back" data-transition="slide" data-direction="reverse" >Retour</a>
                <h1>Choix des photos</h1>
            </div><!-- /header -->

            <div data-role="content" style="text-align:center">

                <ul data-role="listview" data-inset="true">
                    <li class="ui-listview-inset-choixphotos" onclick="getPhoto('gallery')">
                        <a href="#">
                            <img src="img/ouvrir_photo.png" />
                            <h1>Ouvrir la galerie</h1>
                        </a>
                    </li>
                    <li class="ui-listview-inset-choixphotos" onclick="getPhoto('camera')">
                        <a href="#">
                            <img src="img/prendre_photo.png" />
                            <h1>Pendre une photo</h1>
                        </a>
                    </li>
                    <li id="boutonChargerImagePc" class="ui-listview-inset-choixphotos">
                            <h3>Choisir une photo (PC)</h3>
                            <input id="inputFile" type="file" name="mesfichiers" />
                    </li>
                </ul>

                <ul id="nav">
                    <li id="prev" onclick="carouselPhotos.prev()">-</li>
                    <li class="selected" onclick="carouselPhotos.goToPage(0)"></li>
                    <li onclick="carouselPhotos.goToPage(1)"></li>
                    <li onclick="carouselPhotos.goToPage(2)"></li>
                    <li onclick="carouselPhotos.goToPage(3)"></li>
                    <li id="next" onclick="carouselPhotos.next()">+</li>
                </ul>               
                <div id="wrapperCarouselPhotos"></div>

            </div><!-- /content -->

            <div data-role="footer">
                <h1>www.visiocrop.com</h1>
            </div><!-- /header -->
        </div><!-- /page -->

Event listener of the "pageshow" event of the jquery page (id=viewChoixPhotos):


        $("#viewChoixPhotos").on("pageshow", function (event) {
            if (typeof (carouselPhotos) == "undefined")
                initChoixPhotos();
        });

initChoixPhotos() function that instanciate and initialize the SwipeView :

(the name of the div in which I create the wrapper is wrapperCarouselPhotos)

(the name of the wrapper( SwipeView instance) is carouselPhotos)

initChoixPhotos = function () {
    document.addEventListener('touchmove', function (e) { e.preventDefault(); }, false);
    //var el,
    //i,
    //page,
    dots = document.querySelectorAll('#nav li'),
    slides = [
        {
            img: 'img/photo_vide.png',
            desc: 'Photo 1'
        },
        {
            img: 'img/photo_vide.png',
            desc: 'Photo 2'
        },
        {
            img: 'img/photo_vide.png',
            desc: 'Photo 3'
        },
        {
            img: 'img/photo_vide.png',
            desc: 'Photo 4'
        }

    ];

    carouselPhotos = new SwipeView('#wrapperCarouselPhotos', { numberOfPages: slides.length });

    // Load initial data
    var w = document.getElementById("wrapperCarouselPhotos");
    var photoWidth = w.clientWidth - 40; // document.width - 40;
    var photoHeight = photoWidth * 112 / 200;
    //w.style.height = String(photoHeight + 40) + "px";
    for (i = 0; i < 3; i++) {
        page = i == 0 ? slides.length - 1 : i - 1;
        el = document.createElement('img');
        el.className = 'loading';
        el.src = slides[page].img;
        el.width = photoWidth;
        el.height = photoHeight;
        el.onload = function () { this.className = ''; }
        carouselPhotos.masterPages[i].appendChild(el);

        el = document.createElement('span');
        el.innerHTML = slides[page].desc;
        carouselPhotos.masterPages[i].appendChild(el)
    }

    carouselPhotos.onFlip(function () {
        var el,
        upcoming,
        i;

        for (i = 0; i < 3; i++) {
            upcoming = carouselPhotos.masterPages[i].dataset.upcomingPageIndex;

            if (upcoming != carouselPhotos.masterPages[i].dataset.pageIndex) {
                el = carouselPhotos.masterPages[i].querySelector('img');
                el.className = 'loading';
                el.src = slides[upcoming].img;
                el.width = photoWidth;
                el.height = photoHeight;

                el = carouselPhotos.masterPages[i].querySelector('span');
                el.innerHTML = slides[upcoming].desc;
            }
        }

        document.querySelector('#nav .selected').className = '';
        dots[carouselPhotos.pageIndex + 1].className = 'selected';
    });

    // Abonnement au chargement d'une image pour l'interface web (hors appli mobile)
    var inputFile = document.getElementById("inputFile");
    inputFile.addEventListener("change", function (evt) {
        var fichier = this.files[0];
        var reader = new FileReader();
        reader.onload = function (e) {

            var photo = new Image();
            photo.onload = function () {
                ratio = photo.width / photo.height;
                Pixastic.process(photo, "resize", { "width": 640, "height": Math.floor(640 / ratio) },
                        function (oCanvas) {
                            ajouterPhoto(oCanvas.toDataURL(), oCanvas.toDataURL("image/jpeg", 0.1), fichier.name);
                        });
            }
            photo.src = e.target.result;


        }
        reader.readAsDataURL(fichier);
    }, false);


    carouselPhotos.onMoveOut(function () {
        carouselPhotos.masterPages[carouselPhotos.currentMasterPage].className = carouselPhotos.masterPages[carouselPhotos.currentMasterPage].className.replace(/(^|\s)swipeview-active(\s|$)/, '');
    });

    carouselPhotos.onMoveIn(function () {
        var className = carouselPhotos.masterPages[carouselPhotos.currentMasterPage].className;
        /(^|\s)swipeview-active(\s|$)/.test(className) || (carouselPhotos.masterPages[carouselPhotos.currentMasterPage].className = !className ? 'swipeview-active' : className + ' swipeview-active');
    });
}

https://github.com/ejimenez93 @ejimenez93 : no, I have no "else" code, because the wrapper is instanciated just once, the fisrt time the page is shown. The "if (typeof (wrapper) == "undefined")" in the "pageshow" event checks if the wrapper has been already instanciated. If not, then do it, if yes then nothing else to do :


the HTML code of the jquery page in which I add the SwipeView :


    <div data-role="page" id="viewChoixPhotos" data-theme="a">

        <div data-role="header">

            <a href="#viewChoixStade" data-role="button" data-icon="back" data-transition="slide" data-direction="reverse" >Retour</a>

            <h1>Choix des photos</h1>

        </div><!-- /header -->



        <div data-role="content" style="text-align:center">



            <ul data-role="listview" data-inset="true">

                <li class="ui-listview-inset-choixphotos" onclick="getPhoto('gallery')">

                    <a href="#">

                        <img src="img/ouvrir_photo.png" />

                        <h1>Ouvrir la galerie</h1>

                    </a>

                </li>

                <li class="ui-listview-inset-choixphotos" onclick="getPhoto('camera')">

                    <a href="#">

                        <img src="img/prendre_photo.png" />

                        <h1>Pendre une photo</h1>

                    </a>

                </li>

                <li id="boutonChargerImagePc" class="ui-listview-inset-choixphotos">

                        <h3>Choisir une photo (PC)</h3>

                        <input id="inputFile" type="file" name="mesfichiers" />

                </li>

            </ul>



            <ul id="nav">

                <li id="prev" onclick="carouselPhotos.prev()">-</li>

                <li class="selected" onclick="carouselPhotos.goToPage(0)"></li>

                <li onclick="carouselPhotos.goToPage(1)"></li>

                <li onclick="carouselPhotos.goToPage(2)"></li>

                <li onclick="carouselPhotos.goToPage(3)"></li>

                <li id="next" onclick="carouselPhotos.next()">+</li>

            </ul>               

            <div id="wrapperCarouselPhotos"></div>



        </div><!-- /content -->



        <div data-role="footer">

            <h1>www.visiocrop.com</h1>

        </div><!-- /header -->

    </div><!-- /page -->

Event listener of the "pageshow" event of the jquery page (id=viewChoixPhotos):


    $("#viewChoixPhotos").on("pageshow", function (event) {

        if (typeof (carouselPhotos) == "undefined")

            initChoixPhotos();

    });

initChoixPhotos() function that instanciate and initialize the SwipeView :

(the name of the div in which I create the wrapper is wrapperCarouselPhotos)

(the name of the wrapper( SwipeView instance) is carouselPhotos)

initChoixPhotos = function () {

document.addEventListener('touchmove', function (e) { e.preventDefault(); }, false);

//var el,

//i,

//page,

dots = document.querySelectorAll('#nav li'),

slides = [

    {

        img: 'img/photo_vide.png',

        desc: 'Photo 1'

    },

    {

        img: 'img/photo_vide.png',

        desc: 'Photo 2'

    },

    {

        img: 'img/photo_vide.png',

        desc: 'Photo 3'

    },

    {

        img: 'img/photo_vide.png',

        desc: 'Photo 4'

    }



];



carouselPhotos = new SwipeView('#wrapperCarouselPhotos', { numberOfPages: slides.length });



// Load initial data

var w = document.getElementById("wrapperCarouselPhotos");

var photoWidth = w.clientWidth - 40; // document.width - 40;

var photoHeight = photoWidth * 112 / 200;

//w.style.height = String(photoHeight + 40) + "px";

for (i = 0; i < 3; i++) {

    page = i == 0 ? slides.length - 1 : i - 1;

    el = document.createElement('img');

    el.className = 'loading';

    el.src = slides[page].img;

    el.width = photoWidth;

    el.height = photoHeight;

    el.onload = function () { this.className = ''; }

    carouselPhotos.masterPages[i].appendChild(el);



    el = document.createElement('span');

    el.innerHTML = slides[page].desc;

    carouselPhotos.masterPages[i].appendChild(el)

}



carouselPhotos.onFlip(function () {

    var el,

    upcoming,

    i;



    for (i = 0; i < 3; i++) {

        upcoming = carouselPhotos.masterPages[i].dataset.upcomingPageIndex;



        if (upcoming != carouselPhotos.masterPages[i].dataset.pageIndex) {

            el = carouselPhotos.masterPages[i].querySelector('img');

            el.className = 'loading';

            el.src = slides[upcoming].img;

            el.width = photoWidth;

            el.height = photoHeight;



            el = carouselPhotos.masterPages[i].querySelector('span');

            el.innerHTML = slides[upcoming].desc;

        }

    }



    document.querySelector('#nav .selected').className = '';

    dots[carouselPhotos.pageIndex + 1].className = 'selected';

});



// Abonnement au chargement d'une image pour l'interface web (hors appli mobile)

var inputFile = document.getElementById("inputFile");

inputFile.addEventListener("change", function (evt) {

    var fichier = this.files[0];

    var reader = new FileReader();

    reader.onload = function (e) {



        var photo = new Image();

        photo.onload = function () {

            ratio = photo.width / photo.height;

            Pixastic.process(photo, "resize", { "width": 640, "height": Math.floor(640 / ratio) },

                    function (oCanvas) {

                        ajouterPhoto(oCanvas.toDataURL(), oCanvas.toDataURL("image/jpeg", 0.1), fichier.name);

                    });

        }

        photo.src = e.target.result;





    }

    reader.readAsDataURL(fichier);

}, false);





carouselPhotos.onMoveOut(function () {

    carouselPhotos.masterPages[carouselPhotos.currentMasterPage].className = carouselPhotos.masterPages[carouselPhotos.currentMasterPage].className.replace(/(^|\s)swipeview-active(\s|$)/, '');

});



carouselPhotos.onMoveIn(function () {

    var className = carouselPhotos.masterPages[carouselPhotos.currentMasterPage].className;

    /(^|\s)swipeview-active(\s|$)/.test(className) || (carouselPhotos.masterPages[carouselPhotos.currentMasterPage].className = !className ? 'swipeview-active' : className + ' swipeview-active');

});

}

De : ejimenez93 [mailto:notifications@github.com]
Envoyé : lundi 24 juin 2013 23:21
À : cubiq/SwipeView
Cc : pierreandreline
Objet : Re: [SwipeView] Not compatible with JQuery Mobile 1.20 (#41)

@pierreandreline https://github.com/pierreandreline Where did you end the check for the if (typeof (wrapper))? Did you have an else?


Reply to this email directly or view it on GitHub #41 (comment) . https://github.com/notifications/beacon/P3x0b3dhCLcPh3OObmgwbfqbHWT2yxJLX4IIvzO748Zgy_kIagbcSlS9pc0qHe7H.gif

@pierreandreline Thanks a bunch for your help. It fixed the problem!

@ejimenez93 - Your fix worked for me too but it disables the vertical scroll on the inline SwipeView. Any idea why this might be the case? Thanks!

@Doug1818 I'm actually trying to figure that out as well. Right now, the only thing I have is an "overflow-y: auto" on the #swipeview-slider. However, this only seems to allow scrolling on the desktop and not on a mobile, touchscreen device.

@ejimenez93 - Ya, that's exactly what's happening to me. I think it's because the touchmove event is being called and then returning false, which I think disables the scroll. Not sure how to reverse this though.

@ejimenez93 - I think I've figured it out. Seems that using the touchmove event was in fact the problem. Using pageshow instead of touchmove as below worked for me.

document.addEventListener('pageshow', function (e) { e.preventDefault(); }, false);

Yes, I had the same problem. Forgot to mention. I did not check why but removing the 'touchmove' listener fixed it:

    //document.addEventListener('touchmove', function (e) { e.preventDefault(); }, false);

And it worked both on mobile & desktop.
Hope this helps.

@Doug1818 @pierreandreline You guys are awesome! That did the trick. Thank you!