一个“简单”web需求引发的思考

稿件来源: 阳光企业网站管理系统   撰稿作者: 太阳光   发表日期: 2013-11-16   阅读次数: 81   查看权限: 游客查看

一切从需求出发,想起曾经“坑爹”项目需求……

一个web项目需求超出环境能力那是坑人。曾经我遇到这样件事,Flex转出的swf文件因做了透明设置,在网页里输入中文时字符却跑到左上角,百思不得骑姐。最后确实是flash问题,如果不设置透明或者输入英文是没问题的,但我们那个flash是必须要透明的,且被DIV其他层挡住。没法,项目经验说了立马解决,不管你用什么方法!最终我们是很快解决了问题,坑人要求有坑人方法。

一个web项目需求超出指定实现方式那就是坑爹。比方说将军要求把敌军飞机打下来,士兵们蠢蠢欲动有拿枪的有拿炮的,但是将军突然说不能用其他武器,除了这个……,然后慢慢掏出一支鸟弓!这就是坑爹。

言归正传,我们来看一份web要求:

效果:
1、点击问题 + 号,新增一个问题(整个红色框是一个问题),点击 - 号,就删除一个问题。
2、点击答案 + 号,新增一个答案,点击 - 号,就删除那个答案。
3、在问题一上点击 + 号,新增加的问题则是在问题下展示,成为问题二。原来的问题二则变成问题三。删除问题也是同样的原理。
4、不管是在问题一上增加问题还是在问题三上增加问题还是删除问题,顺序都应该是 12345678...按顺序列下来的。
5、答案的顺序也是这样..不管是在哪个答案上点 + 号或者 - 号删除答案 ABCDEFG...都应该是按顺序列下来。
需求:
设置问题*必填的用js验证不能为空。
文本框里的的name属性只要按了 + 号的,每个问题的属性 name 都要不一样。
问题类型:单选题  多选题  主观题  选择了哪一个类型,哪一个类型下面的答案必须 js 验证不能为空。
每一个问题和上面的一样都需验证。

请原谅原文表述不清,我们自己来清理一下需求:其实就是做一份可复制的表单,技术上讲就是元素克隆,但远远没有你想象中的这么简单,这里坑多着呢。

首先需要能复制整个表单,而且是不管在哪个位置复制表单,都必须是在被点击对象的下面显示新表单。而且被复制出来的表单对应的文本应该是顺序排列(问题N,N的变化),意味着新表单及以下的表单都需要重新编号[坑1]。删除表单也是一样,被删除表单以下的表单需要重新编号。

答案的复制问题,基本跟表单一样,首先排序以ABC排序就是一个坑[坑2]意味着不能超过26个答案?
再看需求第二点是个特大的坑,input复制出来的name要求不一样!这话从何说起?后台需要接受大量连name都不知道的变量,后端的程序猿兄弟还不带刀过来闹呀[坑3]。

问题类型的单选框也是一个坑,因为radio组的名字必须不得相同才能正常使用,正常我们应该使用select或者checkbox解决的。没法,项目经验发话他想用哪就用啥[坑4]。

问题类型的单选框交互更是一个隐形大坑,点击”多选题”时需要改变它下面所有对应文字为“多选答案?”同时答案必须两个以上,如果选择“主观题”就隐藏所有答案输入框,并不需要验证答案是否为空,再点回“单选题”时,除了变文本外必须保证至少一个答案。三角关系相互扣住很是深的坑[坑5]。

解决方法:开始我是以原生javascript脚本编写。因兼容加上各种坑,用了大量脚本,还是疏忽了一个坑。今天加班没事我就用jQuery再编写了一下:

<!DOCTYPE html>
<html>
<head>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
    <title>jQuery 实现坑爹表单</title>
    <script src="http://ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min.js" type="text/javascript"></script>
    <style type="text/css">
        body{
            text-align: center;
            font: 14px "宋体";
            color: #666;
        }
        form{width: 660px;margin: 20px auto;}
        .input{
            border: 1px solid #ddd;
            width: 420px;
            height: 25px;
            vertical-align: middle;
        }
        ul,li{margin: 0;padding:0;list-style-type:none;}
        ul{
            border: 2px solid red;
            margin: 40px 0;
            text-align: left;
            padding: 20px 0 30px;
        }
        li{line-height: 40px;}
        label{
            display: inline-block;
            width: 125px;
            text-align: right;
            margin-right: 20px;
        }
        label span{color: red;}
        button{
            border: none;
            vertical-align: middle;
            width: 17px;
            height: 17px;
            cursor: pointer;
            background: url("pic.jpg") no-repeat right top;
            margin-left: 6px\9;/*兼容IE*/
        }
        .reduce{background-position: right -18px}
        .answer{height: 30px;line-height: 30px}
        .answer label{margin-left: 105px;}
        .answer .input{width: 315px;}
        .submit{
            width: 140px;
            height:45px;
            cursor: pointer;
            margin-top:20px;
            display: inline-block;
            border: none;
            background: url("pic.jpg") no-repeat /*含提交按钮及+ -符号的图片*/
        }
        /*css经过IE6-9\Chrome\Firefox\Safari\傲游\360\搜狗 测试*/
    </style>
</head>
<body>
<form action="#" method="post">
    <ul>
        <li>
            <label><span>*</span>问题一:</label>
            <input type="text" class="input" name="qxname_0" />
            <button type="button" class="add"></button>
            <button type="button" class="reduce"></button>
        </li>
        <li>
            <label><span>*</span>问题类型:</label>
            <input type="radio" name="raname_0" value="1" checked /> 单选题
            <input type="radio" name="raname_0" value="2" /> 多选题
            <input type="radio" name="raname_0" value="0" /> 主观题
        </li>
        <li>
            <div class="answer">
                <label>单选答案A:</label>
                <input type="text" class="input" name="answer_1" />
                <button type="button" class="add"></button>
                <button type="button" class="reduce"></button>
            </div>
        </li>
    </ul>
    <input type="submit" class="submit" value="" />
</form>
<script type="text/javascript">
    $(function(){
        var p_i= 1,word = "ABCDEFGHIJKLMNOPQRSTUVWXYZ",n_arr = ["零","一", "二", "三", "四", "五", "六", "七", "八", "九"],p_arr = ["","十","百","千","万"],clone =["<ul>"+$("ul").html()+"</ul>","<li>"+$("li:eq(2)").html()+"</li>"],t_arr = ["主观","单选","多选"];//定义相关变量
        $("button").live("click", function(){
            var c = $(this).parent().attr("class"),p = $(this).parent().parent();//获取父点击的Class与父父节点对象
            $(this).index() % 2 ? (p.parent().find(c ? ".answer" : "ul").size() > 1 && p.remove()) : p.after(clone[c ? 1 : 0 ].replace(/name_\d+/g,"name_"+(++p_i)));
            //自动判断是否删除还是新增,新增时更新input的name以防radio冲突。
            $("ul").each(function(i,item){
                var n=-1;//删除或者新增后重新排序,替换文本
                $("label",this).eq(0).html("<span>*</span>问题"+(i+1).toString().split("").reverse().join("").replace(/\d/g, function(k) {n++; return p_arr[n] + n_arr[k]}).split("").reverse().join("").replace(/零(千|百|十)/g, "零").replace(/(零)+/g, "零").replace(/(零)+$/g, "").replace(/一十/g,"十").replace(/二十/g,"廿")+":");//转化成中文数字
                var v =$("input[name^='raname']:checked",this).val();//返回 0:主观题 1:单选题 2:多选题
                $(".answer",this).each(function(i,item){
                    $("label",this).html(t_arr[v]+"答案"+word.charAt(i%26)+":");//因为只有26个字母,用完了又重新排序
                    $("input",this).attr("name",$("input",this).attr("name").replace(/answer_\d+/g,"answer_"+(i+1)));//每组答案的name都是从123456789排列
                });
            });
        });
        $("input[name^='raname']").live("click",function(){
            //点击 主观|单选|多选 单选框事件
            var v = $(this).val(),o = $(this).parent().nextAll();//获取值与所有答案所在的li对象
            o.find("label").each(function(){
                $(this).html($(this).html().replace(/主观|单选|多选/g,t_arr[v])); //对应修改文本
            });
            v=="0" ? o.hide() : o.show(); //判断显示还是隐藏
        });
        $("form").submit(function(){
            var ck = true;//提交表单检查 定义变量标注是否通过审核
            $("ul").each(function(i,item){
                var _this = this,first = $("input:first",_this),_i = i+1;//循环所有表单检查
                if(first.val()==""){
                    alert("第"+_i+"个问题不能为空!");//每个问题框必填
                    first.focus();//自动获取焦点
                    ck = false;//不通过
                    return false;
                }else{
                    var v = $("input:radio:checked",_this).val(),l = 0;//获取问题类型,和统计多少个答案
                    $(".answer input",_this).each(function(i,item){
                        if(v && $(this).val()==""){
                            alert("请填写第"+_i+"个问题的第"+(i+1)+"个答案!");//非主观题全部必填
                            $(this).focus();//自动获取焦点
                            ck = false;//不通过
                            return false;
                        }
                        l++;//统计答案个数
                    });
                    if(ck && v>l){
                        alert("第"+_i+"个问题是多选题,请多添加一个答案!");
                        first.focus();//自动获取焦点
                        ck = false;//不通过
                        return false;
                    }
                }
                return ck;//判断是否跳出each()
            });
            return ck;//返回表单是否验证成功
        })
    });
</script>
</body>
</html>

并附上使用的图片

在线测试点击浏览

 

关键词: 项目经验,需求   编辑时间: 2013-11-16 16:35:46

  • 感到高兴

    0

    高兴
  • 感到支持

    0

    支持
  • 感到搞笑

    0

    搞笑
  • 感到不解

    0

    不解
  • 感到谎言

    0

    谎言
  • 感到枪稿

    0

    枪稿
  • 感到震惊

    0

    震惊
  • 感到无奈

    0

    无奈
  • 感到无聊

    0

    无聊
  • 感到反对

    0

    反对
  • 感到愤怒

    0

    愤怒
0%(0)
0%(0)
共有0 条评论 发言请遵守【相关规定

网友评论

会员头像
发 表同步腾讯微博    验证码:  点击更新请先登陆
  • 暂无评论
关闭模块文章图片 article Pictrue
  • 我的妈妈爸爸
  • 基于koa2+mysql+vue2.0+Element阳光内容管理系统
  • 代码覆盖率工具 Istanbul 入门教程
  • 全栈工程师的武器——MEAN
  • 9款超炫的 CSS3 复选框(Checkbox)
  • 微信开发在线翻译功能
  • CSS3那些不为人知的高级属性
  • 给easyui的datebox添加清空事件
  • flash写字效果
  • kendoUI系列教程之DropDownList下拉菜单
  • kendoUI系列教程之datetimepicker日期时间选择
  • kendoUI系列教程之datepicker日期选择
  • kendoUI系列教程之combobox下拉列表框
  • kendoUI系列教程之colorpicker
  • kendoUI系列教程之calendar日历表
  • kendoUI系列教程之autocomplete自动补齐