entre Desarrolladores

Recibe ayuda de expertos

Registrate y pregunta

Es gratis y fácil

Recibe respuestas

Respuestas, votos y comentarios

Vota y selecciona respuestas

Recibe puntos, vota y da la solución

Pregunta

1voto

Pull to refresh en JQuery Mobile

Hola.
Mi objetivo es hacer que una "page" de jquery mobile tenga la funcionalidad de "pull to refresh", la pagina no es una simple listview sino una pagina "custom" que crece X hacia abajo.
He probado varios plugins de jquery y librerias pero ninguna funciona bien en jquery mobile. Algunas no cojen siempre el evento de "pull" y simplemente arrastras la pantalla, otras lo hacen, pero siempre, tu haces scroll para bajar y al intentar subir, magia, refresh en lugar de scroll.
Yo creo que el problema de algunas de estas librerias erradica en que jquery mobile hace el scroll como le sale de ...

Alguien conoce alguna libreria/plugin que funcione correctamente en jquery mobile.

Gracias de antemano, estoy desesperado ya, no deberia ser tan dificil encontrar esa funcionalidad.

0voto

white comentado

Hola @Portal-P, podrias agregar el codigo que tienes hasta el momento? asi como describir que plugins intentaste y no te funcionaron como esperabas?

En ocasiones tenemos que modificar o agregarle un hack a un plugin o código para que funcione de acuerdo a nuestras necesidades.


otras lo hacen, pero siempre, tu haces scroll para bajar y al intentar subir, magia, refresh en lugar de scroll.

talvez si agregas una condicional a este plugin podrias prevenir que el evento scroll se gatille en x posicion, por ejemplo:

page.onPull(function()
{
    if( window.scrollY() < 20 ) // solo refrescar si el scroll en Y esta por debajo de 10
        refresh();
    else
        return false;
});

0voto

Portal-P comentado

Hola @white, gracias por contestar.
Los plugin que he provado que al menos hasn funcionado son:

  • https://github.com/visiongeist/pull-to-refresh-js
    Este crea un nuevo scroll que no se comporta del todo bien con el ya existente y buene la .
  • https://github.com/luis-kaufmann-silva/jquery-p2r
    Este es el que al hacer scroll coje el evento de refresh siempre que se tira de la pagina para abajo, este en el punto que este del scroll.
  • https://github.com/sjovanovic/xpull
    Este es el que mejor resultado me ha dado pero como jquery mobile hace scroll sobre la "page" en lugar del "content" y el "header" esta dentro del "page" este plugin desplaza el header fuera del margen superior donde el esconde el indicador de refresco, he fijado el header a "top: 41px" pero al hacer el pull desplaza tambien el header no solo el contenido y no queda bien.

El codigo de la pagina es el estandar similar a este:

<body>
  <div data-role="page" id="page1">
    <div data-role="header" data-tap-toggle="false" data-position="fixed">
      <h3>Header</h3>
    </div>
    <div data-role="content">
      Contenido
    </div>
  </div>
</body>

Lo que he pensado hacer y estoy probando es quitar el position fixed del header y con js forzar el height del content al tamaño de la pantalla el del header y ponerle overflow-y:auto; al content y entonces usar el plugin "xpull".

Si me da resultado lo digo, sino mirare de modificar el comportamiento de los plugins como dices.

Gracias.

0voto

white comentado

movido a respuesta

1 Respuesta

3votos

white Puntos75880

Si ningun plugin logra hacer lo que deseas, lo mejor es que crees uno de acuerdo a tus necesidades, despues de todo tienes jQuery mobile y este da facilidades.

Aca te dejo un simple plugin que hize:

var pullFresh = function(selector, options)
{
    'use strict';

    if( $(selector).find('._wrapper').length === 0)
    {
        $(selector).css('position', 'relative');
        $(selector).wrapInner('<div class="_wrapper">');
    }

    var container = $(selector).find('._wrapper'),
        drag = false,
        start_pos,
        callbacks = {},
        perform_callback = function(callback)
        {
            var args = Array.prototype.slice.call(arguments);

            if(callbacks[callback])
                callbacks[callback].apply(null, args.slice(1));
        },
        pull_pos = function()
        {
            return parseInt($(container).css('top'), 10);
        },
        reset_pos = function()
        {
            drag = false;

            $(container).stop().animate({
                top : 0
            }, 100);
        },
        set_default_opts = function(options)
        {
            var default_opts = {
                threshold : 100,
                offsetTop : 0
            };

            for(var opt in default_opts)
            {
                if( !options[opt] )
                    options[opt] = default_opts[opt];
            }

            return options;
        };

    options = set_default_opts(options || {});

    this.on = function(type, callback)
    {
        if( $.inArray(type, ['refresh', 'pull', 'start-pull', 'end-pull', 'init']) === -1)
            return false;

        callbacks[type] = callback;

        return this;
    }

    if( isNaN(pull_pos) )
    {
        $(container).css({
            'top': 0,
            'position' : 'relative'
        });
    }

    $(container).on('vmousedown', function(event){
        drag = true;
        start_pos = event.pageY;
        perform_callback('start');
    });

    $(container).on('vmouseup vmouseleave', function(event){
        drag = false;
        reset_pos();
        perform_callback('end-pull');
    });

    $(container).on('vmousemove', function(event){

        var pull_offset = (event.pageY - start_pos),
            pull_percentage;

        if( !drag )
            return false;

        if( ($(window).scrollTop() - $('.content').offset().top) > options.offsetTop )
            return false;

        if( pull_offset >= options.threshold ||  pull_offset < 0)
        {
            reset_pos();

            perform_callback('end-pull');

            if(pull_offset >= options.threshold)
                perform_callback('refresh');

            return false;
        }

        $(container).css('top', pull_offset);

        perform_callback('pull', pull_offset, (pull_offset * 100) / options.threshold);
    });

    return this;
};

funciona de esta forma:

new pullFresh('.selector', {
    threshold : 200
})
.on('refresh', function()
{

})
.on('pull', function(pos, percentage)
{

})
.on('end-pull', function()
{

});

la sintaxis:

new pullFresh( selector, opciones )
.on( evento, callback() )


demo:

http://jsfiddle.net/9zcccnkf/1/embedded/result/
http://jsfiddle.net/9zcccnkf/1/

0voto

Portal-P comentado

He probado tu solucion, funciona solo en navegador.
A la que lo usas desde un dispositivo mobil no funciona porque escuchas es evento del mouse en lugar del tap.
Ese es el problema de los demas plugins o similar.
Escuchan el tap para hacer el refresh pero jquery tambien lo hace para hacer el scroll. Resultado, o va uno o va el otro.

La solucion que plantee me da resultado en escala test, me falta implementarla en la app para ver si resulta.
http://jsfiddle.net/t3h9wecq/
En web no cuadra pero esta pensado para usarse en mobile.

Muchas gracias igualmente por haberte molestado en idear una solucion.

0voto

white comentado

Estas seguro? Yo use los eventos vmousedown , vmouseleave, etc que son eventos que trabajan tanto en móviles como en escritorio. Yo lo probé en firefox y chrome android y me funciona bien. Que navegador usaste?

PD: lo probé en chrome y parece que tiene una característica para refrescar la pagina al hacer pull. Una solución es evitar que el scroll se ponga en cero en el evento "touchmove".


PD2: actualizado el código.

  • corregido el problema con la caracteristica "pull-to refresh" de chrome mobile
  • agregada compatibilidad para animacion css3 al hacer pull
  • agregada propiedad -webkit-overflow-scrolling: touch

testado en chrome android y firefox.

por corregir:

  • mejor comportamiento para firefox en el evento vmousemove, al momento se congela por un segundo.
  • agregar mas opciones para el usuario.

http://embed.plnkr.co/yVNvaz4VBLyOqII76S0u/preview
http://plnkr.co/edit/yVNvaz4VBLyOqII76S0u?p=preview

0voto

Portal-P comentado

Lo estoy provando desde safari ipad.
La plataforma sera ipad con cordova asi que el motor sera el de safari.
Solo funciona el pull2refresh pero no el scroll.

0voto

white comentado

El problema esta en event.preventDefault(), he corregido el script.

http://run.plnkr.co/aG4JMQ5IkJN0skeh/
http://plnkr.co/edit/xUxqkoHG2UKptS2DwxCB?p=preview

saludos!

Por favor, accede o regístrate para responder a esta pregunta.

Otras Preguntas y Respuestas


...

Bienvenido a entre Desarrolladores, donde puedes realizar preguntas y recibir respuestas de otros miembros de la comunidad.

Conecta