Ответ 1
Здесь полное решение:
var cursorFocus = function(elem) {
var x = window.scrollX, y = window.scrollY;
elem.focus();
window.scrollTo(x, y);
}
cursorFocus(document.getElementById('search-terms'));
У меня есть текст ввода для поиска, который я хотел бы применить focus()
при загрузке страницы, проблема в том, что функция focus
автоматически выполняет прокрутку к этому полю. Любое решение для отключения этого прокрутки?
<input id="search_terms" type="text" />
<script>
document.getelementbyId('search-terms').focus();
</script>
Здесь полное решение:
var cursorFocus = function(elem) {
var x = window.scrollX, y = window.scrollY;
elem.focus();
window.scrollTo(x, y);
}
cursorFocus(document.getElementById('search-terms'));
Существует новый стандарт WHATWG, который позволяет вам передавать объект в focus()
который указывает, что вы хотите запретить браузеру прокручивать элемент в поле зрения:
const element = document.getElementById('search-terms')
element.focus({
preventScroll: true
});
Он поддерживается начиная с Chrome 64 и Edge Insider Preview сборки 17046, и должен появиться в Firefox 68 - матрица поддержки доступна на тестах веб-платформ здесь.
Если вы используете jQuery, вы также можете сделать это:
$.fn.focusWithoutScrolling = function(){
var x = window.scrollX, y = window.scrollY;
this.focus();
window.scrollTo(x, y);
};
а затем
$('#search_terms').focusWithoutScrolling();
Немного измененная версия, которая поддерживает больше браузеров (включая 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);
}
}
В ответах здесь нет необходимости прокручивать всю иерархию, но только основные полосы прокрутки. Этот ответ позаботится обо всем:
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];
});
};
Для IE11: я бы пошел на раф поверх исправления прокрутки. В противном случае вы можете получить неприятное мерцание, если элемент находится за пределами экрана при получении фокуса.
Это делает назначение фокуса несколько асинхронным, хотя:
function focusNoScroll(element){
window.requestAnimationFrame(function() {
var x = window.scrollX, y = window.scrollY;
element.focus();
window.scrollTo(x, y);
});
};
На сегодняшний день предпочтительным способом установки фокуса на элемент при загрузке страницы является использование атрибута autofocus
. Это не связано с прокруткой.
<input id="search_terms" type="text" autofocus />