cubiq / SwipeView

Virtually infinite loop-able horizontal carousel
MIT License
698 stars 167 forks source link

Not compatible with JQuery Mobile 1.20 #41

Open jvence opened 11 years ago

jvence commented 11 years ago

When I add 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.

benjamingeorge commented 11 years ago

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.

urbien commented 11 years ago

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

jtoth55 commented 11 years ago

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

urbien commented 11 years ago

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

Splintex commented 11 years ago

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?

urbien commented 11 years ago

@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.

pierreandreline commented 11 years ago

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.

ejimenez93 commented 11 years ago

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

pierreandreline commented 11 years ago

@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');
    });
}
pierreandreline commented 11 years ago

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 https://github.com/cubiq/SwipeView/issues/41#issuecomment-19936802 . https://github.com/notifications/beacon/P3x0b3dhCLcPh3OObmgwbfqbHWT2yxJLX4IIvzO748Zgy_kIagbcSlS9pc0qHe7H.gif

ejimenez93 commented 11 years ago

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

Doug1818 commented 11 years ago

@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!

ejimenez93 commented 11 years ago

@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.

Doug1818 commented 11 years ago

@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.

Doug1818 commented 11 years ago

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

pierreandreline commented 11 years ago

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.

ejimenez93 commented 11 years ago

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