Comment arrêter le saut de fenêtre lors de la saisie de texte

J'utilise la réponse acceptée à cette question pour créer une zone de texte qui se développe verticalement lorsque le texte débordement:

<!DOCTYPE html> <html> <head> <title>autoresizing textarea</title> <style type="text/css"> textarea { border: 0 none white; overflow: hidden; padding: 0; outline: none; background-color: #D0D0D0; resize: none; } </style> <script type="text/javascript"> var observe; if (window.attachEvent) { observe = function (element, event, handler) { element.attachEvent('on'+event, handler); }; } else { observe = function (element, event, handler) { element.addEventListener(event, handler, false); }; } function init () { var text = document.getElementById('text'); function resize () { text.style.height = 'auto'; text.style.height = text.scrollHeight+'px'; } /* 0-timeout to get the already changed text */ function delayedResize () { window.setTimeout(resize, 0); } observe(text, 'change', resize); observe(text, 'cut', delayedResize); observe(text, 'paste', delayedResize); observe(text, 'drop', delayedResize); observe(text, 'keydown', delayedResize); text.focus(); text.select(); resize(); } </script> </head> <body onload="init();"> <textarea rows="1" style="height:1em;" id="text"></textarea> </body> </html> 

Il fonctionne bien jusqu'à ce que la taille de la zone de texte augmente plus longtemps que la fenêtre du navigateur. À ce moment-là, le haut de la fenêtre passe au sommet de la zone de texte chaque fois qu'une touche est pressée. Pouvez-vous m'aider à comprendre pourquoi et comment le réparer?

Une solution idéale serait de garder la page en mouvement. Mais s'il est plus facile de garder le bas de la page liée au bas de la zone de texte, cela fonctionnerait aussi.

J'ai ce problème dans Firefox 21.0 et Chrome 28.0: http://jsfiddle.net/CbqFv/

Enregistrez les valeurs scrollLeft , scrollTop , puis rétablissez-les après le redimensionnement de la zone de texte:

 function resize () { var scrollLeft = window.pageXOffset || (document.documentElement || document.body.parentNode || document.body).scrollLeft; var scrollTop = window.pageYOffset || (document.documentElement || document.body.parentNode || document.body).scrollTop; text.style.height = "auto"; text.style.height = text.scrollHeight + 'px'; window.scrollTo(scrollLeft, scrollTop); } 

JSFiddle: http://jsfiddle.net/losnir/nnkeH/1

Vous devez faire défiler la page vers: position de la barre de défilement + (taille du texte, taille après redimensionnement – hauteur de la taille de texte avant redimensionnement)

Voici le code:

  function resize () { var scrollLeft = window.pageXOffset || (document.documentElement || document.body.parentNode || document.body).scrollLeft; var scrollTop = window.pageYOffset || (document.documentElement || document.body.parentNode || document.body).scrollTop; var prevHeight = text.style.height.slice(0, -2); text.style.height = "auto"; var nextHeight = text.scrollHeight; text.style.height = text.scrollHeight + 'px'; window.scrollTo(scrollLeft, scrollTop + (nextHeight - prevHeight)); } 

OU vous pouvez le faire en utilisant jquery (basé sur cette réponse ):

  $('body').on('keyup', 'textarea', function (e) { var scrollTop = $(document).scrollTop(); var prevHeight = $(this).height(); $(this).css('height', 'auto'); var nextHeight = this.scrollHeight; $(this).height(nextHeight); $(document).scrollTop(scrollTop + (nextHeight - prevHeight)); }); $( 'textarea' ).keyup();