2013-02-21 120 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()">