【问题标题】:Event problems with FFFF 的事件问题
【发布时间】:2010-04-13 18:06:31
【问题描述】:

让这个可爱的小脚本在输入后自动更改字段。在 IE、Chrome 和 Safari 中运行良好,但在 FF 或 Opera 中不适用。 JS代码:

function fieldChange(id, e){            
            var keyID = (window.event) ? event.keyCode : e.keyCode;
            if (document.getElementById(id).value.length >= 2){
                if (keyID >= 48 && keyID <= 57 || keyID >= 96 && keyID <= 105){
                    switch(id){
                        case "textf1":
                            document.getElementById("textf2").focus();
                        break;                              
                        case "textf2":                              
                            document.getElementById("textf3").focus();
                        break;                      
                        case "textf3":
                            if (document.getElementById(id).value.length >= 4){
                                document.getElementById("nubPcode").focus();
                            }
                        break;                      
                    }
                }
            }

HTML:

                            <div class="privateOrderSchema">
                                <input type="text" id="textf1" name="textf1" maxlength="2" size="4" onKeyUp="fieldChange('textf1')"/>-
                                <input type="text" id="textf2" name="textf2" maxlength="2" size="4" onKeyUp="fieldChange('textf2')" />-
                                <input type="text" id="textf3" name="textf3" maxlength="4" size="5" onKeyUp="fieldChange('textf3')" />
                            </div>
                            <div class="privateOrderSchema">
                                <input type="text" id="nubPcode" name="nubPcode" size="4" maxlength="4" />
                                <br />
                            </div>

有人知道如何在这种情况下发送“e”变量吗?

Tnx all :D ur gr8!

【问题讨论】:

  • 你试过不显眼的方法吗? document.getElementById('textf1').onkeyup = document.getElementById('textf2').onkeyup = document.getElementById('textf3').onkeyup = function() { fieldChange(this.id); };
  • 我们能不能,请,就一次,对 JavaScript 的工作机制有疑问,而无需宗教性的“只使用 jQuery”回复吗? jQuery 并不是唯一的 JS 库或脚本编写方法。它远非完美无缺,通常会补充有问题的设计决策和使用它可能存在的缺点。

标签: javascript html firefox events


【解决方案1】:

我认为像下面这样的东西会起作用。它仍然通过元素的属性附加处理程序,这确实是不需要的。它们应该通过 javascript 附加。

在此尝试中,您将eventthis 和一个可选元素id 发送到fieldChange 函数。那里有很好的评论,但简而言之,它是这样做的:

在 keyup 时,检查元素当前值的长度。如果它的长度等于(或更大)在maxlength 中设置的长度,请做一些魔术(如果它更长,将值截断为maxlength)。在此键位检查中,不要对键码 9 和 16 执行任何操作(这允许使用制表符和 shift-tabbing 进入“完整”输入元素)。
“魔法”是跳到下一个元素。这将是 表单中的下一个元素,该元素带有可选发送的id (explicitNextId)。

现在是 16 行 js,不包括 cmets。 HTH。

<body>
    <form action="#">
        <div class="privateOrderSchema">
            <input type="text" id="textf1" name="textf1" maxlength="2" size="4" onKeyUp="fieldChange(event, this)"/>-
            <input type="text" id="textf2" name="textf2" maxlength="2" size="4" onKeyUp="fieldChange(event, this)" />-
            <input type="text" id="textf3" name="textf3" maxlength="4" size="5" onKeyUp="fieldChange(event, this, 'nubPcode')" />
        </div>
        <div class="privateOrderSchema">
            <input type="text" id="nubPcode" name="nubPcode" size="4" maxlength="4" />
        </div>
    </form>

    <script type="text/javascript">
    function fieldChange(event, elem, explicitNextId) {
        // Obtain useable event
        event = window.event ? window.event : event;            
        var keyCode = event.keyCode, len = elem.value.length;
        // tab, shift (catches shift/tab) or small length, do nothing:
        if (keyCode===9 || keyCode===16 || len < elem.maxLength) {return;}
        // truncate value if exceding limit
        if (len>elem.maxLength) {elem.value=elem.value.substr(0, len-1);}
        // Get the next input to jump to (either from the id explicitly sent, or next in form)
        var next = getNextElement(elem, explicitNextId);
        // If one was found, focus it
        if (next) {next.focus();}
    }
    function getNextElement(elem, explicitNextId) {
        // From explicit id
        if (typeof explicitNextId!=='undefined') {return document.getElementById(explicitNextId);}
        // Get next in form
        var inputs = elem.form.elements;
        for (var idx=0, len=inputs.length-1, candidate; idx<len; ++idx) {
            candidate = inputs.item(idx);
            if (candidate===elem) {return inputs.item(idx+1);}
        }
    }
    </script>
</body>

在下面 bobince 的有用评论之后,我将 getNextElement 函数中的一些 indexOfArray/slice 内容更改为在 IE 中也应该可以使用的内容。

【讨论】:

  • 在像HTMLCollection 这样的潜在主机对象上调用像Array.slice 这样的方法通常是不正当的。在任何情况下,ECMAScript 都没有定义构造函数属性Array.slice;那是 Mozilla 独有的。同样,Array#indexOf 是 IE 中不可用的第五版功能。
  • @bobince 哦,在数组上使用 indexOf 是一个疏忽,抱歉。修复了您对数组的关注,并添加了一些小的选项卡检查。谢谢指点。
【解决方案2】:
onKeyUp="fieldChange('textf1')"

没有在参数中传递event 对象。而是:

onkeyup="fieldChange('textf1', event)"

这适用于 IE(因为event 指的是全局变量window.event)和其他浏览器(因为event 指的是您使用on... 事件处理程序创建的函数的单个本地参数属性)。

您现在可以从 fieldChange 函数中删除 if (window.event) 代码,因为该事件将始终被传入。在您确实需要该事件的地方,最好先嗅探参数,然后再返回IE版本。通常像:

function somethingHandler(event) {
    event= event || window.event;
    ...
}

清理标记的另一件事是在事件处理程序中使用this

onkeyup="fieldChange(this, event)"

现在fieldChange 不必通过id 查找正确的元素,因为您已经有了对它的引用。

更好的是,丢失事件处理程序属性并更隐蔽地绑定。您也可以使用maxLength 属性,而不是在重新聚焦发生的确切时间构建长度逻辑。例如:

<input type="text" name="textf1" maxlength="2" class="movetonext" />
<input type="text" name="textf2" maxlength="2" class="movetonext" />
<input type="text" name="textf3" maxlength="4" class="movetonext" />

<script type="text/javascript">
    var elements= document.getElementById('myform').elements;
    for (var i= elements.length; i-->0;)
        if (elements[i].className==='movetonext')
            elements[i].onkeyup= checkMoveToNext;

    function checkMoveToNext() {
        if (this.value.length>=this.maxLength) {
            var elements= this.form.elements;
            var ix= List_indexOf(elements, this);
            ix= (ix+1)%elements.length;
            elements[ix].focus();
        }
    }

    function List_indexOf(list, item) {
        for (var i= 0, n= list.length; i<n; i++)
            if (list[i]===item)
                return i;
        return -1;
    }
</script>

【讨论】:

  • 谢谢,解决了!不知道如何发送事件,添加后它在 ff 中也能很好地工作!谢谢!还不错的补充,下班回家后去学习;)
  • @s4v10r 作为 Jquery 的家...先做,然后再处理这些事情。你可以使用 Jquery 编写更好的代码。没有跨浏览器问题...跨度>
  • 亲爱的主。狂热从未停止。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-04-01
  • 1970-01-01
  • 2012-09-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多