입력 포커스에서 텍스트 선택


121

텍스트 입력이 있습니다. 입력이 포커스를 받으면 입력 내부의 텍스트를 선택하고 싶습니다.

jQuery를 사용하면 다음과 같이 할 수 있습니다.

<input type="text" value="test" />
$("input[type=text]").click(function() {
    $(this).select();
    // would select "test" in this example
});

Angular 방식을 찾으려고 노력했지만 내가 찾은 대부분의 예제는 변경 사항에 대한 모달 속성을 감시하는 지시문을 다루는 것입니다. 포커스를받는 입력을 감시하는 지시문이 필요하다고 가정하고 있습니다. 어떻게할까요?


나는 당신이 '각도'를 찾고 싶어한다는 것을 이해합니다. 그러나 당신이 그냥하지 않을 이유가 <input type="text" value="test" onclick="this.select()" />있습니까?
Josef P.

답변:


216

Angular에서이 작업을 수행하는 방법은 자동 선택을 수행하는 사용자 지정 지시문을 만드는 것입니다.

module.directive('selectOnClick', ['$window', function ($window) {
    return {
        restrict: 'A',
        link: function (scope, element, attrs) {
            element.on('click', function () {
                if (!$window.getSelection().toString()) {
                    // Required for mobile Safari
                    this.setSelectionRange(0, this.value.length)
                }
            });
        }
    };
}]);

다음과 같이 지시문을 적용하십시오.

<input type="text" value="test" select-on-click />

View demo

Update1 : jQuery 종속성이 제거되었습니다.

Update2 : 속성으로 제한합니다.

Update3 : 모바일 Safari에서 작동합니다. 텍스트의 일부를 선택할 수 있습니다 (IE> 8 필요).


10
jquery없이이 작업을 수행하려면 element.click을 element.bind ( 'click', function () {...} 및 element.select ()를 element [0] .select ()로 변경하십시오.
jack

3
멋지고 우아합니다. 또한 restrict: 'A'이 지시문은 기존 요소의 동작확장하는 것을 목표로하기 때문에 ( 개체 리터럴을 반환하고 설정하여 ) 특성으로 적용 할 지시문을 명시 적으로 제한합니다 .
Eliran Malka 2014

@Martin 사용자 클릭없이 페이지를 여는 방법에 대한 아이디어가 있습니까? 문제는 내 selectOnLoad지시문 link () 전에 다른 컨트롤러에 기본값이 설정되어 있다는 것 입니다. 그러나 link ()에서는 범위가 이미 채워져 있지만 요소 DOM은 아직 $ scope와 동기화되지 않았으므로 select ()를 호출 할 때 요소가 여전히 비어 있고 아무것도 선택되지 않았습니다. 내가 찾은 유일한 방법은 $ timeout이지만 새로운 Angular 버전에서는 작동하지 않을 수 있다고 생각합니다.
Dzmitry Lazerka 2015 년

이것은 데스크탑 / 안드로이드에서 잘 작동하지만 ipad에서 시도하면 작동하지 않는 것 같습니다. 여기에 알려진 해결 방법이 있습니까?
ak85


44

다음은 사용자가 클릭하여 입력 상자에 커서를 놓을 때 텍스트를 다시 선택하지 않도록하는 향상된 지시문입니다.

module.directive('selectOnClick', function () {
    return {
        restrict: 'A',
        link: function (scope, element) {
            var focusedElement;
            element.on('click', function () {
                if (focusedElement != this) {
                    this.select();
                    focusedElement = this;
                }
            });
            element.on('blur', function () {
                focusedElement = null;
            });
        }
    };
})

3
나는 지시로 자신의 범위를 가지고, 그것은 입력 된 텍스트에서 어떤 위치로 설정 커서를 수 있기 때문에이 답변이 더 잘 받아 들여보다 생각하지만 - 내가 이름을 제안 focusedElement의 에 변수를 isElementFocused 및 저장이 또는 거짓
블라디미르 Gordienko

2
나는 Uncaught TypeError를 얻습니다 : undefined는 .select (); 예, jQuery 1.9.1이 포함되어 있습니다.
Robbie Smith

@RobbieSmith 저는 3 년 늦었지만 모든 인스턴스를 this로 변경 element[0]하면 작동합니다. 사용자가 입력을 클릭하는 대신 탭을 클릭하면 텍스트가 선택되도록로 변경 click하는 것이 좋습니다 focus.
Lex

40

Angular 1.x에 대한 오래된 답변입니다.

더 나은 방법은 ng-click내장 지시문 을 사용하는 것입니다 .

<input type="text" ng-model="content" ng-click="$event.target.select()" />

편집하다:

JoshMB 가 친절하게 상기시켜 준 것처럼 ; Angular 1.2+에서 DOM 노드를 참조하는 것은 더 이상 허용되지 않습니다. 그래서 저는 $event.target.select()컨트롤러 로 이동 했습니다.

<input type="text" ng-model="content" ng-click="onTextClick($event)" />

그런 다음 컨트롤러에서 :

$scope.onTextClick = function ($event) {
    $event.target.select();
};

다음은 fiddle 예제 입니다.


2
내가 말할 수있는 한 이것은 더 이상 지원되지 않습니다. Angular에서 "Angular 표현식에서 DOM 노드를 참조 할 수 없습니다!"라는 오류가 발생합니다. 자세한 정보는이 스레드를 참조하십시오 : groups.google.com/forum/#!topic/angular/bsTbZ86WAY4 . 그러나 지침 접근 방식은 잘 작동합니다.
JoshMB 2014

네가 옳아. Angular 1.2+의 경우입니다. 답변을 업데이트하겠습니다.
Onur Yıldırım

2
DOM 변경은 지시문에서 수행해야합니까?
Piioo 2014 년

어떤 이유로 다른 솔루션은 나를 위해 작동하지 않았지만 이것은 작동했습니다. 문제는이 클릭 이벤트를 추가하는 요소에 대한 지시문이 이미 있다는 것입니다.
Precastic

진지하게, onTextClick ($ event)조차도 지금 오류를 던지고 있습니다. 이 짐승의 직관적이지 않은 특성을 제외하고,이 불편 함으로 인해 성능에 얼마나 많은 비용이 듭니까?
jcalfee314

15

제안 된 솔루션 중 어느 것도 저에게 잘 맞지 않았습니다. 빠른 연구 끝에 나는 이것을 생각해 냈습니다.

module.directive('selectOnFocus', function ($timeout) {
    return {
        restrict: 'A',
        link: function (scope, element, attrs) {
            var focusedElement = null;

            element.on('focus', function () {
                var self = this;
                if (focusedElement != self) {
                    focusedElement = self;
                    $timeout(function () {
                        self.select();
                    }, 10);
                }
            });

            element.on('blur', function () {
                focusedElement = null;
            });
    }

  }

});

제안 된 여러 솔루션이 혼합되어 있지만 클릭과 초점 (자동 초점을 고려) 모두에서 작동하며 입력에서 부분 값을 수동으로 선택할 수 있습니다.


1
구문 오류 수정 : last}); 다음으로 교체 :}}; });
Blackfire

이것은 입력 type = "number"에 대해 작동합니다. 감사합니다
Louis

이건 안드로이드의 Ionic에서는 작동하지만 iOS에서는 작동하지 않습니다. 감사합니다
루이

2
onClick에서 수정했을 때 약간의 코드가 남겨진 것 같습니다 ... 요점은 focusedElement무엇입니까?
Langdon

12

나를 위해 ng-click은 의미가 없었습니다. 모든 텍스트를 다시 선택하지 않고 커서 위치를 변경할 수 없기 때문에 이것이 주석이라는 것을 알았습니다. 그런 다음 ng-focus를 사용하는 것이 좋습니다. 입력에 초점이 맞지 않은 경우에만 텍스트가 선택되기 때문에 다시 클릭하여 커서 위치를 변경하면 텍스트가 예상대로 선택 해제되고 그 사이에 쓸 수 있습니다.

이 접근 방식이 예상되는 UX 동작이라는 것을 알았습니다.

사용 NG 초점

옵션 1 : 별도 코드

<input type="text" ng-model="content" ng-focus="onTextFocus($event)" />

그리고 컨트롤러에서

$scope.onTextFocus = function ($event) {
  $event.target.select();
};

옵션 2 : 대안으로 위의 코드를이 "one-liner"에 결합 할 수 있습니다 (테스트하지는 않았지만 작동 할 것입니다).

<input type="text" ng-model="content" ng-focus="$event.target.select()" />

간단하고 작동합니다. 또한 위에서 설명한 것처럼 선택한 텍스트 내에서 커서를 배치 할 수 있습니다.
pistol-pete

7

angular 2에서는 Chrome과 Firefox에서 모두 저에게 효과적이었습니다.

<input type="text" (mouseup)="$event.target.select()">

6

허용되는 대답은 클릭 이벤트를 사용하는 것입니다. 그러나 포커스 이벤트를 사용하는 경우 첫 번째 클릭 만 이벤트를 발생시키고 입력에 초점을 맞추기 위해 다른 방법을 사용할 때도 발생합니다 (예 : 탭 누르기 또는 코드에서 포커스 호출).

이것은 또한 Tamlyn의 답변에서 알 수 있듯이 요소가 이미 집중되어 있는지 확인할 필요가 없습니다.

app.directive('selectOnClick', function () {
    return {
        restrict: 'A',
        link: function (scope, element, attrs) {
            element.on('focus', function () {
                this.select();
            });
        }
    };
});

Firefox 38.0.5에서 텍스트 중간을 클릭하면 먼저 모든 항목이 선택되지만 선택 항목이 제거되므로 작동하지 않습니다.
user1338062

1
이것은 아마도 지연없이 일관되게 작동하지 않을 것 this.select입니다.
Langdon

6

지시문이 필요하지 않습니다 onfocus="this.select()". 입력 요소 또는 텍스트 영역 에 네이티브 자바 스크립트를 추가하기 만하면 됩니다.


1
가장 쉬운 방법이 여기에있을 때

0

나를 위해 일한 수정 된 버전. 첫 번째 클릭은 텍스트를 선택하고 두 번째 클릭은 텍스트를 선택 취소합니다.

module.directive('selectOnClick', function ($timeout) {
return {
    restrict: 'A',
    link: function (scope, element, attrs) {
        var prevClickElem = null; //Last clicked element
        var ignorePrevNullOnBlur = false; //Ignoring the prevClickElem = null in Blur massege function

        element.on('click', function () {
            var self = this;
            if (prevClickElem != self) { //First click on new element
                prevClickElem = self; 
                $timeout(function () { //Timer
                    if(self.type == "number")
                        self.select();
                    else
                        self.setSelectionRange(0, self.value.length)
                }, 10);
            }
            else { //Second click on same element
                if (self.type == "number") {
                    ignorePrevNullOnBlur = true;
                    self.blur();
                }
                else
                    self.setSelectionRange(self.value.length, self.value.length); //deselect and set cursor on last pos
            }
        });

        element.on('blur', function () {
            if (ignorePrevNullOnBlur == true)
                ignorePrevNullOnBlur = false; //blur called from code handeling the second click 
            else
                prevClickElem = null; //We are leaving input box
        });
    }
}

})

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.