2015-05-09 10 views
6

Setting scrollLeft does reset the scroll bar position e updating the content works as expected ma quando doing both at the same time la barra di scorrimento viene confusa e non viene ripristinata.Android set scrollLeft durante l'aggiornamento del contenuto sull'evento di scorrimento non aggiorna la posizione della barra di scorrimento

Per visualizzare il comportamento previsto e il comportamento imprevisto, visualizzare ogni demo su un dispositivo con un touchpad e utilizzare il touchpad per scorrere verso sinistra o destra all'interno del wrapper, quindi provare a fare la stessa cosa su un dispositivo Android.

Si noti che su un computer portatile l'elemento scorrerà senza fine, su un dispositivo Android l'elemento scorrerà solo fino a quando non ha raggiunto il primo set "max scroll"

ciò che dovrebbe accadere:

Quando l'utente scorre a sinistra oa destra, sposta il primo elemento figlio alla fine dell'elenco dei nodi o sposta l'ultimo bambino all'inizio e reimposta la posizione di scorrimento a metà della metà del primo figlio.

Di seguito sono riportati i miei tentativi di fissare il problema

  1. Set transform: translateX(0px) su .innersee here che ha avuto un comportamento peggio di prima.

  2. la correzione elencata here che era per un bug precedente in Android in cui l'impostazione scrollLeft non funzionava affatto. Questo non ha aiutato affatto il problema.

  3. wrap.appendChild(inner) su ogni evento di scorrimento, che ha rallentato lo scorrimento verso il basso ma non ha risolto il problema in quanto chrome ricorda le posizioni di scorrimento. Questo sarebbe un hack, anche se ho potuto ottenere Chrome per dimenticare la posizione di scorrimento (che sembra potrebbe essere plausibile, ma sarebbe ancora un altro mod)

mi rendo conto che avrei potuto annusare il browser e solo tornare a jquery ui configurazione mobile swipe, ma penso che se potessi farlo funzionare non avrei bisogno di usare una libreria esterna per emulare un comportamento nativo (e nativo è sempre meglio).

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

Quello che ho notato era che stava funzionando benissimo sul mio portatile. Stavo usando il software dell per scorrere, e ha funzionato perfettamente. A parte lo scorrimento molto veloce, va bene per quanto vedo. – mashedpotats

+0

Proverò comunque a provarlo. – mashedpotats

+0

Ok, vuoi dire che le immagini stanno scorrendo troppo velocemente? Perché sembra un po 'veloce. – mashedpotats

risposta

1

per risolvere questo problema temporaneamente, ho avvolto la funzione in un timeout. Il timeout può essere pari a 1 millisecondo. Non so perché, ma cambiando il contenuto e impostando scrollLeft sull'esatto evento della scroll, il browser non ripristina la barra di scorrimento.

(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); 
}; 

Anche se questo "risolvere" la questione, penso che sia un hack. Sto lasciando aperta questa domanda per vedere se riesco a ottenere una risposta reale.

0

Ogni volta che si desidera modificare la proprietà che si sta utilizzando per controllare se è necessario spostare il primo o l'ultimo elemento, si modificano nuovamente le stesse informazioni, in modo da ottenere un comportamento imprevisto.

Il trucco per aggiungere un timeout ha dato l'impressione di essere la soluzione perché dà un po 'di tempo al programma, quindi può serializzare le modifiche alle informazioni.

Ho apportato alcune modifiche nel codice e non utilizza il timeout. Tuttavia, a causa della natura dell'evento di scorrimento, a seconda della configurazione che l'utente ha nel suo comportamento di scorrimento, verrà scorrere una quantità diversa di diapositive.

Quindi mi raccomando di aggiungere qualche verifica, che può essere un timer (hahahahaha ...), ma solo per attivare un booleano per consentire al gestore di scorrimento di andare. Come lo snnipet di seguito:

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

    canScroll = false; 

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

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

Prima di chiedere, il senso di ritardo che inner.scrollLeft = 0 poi inner.scrollLeft = getWidth(items[0])/2; fornisce è a causa di questo overprocessing che il programma originale forzare il browser a fare.

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

Fammi sapere se ha funzionato per te :) –

+0

Oh, scusami per il ritardo ... beh, ho fatto uno scatto a occhi chiusi, perché non ho una suite di test mobile, anche un gadget qui con me ... il mio è in riparazione. Ci sono ancora molti altri modi per farlo e penso che trattare con la pergamena, ascoltando l'evento cambiando i suoi valori, sia il peggiore, ma ho provato anche quello per evitare un enorme refactoring sul tuo codice. Ho realizzato più volte la giostra cilindrica. L'approccio migliore è clonare gli elementi su un numero dispari, il centro uno e gestirlo come un array che attraversa. Vedi questa domanda: http://stackoverflow.com/questions/8007928/ e adattalo. –

+0

Bene, ti incoraggio davvero a usare un altro approccio. Un NodeList non è un array, certo, era un mio malinteso. Ma la pergamena, per essere il gestore e il riferimento, pure ... Un'altra cosa da dire riguarda le restrizioni sulle dimensioni delle cose sui dispositivi mobili, se c'è un limite alle dimensioni, elaborare modifiche per migliorare le prestazioni, ecc. Prova a stampare un contatore, su ogni scorrimento fatto, in posizioni verticali/orizzontali ... Si tratta di iOS, ma può essere utile: http://developer.telerik.com/featured/scroll-event-change-ios- 8-big-deal /. –

Problemi correlati