2011-02-10 11 views
24

Ho un testo di input di ricerca che mi piacerebbe applicare un focus() durante il caricamento della pagina, il problema è che la funzione focus esegue automaticamente uno scorrimento verso questo campo. Qualche soluzione per disabilitare questo scroll?focus() per immettere senza scorrere

<input id="search_terms" type="text" /> 
<script> 
    document.getelementbyId('search-terms').focus(); 
</script> 
+0

Vuoi catturare le battute dei tuoi utenti * senza * vedendo l'elemento in cui stanno digitando? –

+0

Perché consideri questo scorrimento come un problema? – Oded

+0

Ho un'app che richiede esattamente questo comportamento. Ho una pagina che mostra i dati da tre mesi consecutivi in ​​un anno. Ci sono i pulsanti successivi e precedenti che cambiano in quali tre mesi viene visualizzato. Quando l'utente fa clic su Avanti o Indietro, rimetto a fuoco il cursore sull'ultimo input selezionato, consentendo agli utenti di tenere traccia della loro posizione (se stanno inserendo dati o controllando cifre). In questo caso lo scorrimento è molto fastidioso e impedisce di premere ripetutamente i pulsanti prev/next. – peterjwest

risposta

33

Ecco una soluzione completa:

var cursorFocus = function(elem) { 
    var x = window.scrollX, y = window.scrollY; 
    elem.focus(); 
    window.scrollTo(x, y); 
} 

cursorFocus(document.getElementById('search-terms')); 
+4

Buona soluzione, tuttavia in alcuni casi su IE9 è preferibile utilizzare 'setTimeout (function() {window.scrollTo (x, y);}, 100); 'invece di' window.scrollTo (x, y); '. – MDJ

+0

window.scrollX e window.scrollY non sono salvataggi cross browser, usa document.body.scrollLeft e document.body.scrollTop – fantarama

+0

Funzionano con i browser più moderni (IE9 +), penso che sia ragionevole. – peterjwest

4

Se si utilizza jQuery, si può anche fare questo:

$.fn.focusWithoutScrolling = function(){ 
    var x = window.scrollX, y = window.scrollY; 
    this.focus(); 
    window.scrollTo(x, y); 
}; 

e poi

$('#search_terms').focusWithoutScrolling(); 
+3

Grazie per questo, ma ho trovato la necessità di cambiare la prima riga della tua funzione in 'var x = $ (documento).scrollLeft(), y = $ (document) .scrollTop(); 'per farlo funzionare in IE10. –

4

Un po 'modificato versione che supporta più browser (incluso IE9)

var cursorFocus = function(elem) { 
    var x, y; 
    // More sources for scroll x, y offset. 
    if (typeof(window.pageXOffset) !== 'undefined') { 
     x = window.pageXOffset; 
     y = window.pageYOffset; 
    } else if (typeof(window.scrollX) !== 'undefined') { 
     x = window.scrollX; 
     y = window.scrollY; 
    } else if (document.documentElement && typeof(document.documentElement.scrollLeft) !== 'undefined') { 
     x = document.documentElement.scrollLeft; 
     y = document.documentElement.scrollTop; 
    } else { 
     x = document.body.scrollLeft; 
     y = document.body.scrollTop; 
    } 

    elem.focus(); 

    if (typeof x !== 'undefined') { 
     // In some cases IE9 does not seem to catch instant scrollTo request. 
     setTimeout(function() { window.scrollTo(x, y); }, 100); 
    } 
} 
-1

Ad oggi, il metodo preferito per impostare la messa a fuoco su un elemento al caricamento della pagina utilizza l'attributo autofocus. Questo non comporta alcun scorrimento.

<input id="search_terms" type="text" autofocus />

Il autofocus attrubute is part of the HTML5 standard ed è supportato da tutti i principali browser, con la sola eccezione di Internet Explorer 9 o versioni precedenti.

+2

Sono lieto di vedere questo approccio moderno per mettere a fuoco un input ma continua a "scorrere" verso il riquadro di input focalizzato (almeno in Chrome). Ad esempio, quando aggiorni una pagina in Chrome, ricarica la pagina ma ti lascia scorrere alla stessa parte su quella pagina. Se si imposta la messa a fuoco automatica su un ingresso a metà della pagina, quando si ricarica, ora si scorre per avere l'input verticalmente centrato. Penso che questo "scroll" sia ciò che l'OP sta cercando di evitare. Se l'utente sta leggendo un lungo articolo, non vogliamo che vengano fatti scorrere fino alla casella di ricerca nella parte superiore quando raggiungono il refresh. – DutGRIFF

3

Le risposte qui non si occupano di scorrere l'intera gerarchia, ma solo le barre di scorrimento principali. Questa risposta si prenderà cura di tutto:

var focusWithoutScrolling = function (el) { 
     var scrollHierarchy = []; 

     var parent = el.parentNode; 
     while (parent) { 
      scrollHierarchy.push([parent, parent.scrollLeft, parent.scrollTop]); 
      parent = parent.parentNode; 
     } 

     el.focus(); 

     scrollHierarchy.forEach(function (item) { 
      var el = item[0]; 

      // Check first to avoid triggering unnecessary `scroll` events 

      if (el.scrollLeft != item[1]) 
       el.scrollLeft = item[1]; 

      if (el.scrollTop != item[2]) 
       el.scrollTop = item[2]; 
     }); 
    }; 
1

C'è una nuova WHATWG standard che consente di passare un oggetto a focus() che specifica che si vuole evitare che il browser di scorrere l'elemento nella vista:

const element = document.getElementById('search-terms') 

element.focus({ 
    preventScroll: true 
}); 

Attualmente è supportato in Chrome 64 e Edge Insider Preview build 17046.

+0

Cripes che è all'avanguardia - non funzionava per me, ma ho forzato Chrome a controllare l'aggiornamento e poi ha funzionato ... Troppo nuovo per essere in produzione in questo momento però. – user9645

+0

Sì, sfortunatamente non è ancora pronto per la produzione, ma spero che presto guadagnerai la trazione. Ho [creato una PR per aggiungere i dati rilevanti a caniuse.com] (https://github.com/Fyrd/caniuse/pull/4035) che, auspicabilmente, seguirà le implementazioni in corso. – Josh

Problemi correlati