LazyLoad pas très paresseux sous Chrome et Opera

Les nouveaux éléments sont ajoutés comme s'ils avaient déjà été dépassés par défilement dans ces deux navigateurs

a marqué ce sujet comme résolu.

Bonjour à tous !

Je reviens à la charge pour des questions de réalisations cross-broswers

Comme bien d’autres avant moi, j’ai voulu réaliser un script de lazy-loading pour des lignes de tableaux. Comme j’ai l’habitude de Firefox, j’ai fait mes essais avec ce navigateur, tout allait bien. Je tente avec le dernier Safari, tip-top. Mais avec Chrome, le chargement n’est plus trop paresseux… Sans avoir de IE sous la main, je tente quand-même avec Opera, qui a le même comportement que Chrome.
Du peux que j’arrive à comprendre, les éléments chargés par AJAX s’ajoutent au-dessus de la limite inférieure que j’ai déjà atteinte en défilant. Et c’est comme s’il y avait un nouveau défilement pour arriver au bas du contenu…

Voici mon détecteur actuel.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
$container = $('.table-responsive');
$container.scroll( function(e) {
    var $scrolled = $(e.target);
    var $table = $scrolled.find('table.ajax-table');
    var identifier = $table.closest('[id]').attr('id');
    if (!$table.length) {
        return;
    }
    if (((typeof ajaxTableLoading[identifier] === 'undefined') || (typeof ajaxTableLoading[identifier] !== 'undefined') && !ajaxTableLoading[identifier]) && ($scrolled.scrollTop() + $scrolled.innerHeight() >= $scrolled[0].scrollHeight - 5)) {
        ajaxTableLoading[identifier] = true;
        e.preventDefault();
        loadMore($table);
    }
})
Ce que j’utilise actuellement pour détecter si je dois charger plus d’éléments

ajaxTableLoading[identifier] est remis à false dans l’événement complete de l’appel AJAX — ce n’est pas le souci, sans quoi je n’arriverais pas à avoir le comportement souhaité sous Firefox.
N.B. : sous Firefox, ça fonctionne aussi sans la linge 11.

Est-ce que quelqu’un saurait comment éviter ce "défilement" inopportun, ou en tout cas permettre un chargement vraiment lazy ?

Merci d’avance.

+0 -0

Bonjour,

J’ai écris un long pavé expliquant mon point de vue, puis je me suis dit que je n’étais pas clair tout en ne comprenant pas ou tu butais, du coup j’ai moi aussi écris un petit code; j’espère qu’il t’aiderai :)

Marche avec FireFox, Google Chrome, Edge et Internet Explorer (pas testé Safari ni Opera)

+1 -0

Merci La source, ta solution fonctionne aussi sous Safari et Opera, pour ceux qui se demanderaient.

En fait, ce que je ne saisis pas, c’est pourquoi sous Chrome et Opera (mais étrangement pas Safari, j’aurais volontiers extrapolé à "les navigateurs Webkit"), quand on ajoute dynamiquement des lignes à un tableau comme je le fais, c’est comme si je re-scrollais jusqu’en bas immédiatement, ce que Firefox et Safari ne me font pas. Ajouter des lignes dans le tableau semblent déclencher un défilement dans mon exemple sous Chrome et Opera. Pourquoi donc est-ce que ces deux navigateurs estiment qu’on veut rester "en bas de conteneur" alors qu’on ajoute du nouveau contenu ? Sachant que cette "estimation" implique apparemment un défilement…

J’espère que j’arrive à me faire comprendre  :p

J’ai vu que tu avais mis un throttle, mais je ne comprends pas pourquoi ça règle le problème, en fait, sachant que j’ai justement tenté de scroller le plus lentement possible jusqu’à déclencher le chargement, et immédiatement ne plus rien toucher (aucun défilement supplémentaire, la molette ne bouge plus d’un cran), et que ça ne change rien…
Mais du coup, je vais probablement faire le gros moche et mettre un timeout pour faire ajaxLoading[identifier] = true

+0 -0

Le throttle c’est parce que lorsqu’on bouge l’ascenseur (avec la molette ou la souris) en réalité un tas d’événements sont émis, suffit de placer un console.log dans la fonction pour s’en rendre compte. Du coup c’est risquer d’exécuter la fonction de chargement plusieurs fois alors qu’on aurai aimé que cela ne le fasse qu’une seule fois.

+0 -0

C’est justement pour éviter de lancer la fonction plusieurs fois que j’ai mon ajaxLoading[identifier].
Vous pouvez réessayer avec cette mise à jour où je simule un temps de réponse de 4 secondes, rien d’autre n’est changé : aucune autre requête lancée pendant que la précédente charge. Le souci ne vient donc pas de ce que j’avais plusieurs requêtes lancées en parallèle (et du coup, en fait, je récupérerais plusieurs fois les mêmes informations, ce qui ne se voit pas avec mon exemple et à quoi j’avais fait attention), mais vraiment qu’il y a un événement scroll (ou assimilé pour Chrome et Opera) qui est lancé une fois la page mise à jour.

Sans ce comportement que je cherchais initialement à éviter, je ne serais pas venu ici ^^

Edit

Ajouter un throttle à mon code actuel ne résout pas le truc, en tout cas.

+0 -0

On s’est mal compris, j’ai jamais affirmé que le throttle était la solution à ton problème.

Le problème est ailleurs, le fait que ton code est un peu lourd du coup aide pas ^^ (plus de chose que juste le problème d’ascenseur).

Le premier soucis que je remarque est la condition de déclenchement du chargement $scrolled.scrollTop() + $scrolled.innerHeight() >= $scrolled[0].scrollHeight - 5 alors que j’aurai écris $this[0].scrollHeight - $this.scrollTop() - 5 < $this.innerHeight() mais en changeant le code sa n’a pas d’incidence.

Après ce qui se passe, c’est que tu ajoute des éléments dans ton tableau et ton ascenseur reste toujours tout en bas alors qu’avec mon code la position relative de mon ascendeur remonte. J’en déduis que le problème est là.

Après quelques bidouille, le problème est ta "notification" du loader; elle est dans le tableau ce qui repositionne l’ascenseur avec la fonction show et hide (probablement plus la faute de show) ce qui revalide la condition de chargement…

+1 -0

Le plus surprenant est que si on remonte dans le tableau, il n’y a pas ce problème  o_O
Ça survient vraiment que quand on est à 5 pixels du bas. Si on est remonté de plus entre-temps (pendant le temps de réponse), je n’observe pas le comportement…

On s’est mal compris

La source

Comme quoi c’est pas simple d’expliquer quelque chose qu’on aimerait comprendre :lol:
Aucun souci  ;)

+0 -0

Je creuse toujours, et je me dis encore qu’il y a un événement empilé quelque part qui se dépile selon une condition qui m’échappe…

J’ai ajouté un timeout pour mon pseudo-throttle, mais le comportement persiste. Seulement maintenant, il attend un moment avant de relancer automatiquement la requête…

+0 -0

Mais… Mais… Mais… Je croyais que c’était réglé :(

La source

Non, sans quoi j’aurais au moins mis le sujet en résolu, et j’aurais probablement donné l’explication ainsi qu’un éventuel moyen de pallier le problème  :D

Sort ton loader (texte chargement) du tableau et sa va allé nickel (autrement dit, bazarde le tfoot)

La source

C’est ce que je vais faire au final, mais je laisse volontairement le sujet comme étant non-résolu tant que je n’ai pas le fin mot de l’histoire, parce que ça me titille bien plus qu’un peu.

+0 -0
Connectez-vous pour pouvoir poster un message.
Connexion

Pas encore membre ?

Créez un compte en une minute pour profiter pleinement de toutes les fonctionnalités de Zeste de Savoir. Ici, tout est gratuit et sans publicité.
Créer un compte