2011-02-10 15 views
24

Tengo un texto de entrada de búsqueda que me gustaría aplicar focus() al cargar la página, el problema es que la función focus hace automáticamente un desplazamiento a este campo. Cualquier solución para desactivar este desplazamiento?focus() para ingresar sin desplazarse

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

¿Desea capturar las pulsaciones de teclas de los usuarios * sin que * ellas vean el elemento en el que están escribiendo? –

+0

¿Por qué consideras que este desplazamiento es un problema? – Oded

+0

Tengo una aplicación que necesita exactamente este comportamiento. Tengo una página que muestra datos de tres meses consecutivos en un año. Hay botones siguiente y anterior que cambian los tres meses que ve. Cuando el usuario hace clic en Siguiente o Anterior, reenfoco el cursor en la última entrada seleccionada, permitiendo a los usuarios hacer un seguimiento de su posición (si están ingresando datos o verificando cifras). En este caso, el desplazamiento es realmente discordante y deja de presionar repetidamente los botones prev/next. – peterjwest

Respuesta

33

Aquí es una solución completa:

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

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

Buena solución; sin embargo, en algunos casos en IE9 es mejor usar 'setTimeout (function() {window.scrollTo (x, y);}, 100); 'en lugar de' window.scrollTo (x, y); '. – MDJ

+0

window.scrollX y window.scrollY no se guardan en el navegador cruzado, use document.body.scrollLeft y document.body.scrollTop – fantarama

+0

Funcionan con la mayoría de los navegadores modernos (IE9 +), creo que es razonable. – peterjwest

4

Si está utilizando jQuery, también se puede hacer esto:

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

y luego

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

Gracias por esto, pero encontré la necesidad de cambiar la primera línea de su función a 'var x = $ (documento).scrollLeft(), y = $ (document) .scrollTop(); 'para que funcione en IE10. –

4

Un poco modificado versión que admite más navegadores (incluido 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

A partir de hoy, la mejor forma de establecer el foco en un elemento a la carga de la página está utilizando el atributo autofocus. Esto no implica ningún desplazamiento.

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

El autofocus attrubute is part of the HTML5 standard y es soportado por todos los navegadores, con la única excepción notable del Internet Explorer 9 o anterior.

+2

Estoy contento de ver este enfoque moderno para enfocar una entrada, pero todavía se "desplaza" al cuadro de entrada enfocado (al menos en Chrome). Por ejemplo, cuando actualiza una página en Chrome, vuelve a cargar la página, pero lo deja desplazado a la misma parte en esa página. Si configura el enfoque automático en una entrada a la mitad de la página, cuando vuelva a cargar se desplazará para tener la entrada centrada verticalmente. Creo que este "scroll" es lo que el OP intenta evitar. Si el usuario está leyendo un artículo extenso, no queremos que se desplacen hasta el cuadro de búsqueda en la parte superior cuando tocan actualizar. – DutGRIFF

3

Las respuestas aquí no se ocupan de desplazarse por toda la jerarquía, sino solo por las barras de desplazamiento principales. Esta respuesta se hará cargo de todo:

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

hay una nueva WHATWG standard que le permite pasar todo un objeto al focus() que especifica que desea evitar que el navegador de desplazamiento del elemento a la vista:

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

element.focus({ 
    preventScroll: true 
}); 

Actualmente es compatible con Chrome 64 y Edge Insider Preview build 17046.

+0

Cripes de vanguardia: no funcionaba para mí, pero obligué a Chrome a buscar actualizaciones y luego funcionó ... Demasiado nuevo para ser utilizado en la producción en este momento. – user9645

+0

Sí, por desgracia, no está listo para la producción en este momento, pero con suerte pronto ganará tracción. He [creado un PR para agregar los datos relevantes a caniuse.com] (https://github.com/Fyrd/caniuse/pull/4035), que con suerte hará un seguimiento de las implementaciones en curso. – Josh