5 Stimmen

JavaScript window.scroll delay verursacht asynchrones Neuzeichnen

Die Zielsetzung

Ich habe also eine Liste von <div> s in einem einspaltigen Layout, die entweder die Klasse "aktiv" oder "inaktiv" haben. Bei der aktiven Klasse wird rechts neben dem Element eine Grafik angezeigt, bei der inaktiven Klasse nicht. Ich habe es so eingerichtet, dass die "aktive" Klasse (und die dazugehörige Grafik) durch Drücken der Pfeiltaste nach oben oder unten zum vorherigen oder nächsten Element verschoben wird. Es ist nicht animiert, aber man kann visuell sehen, wie die Grafik verschwindet und auf dem Tag darüber oder darunter wieder auftaucht.

Jetzt möchte ich, dass die Seite beim Drücken der Pfeiltaste nach unten scrollt, so dass der obere Rand des Elements immer an der gleichen Stelle ist. Da die Elementliste größer ist als das Seitenfenster, muss der Browser automatisch gescrollt werden, damit das ausgewählte Element immer an der gleichen Stelle erscheint. <div> ist immer in der Mitte des Bildschirms...

Der Kodex

//Paging through items with arrow keys
theWindow.keydown(function (e) {
    var key = e.keyCode,
        oldItem = $('li.active')

    if ((key === 40 && oldItem.next().length) || (key === 38 && oldItem.prev().length)) {
        var theWindowMod = (window.innerHeight / 2) + 43,
            theHTML = $('html'),
            theDetail = $('.detail')

        theHTML.addClass('notransition')

        if (key === 40 && oldItem.next().length) {
            oldItem.removeClass('active').next().addClass('active')
        } else if (key === 38 && oldItem.prev().length) {
            oldItem.removeClass('active').prev().addClass('active')
        }

        var newItem = $('li.active')

        window.scroll(0, newItem.offset().top - theWindowMod)
        e.preventDefault()
        $('.detail-inner.active').fadeOut(0).removeClass('active')
        $('section.active, .tab.active').removeClass('active')
        newItem.find('.tab').add(theDetail).addClass('active')
        theDetail.find('.detail-' + newItem.attr('class').split(' ')[0]).addClass('active').fadeIn(0)

        setTimeout(function () {
            theHTML.removeClass('notransition')
        }, 1)
    }
});

Das Problem

Das Problem ist dass die window.scroll-Methode in allen Versionen von Safari, aber in keinem anderen Browser, leistungsmäßig ein wenig hinter der CSS-Klassenumschaltung zurückbleibt. Was passiert, ist, dass sie in zwei verschiedenen Redraw-Ereignissen landen und es so aussieht, als würde die Seite "glitchen", wenn man nach unten scrollt, weil man kurz die Grafik rechts vom nächsten Element sehen kann, bevor der Browser nach unten scrollt.

Die Live-Demo

Sie können es hier live sehen:

http://hashtag.ly/#minecraft

Verwenden Sie die Pfeiltasten, um durch die Einträge zu blättern. Beachten Sie den Sprung. Wie soll ich das Problem lösen?

1voto

ATOzTOA Punkte 32520

Versuchen Sie es mit einer Schaltfläche anstelle des div und verwenden Sie setfocus(), wenn das entsprechende Element aktiviert ist. Der Browser scrollt dann automatisch, um die fokussierte Schaltfläche immer sichtbar zu machen. Sie können CSS verwenden, um die Schaltfläche genauso aussehen zu lassen wie das div.

1voto

tiffon Punkte 4870

Ich denke, eine Lösung, die das Problem vermeidet, ist die beste Lösung.

Aus einer UX-Perspektive betrachtet, mag ich es nicht, wenn die Website die Kontrolle über die Bildlaufposition an sich reißt.

Außerdem kann für Leute mit großen Browsern (wie mich) derzeit viel weiße Fläche zwischen den Details und dem ausgewählten Beitrag liegen. (siehe Bildschirmfoto)

Details are far from selected post.

Ich empfehle, das Design so zu ändern, dass die Details neben dem ausgewählten Beitrag angezeigt werden und der Benutzer das Scrollen übernehmen kann. Die Steuerung der Position der Details mit CSS, so dass sie neben dem ausgewählten Beitrag sind, wird es in der gleichen Render-Zyklus wie alles andere setzen.

Die Details, die näher an der ausgewählten Stelle liegen, könnten etwa so aussehen:

Details closer to selected post.

Aktualisierung:

Wenn ich es mir recht überlege, hat der E-Mail-Client von AOL Alto die UX, die Sie implementiert haben. In Alto scrollt die linke Spalte automatisch, wenn Sie mit den Tasten blättern. Aber Sie scrollen nicht wirklich, sondern fügen Inhalte in das Containerelement ein und bringen sie in die Ansicht (ich habe vergessen, wie man das nennt... Virtualisierung?). Es sieht so aus, als ob sie alle mit dem Scrollen zusammenhängenden visuellen Elemente und das Verhalten selbst verwalten und nicht die systemeigene Funktionalität verwenden. Es ist also alles JS-gesteuerte CSS- und DOM-Manipulation, es gibt nicht wirklich eine scrollTo() Aufforderung. Dadurch wird alles in denselben Rendering-Zyklus integriert.

AOL Alto email

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X