2011-07-05 124 views
7

好吧,所以我们都知道onChange用于在选项更改时在select语句上执行javascript代码。但是,如果使用箭头键更改选择语句,则不会调用onChange事件。有没有解决的办法?请帮忙!我是强迫症,我知道。Javascript onChange箭头键

--edit 1--

在IE刚刚测试此键和方向键做的工作。显然这只是Chrome。 **去检查火狐

- 编辑2 -

测试在Firefox和实现所需要的变化之前下面谈到的onblur行动的答案。所以这里的答案是:

Internet Explorer从键盘识别onChange事件并点击它们。 为了调用onChange,Firefox和Chrome都需要关键事件以及blur事件。

现在通常情况下,我不喜欢Internet Explorer,因为它是一块垃圾......但我想我......不幸的是,不得不说他们得到了一个正确的答案。

我对Chrome和Firefox的blur事件的理解是为了节省资源,但我不同意这一点。我觉得它应该遵循字面上的命令onChange ...唉...我想我可能是错的某种方式,虽然。

+3

按Enter键后,它将被称为或Tab – SLaks

回答

4

回过头来看,自从提出这个问题后,Chrome现在在关键事件之后触发了更改。 Firefox似乎还在等待onblur。 http://jsfiddle.net/2aQBN/

$(document).ready(function() { 
    $("#test").on("change", function() { 
     console.log("Changed."); 
    }); 
}); 

W3C Specification出现使用input事件,而不是建议。

当输入事件适用,任何时候用户使元素的 值发生变化,用户代理必须队列的任务射击简单 事件命名的气泡在输入元件输入。

但是,没有输入事件出现在 Chrome或火狐 对火选择元素。 (只是输入元素。)

测试演示当前值与最后一个变化值。

http://jsfiddle.net/teynon/MpyHK/5/

Firefox会的onmouseover改变数值。关键的变化也会改变价值。然而,改革并没有解雇。如果在用户打开选择菜单时提交表单,则会提交当前突出显示的选项。

From W3C:

如果多个属性不存在,而该元素没有被禁用, 则用户代理应该允许用户选择相应的选项元素 其选项列表,其本身没有被禁用。当这个选项 元件被拾起(通过点击,或通过unfocusing 所述元件改变其值后,或通过菜单命令,或 通过任何其它机构),以及相关的用户交互之前被排队 事件(例如,在点击事件之前),用户代理必须将拾取的选项元素的选择性设置为真,然后将 任务排队以使用用户交互任务源在选定 元素处触发名为改变的泡沫的简单事件作为任务来源。

https://bugzilla.mozilla.org/show_bug.cgi?id=126379有很长的讨论,有很多人要求箭头键工作。 (还有一些防御onchange方法。)

有些用户提出W3C在select元素的change事件的规范中是错误的。而是建议我们对规范进行修改,以便我们如何期望select的功能正常工作。

目前的功能对于大量的人来说显然不直观,仅仅基于错误报告的数量。 (Mozilla已经40标记为重复。)

4

我建议你在Key Up事件中编写所需的代码来捕获按键并检查键码。希望这有助于

+0

你和AlienWebguy都回应了适当的回应,但我不能接受这两个答案......愚蠢的...无论如何,你的回答是对问题的适当回应(如何解决上述问题)。 – teynon

4

滚动选择框不被视为更改。当blur()将select和新选项值应用于select元素时,会发生更改。

+2

这应该是正确的答案恕我直言 – Xoundboy

2

这是一个非常肮脏的黑客,但可以强制的change事件做这个火:

element.addEventListener('keyup', function(evt){ 
    evt.target.blur(); 
    evt.target.focus(); 
}, false); 

所以,你会注册一个事件监听器change以及当用户通过上面的代码按<select>上的一个键时,该功能将被调用。

您可能希望将此范围仅限于Firefox,但AFAIK您必须使用UA嗅探,因此如果可以接受则由您决定。

Source

0

我想是这样的(如果以价值没有改变不会触发事件):

  select.keydown(function(){ 
       var _this = $(this); 
       var _val = $(this).val(); 

       setTimeout(function(){  
        if(_this.val() !== _val){ 
         _this.trigger("change"); 
        } 
       }, 1); 
      });