Dopo aver cercato di trovare una soluzione che gestisse ogni circostanza (opzioni per l'animazione del rotolo, il riempimento attorno all'oggetto una volta che scorre in vista, funziona anche in circostanze oscure come in un iframe), ho finalmente finito per scrivere la mia soluzione per questo. Dal momento che sembra funzionare quando molte altre soluzioni falliscono, ho pensato di condividerlo:
function scrollIntoViewIfNeeded($target, options) {
var options = options ? options : {},
$win = $($target[0].ownerDocument.defaultView), //get the window object of the $target, don't use "window" because the element could possibly be in a different iframe than the one calling the function
$container = options.$container ? options.$container : $win,
padding = options.padding ? options.padding : 20,
elemTop = $target.offset().top,
elemHeight = $target.outerHeight(),
containerTop = $container.scrollTop(),
//Everything past this point is used only to get the container's visible height, which is needed to do this accurately
containerHeight = $container.outerHeight(),
winTop = $win.scrollTop(),
winBot = winTop + $win.height(),
containerVisibleTop = containerTop < winTop ? winTop : containerTop,
containerVisibleBottom = containerTop + containerHeight > winBot ? winBot : containerTop + containerHeight,
containerVisibleHeight = containerVisibleBottom - containerVisibleTop;
if (elemTop < containerTop) {
//scroll up
if (options.instant) {
$container.scrollTop(elemTop - padding);
} else {
$container.animate({scrollTop: elemTop - padding}, options.animationOptions);
}
} else if (elemTop + elemHeight > containerTop + containerVisibleHeight) {
//scroll down
if (options.instant) {
$container.scrollTop(elemTop + elemHeight - containerVisibleHeight + padding);
} else {
$container.animate({scrollTop: elemTop + elemHeight - containerVisibleHeight + padding}, options.animationOptions);
}
}
}
$target
è un oggetto jQuery contenente l'oggetto che si desidera scorrere in vista se necessario.
options
(facoltativo) può contenere le seguenti opzioni passate in un oggetto:
options.$container
- un oggetto jQuery che punta all'elemento contenente $ target (in altre parole, l'elemento nel dom con le barre di scorrimento). Il valore predefinito è la finestra che contiene l'elemento $ target ed è abbastanza intelligente da selezionare una finestra iframe. Ricorda di includere $ nel nome della proprietà.
options.padding
- il riempimento in pixel da aggiungere sopra o sotto l'oggetto quando viene fatto scorrere in vista. In questo modo non è proprio contro il bordo della finestra. Il valore predefinito è 20.
options.instant
- se impostato su true, jQuery animate non verrà utilizzato e lo scorrimento apparirà immediatamente nella posizione corretta. Il valore predefinito è false.
options.animationOptions
- eventuali opzioni jQuery che si desidera passare alla funzione animata jQuery (consultare http://api.jquery.com/animate/ ). In questo modo, è possibile modificare la durata dell'animazione o eseguire una funzione di richiamata al termine dello scorrimento. Funziona solo se options.instant
impostato su false. Se è necessario disporre di un'animazione istantanea ma con un callback, impostare options.animationOptions.duration = 0
invece di utilizzare options.instant = true
.