Javascript onFocus表现出奇怪的行为

Javascript onFocus表现出奇怪的行为,javascript,dom-events,onfocus,Javascript,Dom Events,Onfocus,我对onFocus事件的行为感到有点困惑。我有一个包含多个文本区域的表单,我希望它们执行的操作与input[:text]字段几乎相同,也就是说,当用户在某个字段中进行制表或单击时,该字段中的所有文本都会被选中。Mozilla网站上的文档说,每当用户通过鼠标单击或Tab键输入字段时,onFocus就会被触发,因此这似乎是理想的事件。然而,它的行为并不像我期望的那样 我假设以下代码可以工作: e.addEventListener('focus',function(){e.select()}) 但它

我对onFocus事件的行为感到有点困惑。我有一个包含多个文本区域的表单,我希望它们执行的操作与
input[:text]
字段几乎相同,也就是说,当用户在某个字段中进行制表或单击时,该字段中的所有文本都会被选中。Mozilla网站上的文档说,每当用户通过鼠标单击或Tab键输入字段时,
onFocus
就会被触发,因此这似乎是理想的事件。然而,它的行为并不像我期望的那样

我假设以下代码可以工作:

e.addEventListener('focus',function(){e.select()})
但它不起作用。但是,使用
onClick
可以正常工作:

e.addEventListener('click',function(){e.select()})
除了当用户通过鼠标单击而不是通过Tab键进入字段时,它仅选择字段中的文本。在玩了一会儿之后,我发现这是可行的:

e.addEventListener('focus',function(){setTimeout(function(){e.select()},0)})
我已经在Safari 7和Chrome 35上测试过了。Firefox29可以正常工作,但我还没有弄清楚它在做什么

有人能解释一下我遗漏了什么吗

我提供了一个示例页面,说明了我一直在讨论的内容:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/html5/strict.dtd">
<html>
<head>
<script type="text/javascript">
    function init() {
        var e = document.forms[0].elements
        e[0].value = "fld1: "
        e[0].addEventListener('focus',function(event){
                e[0].value += "onfocus, "
                e[0].select()
            })
        e[1].value = "fld2: "
        e[1].addEventListener('focus',function(event){
                e[1].value += "onfocus, "
                setTimeout(function(){e[1].select()},0)
            })
        e[2].value = "fld3: "
        e[2].addEventListener('click',function(event){
                e[2].value += "onclick, "
                e[2].select()
            })
    }
</script>
</head>

<body onload="init()">
<form>
    <textarea rows=4 cols=80></textarea>
    <br/><br/>
    <textarea rows=4 cols=80></textarea>
    <br/><br/>
    <textarea rows=4 cols=80></textarea>
</form>
</body>

函数init(){
var e=document.forms[0]。元素
e[0]。value=“fld1:”
e[0]。addEventListener('focus',函数(事件){
e[0]。值+=“聚焦,”
e[0]。选择()
})
e[1]。value=“fld2:”
e[1]。addEventListener('focus',函数(事件){
e[1]。值+=“聚焦,”
setTimeout(函数(){e[1]。选择()},0)
})
e[2]。value=“fld3:”
e[2]。addEventListener('click',函数(事件){
e[2]。值+=“onclick,”
e[2]。选择()
})
}





就Vanilla JS而言,问题很可能在于将
EventListener
附加到适当的元素中。这可以通过获取所有元素(按类名或类似名称),以类似数组的格式循环它们,并以这种方式附加
EventListener
函数来实现

HTML:

<div class="row d-flex justify-content-center">
    <div class="col-md-6">
        <input type="text" class="form-control auto-selector" value="Some input field text value" />
    </div>
</div>
<br />
<div class="row d-flex justify-content-center">
    <div class="col-md-6">
        <textarea class="form-control auto-selector">Lorem ipsum dolor sit amet, consectetur adipiscing elit. Suspendisse aliquet felis vel lacus auctor, nec sollicitudin leo blandit. Praesent arcu tellus, fringilla id efficitur ut, interdum vitae risus. Aliquam erat volutpat. Aenean eleifend dui vel blandit facilisis. Curabitur vel libero ut erat ultricies pretium. Proin congue, orci sed dignissim consequat, nunc massa scelerisque ante, in efficitur est sem ac nulla. Aliquam at est sed ligula lobortis feugiat ut et nisl.</textarea>
    </div>
</div>
var elements = document.getElementsByClassName('auto-selector');

Array.from(elements).forEach(function(element) {
    element.addEventListener("focus", function(e) {
        this.focus();
        this.select();
    });
});
代码片段示例:

<div class="row d-flex justify-content-center">
    <div class="col-md-6">
        <input type="text" class="form-control auto-selector" value="Some input field text value" />
    </div>
</div>
<br />
<div class="row d-flex justify-content-center">
    <div class="col-md-6">
        <textarea class="form-control auto-selector">Lorem ipsum dolor sit amet, consectetur adipiscing elit. Suspendisse aliquet felis vel lacus auctor, nec sollicitudin leo blandit. Praesent arcu tellus, fringilla id efficitur ut, interdum vitae risus. Aliquam erat volutpat. Aenean eleifend dui vel blandit facilisis. Curabitur vel libero ut erat ultricies pretium. Proin congue, orci sed dignissim consequat, nunc massa scelerisque ante, in efficitur est sem ac nulla. Aliquam at est sed ligula lobortis feugiat ut et nisl.</textarea>
    </div>
</div>
var elements = document.getElementsByClassName('auto-selector');

Array.from(elements).forEach(function(element) {
    element.addEventListener("focus", function(e) {
        this.focus();
        this.select();
    });
});
var elements=document.getElementsByClassName('auto-selector');
数组.from(元素).forEach(函数(元素){
元素。addEventListener(“焦点”,函数(e){
这是focus();
这是select();
});
});
textarea.auto-selector{
宽度:100%;
高度:200px;
}


Lorem ipsum dolor sit amet,是一位杰出的献身者。这是一家拍卖行,nec sollicitudin leo blandit。这是一个很好的例子,它是一个很好的例子。阿利奎姆·埃拉特·帕特。设备齐全,设备齐全。自由之家的馆长。在康格,或是在康塞卡特的权贵们,修女们的权杖,效率最高。在东部的阿利夸姆是一个年轻人。
浏览器取消选择字段内容是“焦点”交互的默认行为。您没有阻止默认操作,在您的事件处理程序返回后,浏览器将执行其正常操作。您能否提供一个链接来解释这一点?显然,该操作只适用于textarea元素。text[:input]元素没有表现出这种行为。我在快速阅读W3C规范中找不到任何东西,但浏览器肯定是这样的。是的,它特别是一个
东西。好的,谢谢。我会继续搜索。您是否尝试过使用preventDefault方法在代码完成后阻止浏览器执行更多操作?Martin不要求使用jquery,只是为了避开文本选择而添加jquery是一项非常重要的要求。虽然您的解决方案确实有效,而且对jquery的粉丝也会很有用,但我想。编辑后的答案中也包含了Vanilla JS@彼得·布兰德,但香草JS不能按要求工作。尝试在文本和文本区域之间单击。当文本区域没有选择时,代码将选择整个文本。但是,如果文本区域有一个选择,下次您单击它时,浏览器会在代码运行后取消选择该文本。我怀疑jquery会将焦点代码延迟到浏览器完成它的工作之后。“我有一个包含多个文本区域的表单,我希望它们的执行方式与输入[:text]字段几乎相同,也就是说,当用户在某个字段中进行制表或单击时,该字段中的所有文本都会被选中。”@PeterBrand这是OP要求的,我的坏Martin,我再次测试了vanilla JS,现在它在FireFox中可以正常工作了。不记得我以前用过什么。我现在看到在onFocus事件中,您再次运行focus()事件,这将触发浏览器的取消选择代码,然后执行select()。我猜最后浏览器会认为元素已经有了焦点,不会触发取消选择代码。一种方法是这样做,但默认设置仍然更简单,跨浏览器可能更可靠。