2013-02-21 208 views
114

我有一個文本輸入。當輸入獲得焦點時,我想選擇輸入內的文本。在輸入焦點上選擇文本

使用jQuery我會做這種方式:

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

我周圍中搜索,試圖找到該角的方式,但大多數的例子我發現正在處理一個指令那是在觀察改變的模態屬性。我假設我需要一個指令來監視接收焦點的輸入。我會怎麼做?

+0

你想找到一個「角的方式」我明白了,但沒有任何理由,你將不只是做''? – 2017-03-31 11:42:14

回答

208

在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('點擊',功能(){...}和element.select()元素[0] .select() – jack 2013-08-15 07:02:03

+3

尼斯和優雅。我還會明確地限制指令被應用爲屬性(通過返回對象字面值並設置'restrict:'A''),因爲這個指令旨在*擴展現有元素的行爲*。 – 2014-02-09 10:02:44

+0

好主意@EliranMalka ,我更新了答案 – Martin 2014-02-09 11:41:13

34

這是一個古老的答案,對角的1.x

更好的方式來做到這一點是通過使用ng-click內置指令:

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

編輯:

由於JoshMB已經提醒;在Angular 1.2+中引用DOM節點不再被允許。在您的控制器

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

然後::所以,我搬到$event.target.select()到控制器

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

這裏是一個example fiddle

+2

據我所知,這不再支持。 Angular會拋出一個錯誤:「不允許在Angular表達式中引用DOM節點!」。有關詳情,請參閱以下主題:https://groups.google.com/forum/#!topic/angular/bsTbZ86WAY4。然而,指令方法運作良好。 – JoshMB 2014-04-17 20:17:11

+0

你說得對。 Angular 1.2+就是這種情況。我會更新答案。 – 2014-05-10 21:37:27

+2

DOM更改應該在指令中完成,還是不? – Piioo 2014-10-28 08:45:36

42

這是一個增強的指令,它避免在用戶單擊以將光標置於輸入框中時重新選擇文本。

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 **並存儲有_true_或_false_ – 2014-10-06 12:55:04

+2

我得到Uncaught TypeError:undefined不是「this」上的一個函數.select();是的,包括jQuery 1.9.1。 – 2015-01-12 19:57:51

+0

@RobbieSmith我遲了3年,但將'this'的所有實例更改爲'element [0]',它應該可以工作。我還建議將'click'改爲'focus',以便在用戶輸入輸入而不是點擊輸入時選擇文本。 – Lex 2018-02-01 22:06:08

6

接受的答案是使用單擊事件但是如果你使用的焦點事件,只有第1點擊就會觸發該事件,同時也時觸發一些其他的方法來集中輸入(如打標籤或在代碼中調用焦點)。

這也使得沒有必要檢查元素是否已經被Tamlyn的回答所暗示。

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

在Firefox 38.0.5中點擊文本中間的第一個選擇全部,但是然後刪除選擇,所以這不起作用。 – user1338062 2015-06-04 10:27:56

+1

如果不拖延'this.select',這可能不會持續工作。 – Langdon 2016-10-07 18:19:05

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

其他解決方案也不適用於我。這一個。謝謝! – 2016-01-20 17:05:48

+1

糾正語法錯誤: last});替換爲: \t \t} \t}; }); – Blackfire 2016-02-17 21:57:57

+0

這一個適用於輸入類型=「數字」,這是偉大的!謝謝 – Louis 2016-04-26 19:00:20

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 
     }); 
    } 
} 

})

11

對於我來說,NG-點擊沒有意義,因爲你永遠無法重新定位光標,而無需再次選擇所有文字,我發現這是令人興奮的。那麼最好使用ng-focus,因爲只有當輸入沒有被聚焦時才選擇文本,如果再次點擊來重新定位光標,那麼文本就像預期的那樣取消選擇,並且可以在兩者之間寫入。

我發現這種方法是預期的UX行爲。

使用ng-focus

選項1:單獨的代碼

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

和在控制器

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

選項2:作爲替代可以加入上面的代碼到該「單線」(我沒有測試這個,但它應該工作)

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

簡單而有效。如上所述,這也允許將光標定位在所選文本內。 – 2016-12-28 17:12:36

5

在角2,這個工作對我來說,無論是在瀏覽器火狐&:

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