最新消息:Welcome to the puzzle paradise for programmers! Here, a well-designed puzzle awaits you. From code logic puzzles to algorithmic challenges, each level is closely centered on the programmer's expertise and skills. Whether you're a novice programmer or an experienced tech guru, you'll find your own challenges on this site. In the process of solving puzzles, you can not only exercise your thinking skills, but also deepen your understanding and application of programming knowledge. Come to start this puzzle journey full of wisdom and challenges, with many programmers to compete with each other and show your programming wisdom! Translated with DeepL.com (free version)

javascript - Angularjs - TextArea autogrow - Stack Overflow

matteradmin7PV0评论

I want to use this directive in my project but I want the text area to expand the moment the content is loaded.

Angular-Autogrow.js:

(function(){
    'use strict';
    angular.module('angular-autogrow', []).directive('autogrow', ['$window', function($window){
        return {
            link: function($scope, $element, $attrs){

                /**
                 * Default settings
                 */
                $scope.attrs = {
                    rows: 1,
                    maxLines: 999
                };

                /**
                 * Merge defaults with user preferences
                 */
                for(var i in $scope.attrs){
                    if($attrs[i]){
                        $scope.attrs[i] = parseInt($attrs[i]);
                    }
                }

                /**
                 * Calculates the vertical padding of the element
                 * @returns {number}
                 */
                $scope.getOffset = function(){
                    var style = $window.getComputedStyle($element[0], null),
                        props = ['paddingTop', 'paddingBottom'],
                        offset = 0;

                    for(var i=0; i<props.length; i++){
                        offset += parseInt(style[props[i]]);
                    }
                    return offset;
                };

                /**
                 * Sets textarea height as exact height of content
                 * @returns {boolean}
                 */
                $scope.autogrowFn = function(){
                    var newHeight = 0, hasGrown = false;
                    if(($element[0].scrollHeight - $scope.offset) > $scope.maxAllowedHeight){
                        $element[0].style.overflowY = 'scroll';
                        newHeight = $scope.maxAllowedHeight;
                    }
                    else {
                        $element[0].style.overflowY = 'hidden';
                        $element[0].style.height = 'auto';
                        newHeight = $element[0].scrollHeight - $scope.offset;
                        hasGrown = true;
                    }
                    $element[0].style.height = newHeight + 'px';
                    return hasGrown;
                };

                $scope.offset = $scope.getOffset();
                $scope.lineHeight = ($element[0].scrollHeight / $scope.attrs.rows) - ($scope.offset / $scope.attrs.rows);
                $scope.maxAllowedHeight = ($scope.lineHeight * $scope.attrs.maxLines) - $scope.offset;

                $element[0].addEventListener('input', $scope.autogrowFn);
                /**
                 * Auto-resize when there's content on page load
                 */
                if($element[0].value != ''){
                    $scope.autogrowFn();
                }
            }
        }
    }]);
})();

I change:

// $element[0].addEventListener('input', $scope.autogrowFn);

  $element[0].addEventListener('load', $scope.autogrowFn);//<-- I add this line

but it did not work. How can I change it so that the text area automatically expand when the content is loaded?

I want to use this directive in my project but I want the text area to expand the moment the content is loaded.

Angular-Autogrow.js:

(function(){
    'use strict';
    angular.module('angular-autogrow', []).directive('autogrow', ['$window', function($window){
        return {
            link: function($scope, $element, $attrs){

                /**
                 * Default settings
                 */
                $scope.attrs = {
                    rows: 1,
                    maxLines: 999
                };

                /**
                 * Merge defaults with user preferences
                 */
                for(var i in $scope.attrs){
                    if($attrs[i]){
                        $scope.attrs[i] = parseInt($attrs[i]);
                    }
                }

                /**
                 * Calculates the vertical padding of the element
                 * @returns {number}
                 */
                $scope.getOffset = function(){
                    var style = $window.getComputedStyle($element[0], null),
                        props = ['paddingTop', 'paddingBottom'],
                        offset = 0;

                    for(var i=0; i<props.length; i++){
                        offset += parseInt(style[props[i]]);
                    }
                    return offset;
                };

                /**
                 * Sets textarea height as exact height of content
                 * @returns {boolean}
                 */
                $scope.autogrowFn = function(){
                    var newHeight = 0, hasGrown = false;
                    if(($element[0].scrollHeight - $scope.offset) > $scope.maxAllowedHeight){
                        $element[0].style.overflowY = 'scroll';
                        newHeight = $scope.maxAllowedHeight;
                    }
                    else {
                        $element[0].style.overflowY = 'hidden';
                        $element[0].style.height = 'auto';
                        newHeight = $element[0].scrollHeight - $scope.offset;
                        hasGrown = true;
                    }
                    $element[0].style.height = newHeight + 'px';
                    return hasGrown;
                };

                $scope.offset = $scope.getOffset();
                $scope.lineHeight = ($element[0].scrollHeight / $scope.attrs.rows) - ($scope.offset / $scope.attrs.rows);
                $scope.maxAllowedHeight = ($scope.lineHeight * $scope.attrs.maxLines) - $scope.offset;

                $element[0].addEventListener('input', $scope.autogrowFn);
                /**
                 * Auto-resize when there's content on page load
                 */
                if($element[0].value != ''){
                    $scope.autogrowFn();
                }
            }
        }
    }]);
})();

I change:

// $element[0].addEventListener('input', $scope.autogrowFn);

  $element[0].addEventListener('load', $scope.autogrowFn);//<-- I add this line

but it did not work. How can I change it so that the text area automatically expand when the content is loaded?

Share Improve this question asked Jul 18, 2016 at 3:47 sooonsooon 4,8988 gold badges74 silver badges125 bronze badges
Add a ment  | 

3 Answers 3

Reset to default 2

Hi u have to use the directive first then include "angularjs-autogrow" the directive in app.js , then check the text area will auto grow based on you type

HTML

<textarea autogrow></textarea>

JS

var app = angular.module('plunker', ["angularjs-autogrow"]);

app.controller('MainCtrl', function($scope) {

});

for reference https://plnkr.co/edit/kj3ikS30cqVIRofTU22X?p=preview

As modern browsers support event.target there is also a minimal non angularjs alternative and you do not need to upgrade it to Angular later. Additionally there seems to be "this" (HTMLElement) accessible as a parameter. Using onscroll the textarea grows if it starts scrolling. Alternatives are onfocus or onkeyup events. Note that the textarea cannot shrink.

You may need to trigger a scroll event manually in a $watch if the model changes programmatically: htmlElement.dispatchEvent(new Event("scroll"));

https://jsfiddle/hnxd91rq/

<textarea onscroll="autogrowTextHeight(event, this)"></textarea>

<script>
function autogrowTextHeight(event, htmlElement) {
  // https://developer.mozilla/en-US/docs/Web/API/Event
  // var htmlElement = event.target; ... OR use this ...
  htmlElement.style.height = htmlElement.scrollHeight+"px";
}
</script>

My HTML is:

<textarea autogrow ng-model="vm.myinput" ></textarea>

I replaced:

$element[0].addEventListener('input', $scope.autogrowFn);

with:

$scope.$watch($attrs.ngModel, $scope.autogrowFn);

so every time the model is changed, the autogrow function is called. This should also work in your case.

Post a comment

comment list (0)

  1. No comments so far