【问题标题】:Making Dynamic JQuery Switch Statement Less Bulky使动态 JQuery Switch 语句更简洁
【发布时间】:2013-09-10 14:50:55
【问题描述】:

我有一个 php 页面,上面有几个表单。总共大约 9 个,但为了简洁起见,我的示例仅反映 4 个。我终于得到了代码来成功找到元素 id,具体取决于单击它的表单上的哪个按钮,并验证 url 是否已正确添加到表单中,如果没有,它将显示错误消息并突出显示输入(同时还留下一个支持跨度标签中 div 底部的错误消息。代码运行良好,如果需要,欢迎任何人使用它。我只需要帮助来压缩它。有没有办法让 Switch 不那么笨重?

===EXAMPLE FORM HTML(一页上有好几个)===

<div class="thumbnail">

    <form id="buyMe" action="#" method="post">
            <input type="hidden" name="none" value="#">
            <input type="hidden" name="#">
        <table id="myTable">
            <tr><td><select id="select" name="os0">
                    <option value="opt1">option 1</option>
                    <option value="opt2">Option 2</option>
                    <option value="opt3">Option 3</option>
                    <option value="opt4">Option 4</option>
                </select> 
            </td></tr>
            <tr><td><input type="hidden" id="on1" name="on1" value="This Title">This One Title</td></tr>
            <tr><td><input id="os1" type="text" value="http://" name="urlText" maxlength="200"></td></tr>
        </table>
            <input type="hidden" name="something" value="something">
            <button alt="tryThis" id="purchase1" name="submit" class="btn" type="image">Try This</button>
            <img alt="" border="0" src="pixel.gif" width="1" height="1">
    </form>
    <span id="msgsText1">Error Msgs appear here</span>
</div> 

=== JQuery SWITCH/CASE ==

    //BEGINNING OF SWITCH CODE
    emptyerror2 = "Please enter a valid URL";
    htmlEmpty = "Please use the proper URL format";
    success2 = "Added to cart successfully!";

$(' :button').click(function (e) {
    var btns = ["purchase1", "purchase2", "purchase3", "purchase4"];
    for (var i = 0, ii = btns.length; i < ii; i++) {
        var aTc = btns[i];
        var whatSpan = $(this).parent('#buyMe').nextAll('span').eq(0).attr('id');
        var msgSpan = $('#'+ whatSpan);
        var whoseInput = $(this).siblings('#myTable').find(':input').eq(2).attr('id');
        var myInput = $('#'+ whoseInput);
        if ((e.target || e.srcElement).id == aTc) {
            switch (aTc) {
                case 'purchase1':
                            if (!/(ftp|http|https):\/\/(\w+:{0,1}\w*@)?(\S+)(:[0-9]+)?(\/|\/([\w#!:.?+=&%@!\-\/]))?/.test(myInput.val())) {
                            myInput.addClass("errorAlert");
                            myInput.val(emptyerror2);
                            msgSpan.addClass("text-error");
                            msgSpan.html(htmlEmpty);
                            return false;
                            } else {
                            myInput.removeClass("errorAlert");
                            msgSpan.removeClass("text-error");
                            msgSpan.addClass("text-success");
                            msgSpan.html(success2);
                            return true;
                            } // end of if else
                        break;
                case 'purchase2':
                            if (!/(ftp|http|https):\/\/(\w+:{0,1}\w*@)?(\S+)(:[0-9]+)?(\/|\/([\w#!:.?+=&%@!\-\/]))?/.test(myInput.val())) {
                            myInput.addClass("errorAlert");
                            myInput.val(emptyerror2);
                            msgSpan.addClass("text-error");
                            msgSpan.html(htmlEmpty);
                            return false;
                            } else {
                            myInput.removeClass("errorAlert");
                            msgSpan.removeClass("text-error");
                            msgSpan.addClass("text-success");
                            msgSpan.html(success2);
                            return true;
                            } // end of if else
                        break;
                case 'purchase3':
                            if (!/(ftp|http|https):\/\/(\w+:{0,1}\w*@)?(\S+)(:[0-9]+)?(\/|\/([\w#!:.?+=&%@!\-\/]))?/.test(myInput.val())) {
                            myInput.addClass("errorAlert");
                            myInput.val(emptyerror2);
                            msgSpan.addClass("text-error");
                            msgSpan.html(htmlEmpty);
                            return false;
                            } else {
                            myInput.removeClass("errorAlert");
                            msgSpan.removeClass("text-error");
                            msgSpan.addClass("text-success");
                            msgSpan.html(success2);
                            return true;
                            } // end of if else
                        break;
                case 'purchase4':
    if (!/(ftp|http|https):\/\/(\w+:{0,1}\w*@)?(\S+)(:[0-9]+)?(\/|\/([\w#!:.?+=&%@!\-\/]))?/.test(myInput.val())) {
                            myInput.addClass("errorAlert");
                            myInput.val(emptyerror2);
                            msgSpan.addClass("text-error");
                            msgSpan.html(htmlEmpty);
                            return false;
                            } else {
                            myInput.removeClass("errorAlert");
                            msgSpan.removeClass("text-error");
                            msgSpan.addClass("text-success");
                            msgSpan.html(success2);
                            return true;
                            } // end of if else
                        break;
               }//end of switch
            } //end of if
        } // end of for loop
    }); //end of button event code

【问题讨论】:

  • 案例之间到底有什么区别?他们似乎都在做同样的事情......
  • 如果案例之间没有区别,那么您可以完全摆脱开关
  • 如前文所述,有几个带有提交按钮的表单(即:purchase1、purchase2、purchase3、purchase4)为简洁起见,我只发布了1个表单。我需要这些案例来跟踪单击了哪个按钮,因为 myInput 和 msgSpan 等变量是动态的,并且会根据单击的提交按钮而变化。例如,单击 purchase3 提交按钮将导致 myInput id 更改为 os3 并且 msgSpan 现在将变为 msgsText3。虽然,我看到 Tarnation 是对的,但我什至可能根本不需要 switch 语句。

标签: jquery forms button switch-statement


【解决方案1】:

我不太确定您是否需要循环或开关。 switch 语句看起来都一样。跨度和输入似乎都由执行上下文决定。只是:

  $(' :button').click(function (e) {
        var whatSpan = $(this).parent('#buyMe').nextAll('span').eq(0).attr('id');
        var msgSpan = $('#'+ whatSpan);
        var whoseInput = $(this).siblings('#myTable').find(':input').eq(2).attr('id');
        var myInput = $('#'+ whoseInput);
        if (!/(ftp|http|https):\/\/(\w+:{0,1}\w*@)?(\S+)(:[0-9]+)?(\/|\/([\w#!:.?+=&%@!\-\/]))?/.test(myInput.val())) {
                            myInput.addClass("errorAlert");
                            myInput.val(emptyerror2);
                            msgSpan.addClass("text-error");
                            msgSpan.html(htmlEmpty);
                            return false;
                            } else {
                            myInput.removeClass("errorAlert");
                            msgSpan.removeClass("text-error");
                            msgSpan.addClass("text-success");
                            msgSpan.html(success2);
                            return true;
                            }

如果您担心“杂散”点击事件(页面上有其他按钮),请给这四个单独的类。否则,您似乎只是在检查按钮是否是四个之一(您可以知道它在哪里),并且无论如何都执行相同的验证。当然,我可能会遗漏一些东西!

【讨论】:

  • 谢谢。你的建议很有道理。我会测试一下,当我下次有能力的时候,让你知道。
  • 谢谢。这运作良好,并清理了庞大的冗余。我认为你的代码只需要一个 });最后关闭按钮点击功能。再次感谢。
【解决方案2】:

有几种方法可以使代码更紧凑。

一种是用一个对象来做切换:

var switcher = { 'purchase1': purchase1, ... };
...
switcher[aTc]();

这使您可以将代码分散到多个函数中。接下来,似乎每个 switch 语句中的代码看起来非常相似。所以你可以使用这个模式:

var data = { msgSpan: $('#'+ whatSpan), ... };
var validators = { 'purchase1': function(text) {
    return !/(ftp|http|https):\/\/(\w+:{0,1}\w*@)?(\S+)(:[0-9]+)?(\/|\/([\w#!:.?+=&%@!\-\/]))?/.test(text); }
    ...
};
var validator = validators[aTc];
updateUI(data, validator(myInput.val()));

updateUI 函数对于每种情况都是相同的。

这种方法允许您将庞大的函数拆分为许多可以独立测试的小构建块。您还可以为每一部分赋予有意义的名称,作为可靠的文档来源。

或者您可以在创建验证器时使用 jQuery.data() 将验证器附加到元素上,并像这样使用它:

var validator = myInput.data('validator');
updateUI(data, validator(myInput.val()));

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-06-17
    • 1970-01-01
    • 1970-01-01
    • 2021-04-11
    • 1970-01-01
    • 2015-10-27
    • 1970-01-01
    相关资源
    最近更新 更多