2015-05-09 9 views
6

Setting scrollLeft does reset the scroll bar position i updating the content works as expected ale kiedy doing both at the same time paska przewijania pogubi i nie resetuje.Android ustawić scrollLeft podczas aktualizacji treści w przypadku przewijania nie aktualizuje pozycję przewijania

Aby zobaczyć oczekiwane zachowanie w stosunku do nieoczekiwanego zachowania, wyświetl każde demo na urządzeniu za pomocą touchpada i użyj touchpada do przewijania w lewo lub w prawo wewnątrz opakowania, a następnie spróbuj zrobić to samo na urządzeniu z Androidem.

Zauważ, że na laptopie element będzie przewijać bez końca, na urządzenie z Androidem, element będzie przewijać tylko dopóki nie osiągnie ona początkowo ustawiony „max scroll”

Co powinno się wydarzyć:

gdy użytkownik przewija w lewo lub w prawo, przesuwa pierwszy element potomny na koniec węzła lub przenosi ostatnie dziecko na początek i ustawia pozycję przewijania na połowę pierwszego elementu potomnego.

Poniżej moje próby w rozwiązaniu problemu

  1. Set transform: translateX(0px) na .innersee here który miał gorsze zachowanie niż wcześniej.

  2. Naprawiono listę wymienionych here, które było dla poprzedniego błędu w systemie Android, gdzie ustawienie scrollLeft nie działa w ogóle. To wcale nie pomogło.

  3. wrap.appendChild(inner) na każdym zdarzeniu przewijania, które spowolniło przewijanie w dół, ale nie rozwiązało problemu, ponieważ chrome zapamiętuje pozycje przewijania. Byłoby to hack nawet jeśli mogę dostać chrom zapomnieć pozycję przewijania (który wygląda jak to może być prawdopodobne, ale byłoby jeszcze inny siekać)

zdaję sobie sprawę, że mogę powąchać przeglądarkę i po prostu powrócić do jquery ui mobilny setup, ale myślę, że gdybym mógł to uruchomić, nie musiałbym używać zewnętrznej biblioteki do emulowania natywnego zachowania (a natywna zawsze jest lepsza).

var log = function(event) { 
 
    var log = document.querySelector('.log'); 
 
    log.innerHTML = event + "<br>" + log.innerHTML; 
 
}; 
 
var wrap = document.querySelector('.wrap'); 
 
var inner = document.querySelector('.inner'); 
 
var items = document.querySelectorAll('.item'); 
 
var controlLeft = document.createElement('a'); 
 
controlLeft.className = 'control control-left'; 
 
controlLeft.href = 'javascript:void(0)'; 
 
controlLeft.innerHTML = '&lt;'; 
 
controlLeft.onclick = function() { 
 
    log('click left'); 
 
    inner.scrollLeft++; 
 
}; 
 
wrap.appendChild(controlLeft); 
 
var controlRight = document.createElement('a'); 
 
controlRight.className = 'control control-right'; 
 
controlRight.href = 'javascript:void(0)'; 
 
controlRight.innerHTML = '&gt;'; 
 
controlRight.onclick = function() { 
 
    log('click right'); 
 
    inner.scrollLeft--; 
 
}; 
 
wrap.appendChild(controlRight); 
 
var darken1 = document.createElement('div'); 
 
var darken2 = document.createElement('div'); 
 
darken1.className = 'darken'; 
 
darken2.className = 'darken'; 
 
items[0].appendChild(darken1); 
 
items[2].appendChild(darken2); 
 
var getWidth = function(element) { 
 
    return Number(window.getComputedStyle(element, null).getPropertyValue('width').replace('px', '')) + 1; 
 
}; 
 
wrap.style.overflow = 'hidden'; 
 
inner.style.overflowY = 'hidden'; 
 
inner.style.overflowX = 'auto'; 
 
wrap.style.height = inner.scrollHeight + 'px'; 
 
window.onresize = function() { 
 
    wrap.style.height = inner.scrollHeight + 'px'; 
 
    inner.scrollLeft = 0; 
 
    inner.scrollLeft = getWidth(items[0])/2; 
 
}; 
 
inner.scrollLeft = getWidth(items[0])/2; 
 
oldScroll = inner.scrollLeft; 
 
inner.onscroll = function() { 
 
    if (inner.scrollLeft < oldScroll) { 
 
    log('scroll right'); 
 
    inner.appendChild(inner.querySelector('.item:first-child')); 
 
    inner.querySelector('.item:first-child').appendChild(darken1); 
 
    inner.querySelector('.item:nth-child(3)').appendChild(darken2); 
 
    } else if (inner.scrollLeft > oldScroll) { 
 
    log('scroll left'); 
 
    var first = inner.querySelector('.item:first-child'); 
 
    var last = inner.querySelector('.item:last-child'); 
 
    inner.insertBefore(last, first); 
 
    inner.querySelector('.item:first-child').appendChild(darken1); 
 
    inner.querySelector('.item:nth-child(3)').appendChild(darken2); 
 
    } 
 
    inner.scrollLeft = 0; 
 
    inner.scrollLeft = getWidth(items[0])/2; 
 
    oldScroll = inner.scrollLeft; 
 
};
*, *::before, *::after { 
 
    box-sizing: border-box; 
 
} 
 
html, 
 
body { 
 
    padding: 0; 
 
    margin: 0; 
 
    max-height: 100%; 
 
    overflow: hidden; 
 
} 
 
.wrap { 
 
    position: relative; 
 
} 
 
.control { 
 
    font-weight: bold; 
 
    text-decoration: none; 
 
    display: inline-block; 
 
    position: absolute; 
 
    padding: 10px; 
 
    background: rgba(255, 255, 255, 0.5); 
 
    top: 50%; 
 
    transform: translateY(-50%); 
 
    color: #FFF; 
 
    font-size: 20pt; 
 
} 
 
.control-left { 
 
    padding-right: 20px; 
 
    border-top-right-radius: 50%; 
 
    border-bottom-right-radius: 50%; 
 
    left: 0; 
 
} 
 
.control-right { 
 
    padding-left: 20px; 
 
    border-top-left-radius: 50%; 
 
    border-bottom-left-radius: 50%; 
 
    right: 0; 
 
} 
 
.inner { 
 
    font-size: 0; 
 
    white-space: nowrap; 
 
    overflow: auto; 
 
} 
 
.item { 
 
    position: relative; 
 
    display: inline-block; 
 
    font-size: 1rem; 
 
    white-space: initial; 
 
    padding-bottom: 33.3333%; 
 
    width: 50%; 
 
} 
 
.item .darken { 
 
    position: absolute; 
 
    top: 0; 
 
    left: 0; 
 
    right: 0; 
 
    bottom: 0; 
 
    background-color: rgba(0, 0, 0, 0.8); 
 
} 
 
.item[data-n="2"] { 
 
    background-image: url(http://www.lorempixel.com/400/300/animals); 
 
    background-size: cover; 
 
} 
 
.item[data-n="3"] { 
 
    background-image: url(http://www.lorempixel.com/400/300/business); 
 
    background-size: cover; 
 
} 
 
.item[data-n="4"] { 
 
    background-image: url(http://www.lorempixel.com/400/300/cats); 
 
    background-size: cover; 
 
} 
 
.item[data-n="5"] { 
 
    background-image: url(http://www.lorempixel.com/400/300/city); 
 
    background-size: cover; 
 
} 
 
.item[data-n="6"] { 
 
    background-image: url(http://www.lorempixel.com/400/300/food); 
 
    background-size: cover; 
 
} 
 
.item[data-n="7"] { 
 
    background-image: url(http://www.lorempixel.com/400/300/nightlife); 
 
    background-size: cover; 
 
} 
 
.item[data-n="8"] { 
 
    background-image: url(http://www.lorempixel.com/400/300/fashion); 
 
    background-size: cover; 
 
} 
 
.item[data-n="9"] { 
 
    background-image: url(http://www.lorempixel.com/400/300/people); 
 
    background-size: cover; 
 
} 
 
.item[data-n="10"] { 
 
    background-image: url(http://www.lorempixel.com/400/300/nature); 
 
    background-size: cover; 
 
} 
 
.item[data-n="11"] { 
 
    background-image: url(http://www.lorempixel.com/400/300/sports); 
 
    background-size: cover; 
 
} 
 
.item[data-n="12"] { 
 
    background-image: url(http://www.lorempixel.com/400/300/technics); 
 
    background-size: cover; 
 
} 
 
.item[data-n="13"] { 
 
    background-image: url(http://www.lorempixel.com/400/300/transport); 
 
    background-size: cover; 
 
}
<div class="wrap"> 
 
    <div class="inner"> 
 
    <div class="item" data-n="2"></div> 
 
    <div class="item" data-n="3"></div> 
 
    <div class="item" data-n="4"></div> 
 
    <div class="item" data-n="5"></div> 
 
    <div class="item" data-n="6"></div> 
 
    <div class="item" data-n="7"></div> 
 
    <div class="item" data-n="8"></div> 
 
    <div class="item" data-n="9"></div> 
 
    <div class="item" data-n="10"></div> 
 
    <div class="item" data-n="11"></div> 
 
    <div class="item" data-n="12"></div> 
 
    <div class="item" data-n="13"></div> 
 
    </div> 
 
</div> 
 
<div class="log"> 
 
</div>

+0

Co zauważyłem było to, że działa dobrze na moim laptopie. Używałem oprogramowania dell do przewijania i działało idealnie. Poza tym przewijanie bardzo szybko, jest w porządku, o ile widzę. – mashedpotats

+0

Spróbuję to przetestować. – mashedpotats

+0

OK, masz na myśli, że zdjęcia przewijają się zbyt szybko? Ponieważ wydaje się trochę szybki. – mashedpotats

Odpowiedz

1

Aby rozwiązać ten problem tymczasowo, ja owinięty funkcję w timeout. Limit czasu może wynosić zaledwie 1 milisekundę. Nie wiem dlaczego, ale zmiana zawartości i ustawienie opcji scrollLeft na dokładnie zdarzenie przewijania powoduje, że przeglądarka nie resetuje paska przewijania.

(Demo)

inner.onscroll = function() { 
    window.clearTimeout(window.updateTimeout); 
    window.updateTimeout = window.setTimeout(function() { 
    if (inner.scrollLeft < oldScroll) { 
     log('scroll right'); 
     inner.appendChild(inner.querySelector('.item:first-child')); 
    } else if (inner.scrollLeft > oldScroll) { 
     log('scroll left') 
     var first = inner.querySelector('.item:first-child'); 
     var last = inner.querySelector('.item:last-child'); 
     inner.insertBefore(last, first); 
    } 
    inner.querySelector('.item:first-child').appendChild(darken1); 
    inner.querySelector('.item:nth-child(3)').appendChild(darken2); 
    inner.scrollLeft = 0; 
    inner.scrollLeft = getWidth(items[0])/2; 
    oldScroll = inner.scrollLeft; 
    }, 1); 
}; 

Chociaż nie "naprawić" ten problem, myślę, że jest hack. Pozostawiam to pytanie otwarte, aby zobaczyć, czy mogę uzyskać prawdziwą odpowiedź.

0

Za każdym razem, gdy chcesz zmodyfikować właściwość używaną do sprawdzenia, czy pierwszy lub ostatni element musi zostać przeniesiony, modyfikujesz te same informacje ponownie, aby uzyskać nieoczekiwane zachowanie.

Twoja sztuczka dodania limitu czasu sprawiała wrażenie, że jest rozwiązaniem, ponieważ daje trochę czasu programowi, dzięki czemu może serializować zmiany informacji.

Wprowadziłem pewne zmiany w kodzie i nie wykorzystano limitu czasu. Jednak ze względu na naturę zdarzenia przewijania, w zależności od konfiguracji użytkownika w trybie przewijania, przewijana jest jedna inna liczba slajdów.

Zalecam więc dodanie pewnej weryfikacji, która może być stoperem (hahahahaha ...), ale tylko przełącza wartość boolean, aby umożliwić obsługę przewijania. Jak na poniższym snnipet:

inner.onscroll = function(e) { 
    if (!canScroll) { 
     return; 
    } 

    canScroll = false; 

    setTimeout(function() { 
     canScroll = true; 
    }, 300); 

    if (inner.scrollLeft < oldScrollLeft) { 
    // ... 

Zanim zapytasz, poczucie opóźnieniem inner.scrollLeft = 0 następnie inner.scrollLeft = getWidth(items[0])/2; świadczy to o tym overprocessing że oryginalny program zmusić przeglądarkę do zrobienia, ponieważ.

var log = function(event) { 
 
    var log = document.querySelector('.log'); 
 
    log.innerHTML = event + "<br>" + log.innerHTML; 
 
}; 
 
var wrap = document.querySelector('.wrap'); 
 
var inner = document.querySelector('.inner'); 
 
var items = document.querySelectorAll('.item'); 
 
var controlLeft = document.createElement('a'); 
 
controlLeft.className = 'control control-left'; 
 
controlLeft.href = 'javascript:void(0)'; 
 
controlLeft.innerHTML = '&lt;'; 
 
controlLeft.onclick = function() { 
 
    log('click left'); 
 
    inner.scrollLeft++; 
 
}; 
 
wrap.appendChild(controlLeft); 
 
var controlRight = document.createElement('a'); 
 
controlRight.className = 'control control-right'; 
 
controlRight.href = 'javascript:void(0)'; 
 
controlRight.innerHTML = '&gt;'; 
 
controlRight.onclick = function() { 
 
    log('click right'); 
 
    inner.scrollLeft--; 
 
}; 
 
wrap.appendChild(controlRight); 
 
var darken1 = document.createElement('div'); 
 
var darken2 = document.createElement('div'); 
 
darken1.className = 'darken'; 
 
darken2.className = 'darken'; 
 
items[0].appendChild(darken1); 
 
items[2].appendChild(darken2); 
 
var getWidth = function(element) { 
 
    return Math.floor(Number(window.getComputedStyle(element, null).getPropertyValue('width').replace('px', ''))); 
 
}; 
 
wrap.style.overflow = 'hidden'; 
 
inner.style.overflowY = 'hidden'; 
 
inner.style.overflowX = 'auto'; 
 
wrap.style.height = inner.scrollHeight + 'px'; 
 
var oldScrollLeft = getWidth(items[0])/2; 
 
var oldScrollWidth = inner.scrollWidth; 
 
window.onresize = function() { 
 
    wrap.style.height = inner.scrollHeight + 'px'; 
 
    oldScrollWidth = inner.scrollWidth; 
 
    oldScrollLeft = getWidth(items[0])/2; 
 
    inner.scrollLeft = oldScrollLeft; 
 
}; 
 
inner.scrollLeft = getWidth(items[0])/2; 
 
inner.onscroll = function(e) { 
 
    if (inner.scrollLeft < oldScrollLeft) { 
 
    log('scroll right'); 
 
    inner.appendChild(inner.querySelector('.item:first-child')); 
 
    inner.querySelector('.item:first-child').appendChild(darken1); 
 
    inner.querySelector('.item:nth-child(3)').appendChild(darken2); 
 
    } else if (inner.scrollLeft > oldScrollLeft) { 
 
    log('scroll left'); 
 
    var first = inner.querySelector('.item:first-child'); 
 
    var last = inner.querySelector('.item:last-child'); 
 
    inner.insertBefore(last, first); 
 
    inner.querySelector('.item:first-child').appendChild(darken1); 
 
    inner.querySelector('.item:nth-child(3)').appendChild(darken2); 
 
    inner.scrollLeft = 0; 
 
    } 
 

 
    inner.scrollLeft = oldScrollLeft; 
 
};
*, *::before, *::after { 
 
    box-sizing: border-box; 
 
} 
 
html, 
 
body { 
 
    padding: 0; 
 
    margin: 0; 
 
    max-height: 100%; 
 
    overflow: hidden; 
 
} 
 
.wrap { 
 
    position: relative; 
 
} 
 
.control { 
 
    font-weight: bold; 
 
    text-decoration: none; 
 
    display: inline-block; 
 
    position: absolute; 
 
    padding: 10px; 
 
    background: rgba(255, 255, 255, 0.5); 
 
    top: 50%; 
 
    transform: translateY(-50%); 
 
    color: #FFF; 
 
    font-size: 20pt; 
 
} 
 
.control-left { 
 
    padding-right: 20px; 
 
    border-top-right-radius: 50%; 
 
    border-bottom-right-radius: 50%; 
 
    left: 0; 
 
} 
 
.control-right { 
 
    padding-left: 20px; 
 
    border-top-left-radius: 50%; 
 
    border-bottom-left-radius: 50%; 
 
    right: 0; 
 
} 
 
.inner { 
 
    font-size: 0; 
 
    white-space: nowrap; 
 
    overflow: auto; 
 
} 
 
.item { 
 
    position: relative; 
 
    display: inline-block; 
 
    font-size: 1rem; 
 
    white-space: initial; 
 
    padding-bottom: 33.3333%; 
 
    width: 50%; 
 
} 
 
.item .darken { 
 
    position: absolute; 
 
    top: 0; 
 
    left: 0; 
 
    right: 0; 
 
    bottom: 0; 
 
    background-color: rgba(0, 0, 0, 0.8); 
 
} 
 
.item[data-n="2"] { 
 
    background-image: url(http://www.lorempixel.com/400/300/animals); 
 
    background-size: cover; 
 
} 
 
.item[data-n="3"] { 
 
    background-image: url(http://www.lorempixel.com/400/300/business); 
 
    background-size: cover; 
 
} 
 
.item[data-n="4"] { 
 
    background-image: url(http://www.lorempixel.com/400/300/cats); 
 
    background-size: cover; 
 
} 
 
.item[data-n="5"] { 
 
    background-image: url(http://www.lorempixel.com/400/300/city); 
 
    background-size: cover; 
 
} 
 
.item[data-n="6"] { 
 
    background-image: url(http://www.lorempixel.com/400/300/food); 
 
    background-size: cover; 
 
} 
 
.item[data-n="7"] { 
 
    background-image: url(http://www.lorempixel.com/400/300/nightlife); 
 
    background-size: cover; 
 
} 
 
.item[data-n="8"] { 
 
    background-image: url(http://www.lorempixel.com/400/300/fashion); 
 
    background-size: cover; 
 
} 
 
.item[data-n="9"] { 
 
    background-image: url(http://www.lorempixel.com/400/300/people); 
 
    background-size: cover; 
 
} 
 
.item[data-n="10"] { 
 
    background-image: url(http://www.lorempixel.com/400/300/nature); 
 
    background-size: cover; 
 
} 
 
.item[data-n="11"] { 
 
    background-image: url(http://www.lorempixel.com/400/300/sports); 
 
    background-size: cover; 
 
} 
 
.item[data-n="12"] { 
 
    background-image: url(http://www.lorempixel.com/400/300/technics); 
 
    background-size: cover; 
 
} 
 
.item[data-n="13"] { 
 
    background-image: url(http://www.lorempixel.com/400/300/transport); 
 
    background-size: cover; 
 
}
<div class="wrap"> 
 
    <div class="inner"> 
 
    <div class="item" data-n="2"></div> 
 
    <div class="item" data-n="3"></div> 
 
    <div class="item" data-n="4"></div> 
 
    <div class="item" data-n="5"></div> 
 
    <div class="item" data-n="6"></div> 
 
    <div class="item" data-n="7"></div> 
 
    <div class="item" data-n="8"></div> 
 
    <div class="item" data-n="9"></div> 
 
    <div class="item" data-n="10"></div> 
 
    <div class="item" data-n="11"></div> 
 
    <div class="item" data-n="12"></div> 
 
    <div class="item" data-n="13"></div> 
 
    </div> 
 
</div> 
 
<div class="log"> 
 
</div>

+0

Daj mi znać, jeśli to zadziałało dla ciebie :) –

+0

Przepraszam za opóźnienie ... cóż, zrobiłem zdjęcie zamknięte, ponieważ nie mam zestawu testów mobilnych, nawet gadżet tutaj ze mną ... mój jest w naprawie. Jest jeszcze wiele innych sposobów na zrobienie tego i myślę, że radzę sobie ze zwojem, słuchając wydarzenia, zmieniając jego wartości, jego najgorszy strzał, ale próbowałem też tego, aby uniknąć wielkiego refaktora na twoim kodzie. Kilkakrotnie stworzyłem cylindryczną karuzelę. Najlepszym podejściem jest klonowanie elementów do liczby nieparzystej, środkowej i radzenie sobie z nią jak przejście przez tablicę. Zobacz to pytanie: http://stackoverflow.com/questions/8007928/ i dostosuj je. –

+0

Cóż, naprawdę zachęcam cię do innego podejścia. Lista NodeList nie jest tablicą, na pewno była to moja nieporozumienie. Ale zwój, aby być przewodnikiem i odniesienie, również ... Inną rzeczą, o której warto wspomnieć, jest ograniczenie rozmiarów rzeczy na urządzeniach mobilnych, jeśli istnieją pewne ograniczenia dotyczące rozmiarów, modyfikacji przetwarzania w celu poprawy wydajności itp. Spróbuj wydrukować licznik, nad każdym zwoju, w pozycji pionowej/poziomej ... Dotyczy to iOS, ale może być przydatny: http://developer.telerik.com/featured/scroll-event-change-ios- 8-big-deal /. –

Powiązane problemy