请教一下,怎么把这段代码换一个优雅的写法 - V2EX
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
推荐关注
Meteor
JSLint - a Javascript code quality tool
jsFiddle
D3.js
WebStorm
推荐书目
Javascript 权威指南第 5 版
Closure: The Definitive Guide
IMFFA
V2EX    Javascript

请教一下,怎么把这段代码换一个优雅的写法

  •  
  •   IMFFA 2020-01-13 16:08:06 +08:00 6224 次点击
    这是一个创建于 2097 天前的主题,其中的信息可能已经有所发展或是发生改变。

    如下所示,一段拼接的 html 字符串,想要根据接受到的 value 不同,给不同的 radio 加 checked 属性。
    这样写实在太丑了
    var value = field.value;
    var checked1 = "";
    var checked2 = "";
    var checked3 = "";
    var checked4 = "";
    var checked5 = "";
    var checked6 = "";
    var checked7 = "";
    switch(value){
    case "1":
    checked1 = "checked";
    break;
    case "2":
    checked2 = "checked";
    break;
    case "3":
    checked3 = "checked";
    break;
    case "4":
    checked4 = "checked";
    break;
    case "5":
    checked5 = "checked";
    break;
    case "6":
    checked6 = "checked";
    break;
    case "7":
    checked7 = "checked";
    break;
    }
    var html = '<input id="cycle_type" type="radio" name="cycle_type" value="1" '+checked1+' title="日" lay-filter="cycle_type">'+
    '<input id="cycle_type" type="radio" name="cycle_type" value="2" '+checked2+' title="周" lay-filter="cycle_type">'+
    '<input id="cycle_type" type="radio" name="cycle_type" value="3" '+checked3+' title="半月" lay-filter="cycle_type">'+
    '<input id="cycle_type" type="radio" name="cycle_type" value="4" '+checked4+' title="月" lay-filter="cycle_type">'+
    '<input id="cycle_type" type="radio" name="cycle_type" value="5" '+checked5+' title="季" lay-filter="cycle_type">'+
    '<input id="cycle_type" type="radio" name="cycle_type" value="6" '+checked6+' title="半年" lay-filter="cycle_type">'+
    '<input id="cycle_type" type="radio" name="cycle_type" value="7" '+checked7+' title="年" lay-filter="cycle_type">';
    return html;

    54 条回复    2020-01-18 17:08:00 +08:00
    wszgrcy
        1
    wszgrcy  
       2020-01-13 16:09:10 +08:00 via Android
    能用就行
    dongisking
        2
    dongisking  
       2020-01-13 16:13:12 +08:00   1
    你是个后端吧
    IMFFA
        3
    IMFFA  
    OP
       2020-01-13 16:15:57 +08:00
    @dongisking 没错,我是个后端 o()o
    puzzle9
        4
    puzzle9  
       2020-01-13 16:16:08 +08:00 via Android
    @dongisking 赞同
    tabris17
        5
    tabris17  
       2020-01-13 16:17:59 +08:00   2
    不要拼接 HTML,直接操作 DOM
    sagaxu
        6
    sagaxu  
       2020-01-13 16:19:05 +08:00 via Android   2
    请教一下,怎么把这坨屎换一个优雅的吃法
    Kakus
        7
    Kakus  
       2020-01-13 16:20:17 +08:00
    把值放数组里面,用下标存取数据
    learnshare
        8
    learnshare  
       2020-01-13 16:20:51 +08:00
    后端通常有模板化的写法,不需要拼接字符串
    berforest
        9
    berforest  
       2020-01-13 16:21:54 +08:00
    写的好看有球用,用户又看不到
    violetlai
        10
    violetlai  
       2020-01-13 16:22:28 +08:00
    var someJson ={

    }
    $.each(someJson, function (k, v) {
    //判断条件
    if (){
    var ele = ""//html 拼接
    }
    //直接加到 html 里面
    $("#html").append(ele)
    })
    2pen
        11
    2pen  
       2020-01-13 16:23:02 +08:00
    var checked = [false,false,false,false]; checked[value] = true
    OnlyShimmer
        12
    OnlyShimmer  
       2020-01-13 16:26:38 +08:00   1
    let html = '';
    let TimeArr = ['日','周','半月','月','季','半年','年',]
    for(let i=1;i<7;i++){
    if(i==field.value){
    html += '<input id="cycle_type" type="radio" name="cycle_type" value="'+i+'" checked title="'+TimeArr[i]+'" lay-filter="cycle_type">'
    }else{
    html += '<input id="cycle_type" type="radio" name="cycle_type" value="'+i+'" title="'+TimeArr[i]+'" lay-filter="cycle_type">'
    }
    }
    return html;
    =================================
    献丑
    wa143825
        13
    wa143825  
       2020-01-13 16:27:02 +08:00   1
    let value = field.value
    let h = ''
    let titleArray = ['日','周','半月']
    return titleArray.forEach((e,idx) => {
    h += `<input id="cycle_type" type="radio" name="cycle_type" value="${idx+1}" ${v===idx+1 && 'checked'} title="${e}" lay-filter="cycle_type">`
    });
    Oceanhime
        14
    Oceanhime  
       2020-01-13 16:28:51 +08:00   1
    看头像还是个夏娜粉??

    你可以使用 JS 操作 DOM 动态设置,把这些 input 直接写到 html 里,不用带 checked,记得用 class 或 id 把年月日这些区分开。
    用 element.checked = true 设置 element 为 checked 状态,然后用 element.removeAttribute('checked'); 移除 element 的这个属性。
    然后你再根据 value 设置 checked 状态。例如:
    var v = field.value;
    switch(v){
    case 1: document.querySelector('.select-year').checked = true; break;
    case 2: document.querySelector('.select-month').checked = true; break;
    }
    不需要用 JS 构建 direct HTML 的。这种既乱又不好进行扩展。
    OnlyShimmer
        15
    OnlyShimmer  
       2020-01-13 16:33:48 +08:00
    我来领打脸了,没有跑过就放代码,后面看到的不要抽我脸
    =====
    function getType(e) {
    let html = '';
    let TimeArr = ['日','周','半月','月','季','半年','年']
    for(let i=1;i<=7;i++){
    if(i==e){
    html += '<input id="cycle_type" type="radio" name="cycle_type" value="'+i+'" checked title="'+TimeArr[i]+'" lay-filter="cycle_type">'
    }else{
    html += '<input id="cycle_type" type="radio" name="cycle_type" value="'+i+'" title="'+TimeArr[i]+'" lay-filter="cycle_type">'
    }
    }
    return html;
    }
    =====
    jeodeng
        16
    jeodeng  
       2020-01-13 16:36:13 +08:00   1
    var value = field.value;

    var cOnfig= [
    { value: 1, title: '日', checked: null },
    { value: 2, title: '周', checked: null },
    { value: 3, title: '半月', checked: null },
    { value: 4, title: '月', checked: null },
    { value: 5, title: '季', checked: null },
    { value: 6, title: '半年', checked: null },
    { value: 7, title: '年', checked: null },
    ];

    config[value - 1].checked = 'checked';

    var radioInit = (value, checked, title) => `<input id="cycle_type" type="radio" name="cycle_type" value="${value}" ${checked || ''} title="${title}" lay-filter="cycle_type">`;

    var html = config.reduce((acc, cur) => {
    return acc + radioInit(cur.value, cur.checked, cur.title);
    }, '');

    return html;
    ihuzhou
        17
    ihuzhou  
       2020-01-13 16:36:33 +08:00
    编程珠玑中吐槽了这种写法。用数组。建立适用的数据结构让程序更加优美。
    IMFFA
        18
    IMFFA  
    OP
       2020-01-13 16:37:11 +08:00
    @13725151469wy 哈哈哈,至少你写的结构比我好看多了,不要在意细节
    IMFFA
        19
    IMFFA  
    OP
       2020-01-13 16:38:45 +08:00
    感谢各位大胸弟,又学到了不少
    jeodeng
        20
    jeodeng  
       2020-01-13 16:39:06 +08:00
    嗯...config 里面 checked: null 可以去掉...习惯预设属性了
    @jeodeng
    minute
        21
    minute  
       2020-01-13 16:41:19 +08:00
    用 map
    zcreg
        22
    zcreg  
       2020-01-13 16:47:44 +08:00
    不管前后端都要活用数组与 MAP,代码要像裙子越短越好
    sagaxu
        23
    sagaxu  
       2020-01-13 16:56:03 +08:00 via Android
    const periods = ['日','周','半月','月','季','半年','年'];
    const checked = 2;

    const html = periods.map((v,i) => `<input id="cycle_type" type="radio" name="cycle_type" value="${i}"
    ${i === checked ? 'checked' : ''} title="${periods[i]}" lay-filter="cycle_type">`).join("\n")
    ncwtf
        24
    ncwtf  
       2020-01-13 17:09:16 +08:00
    hhh
    ncwtf
        25
    ncwtf  
       2020-01-13 17:11:19 +08:00
    @sagaxu 这段代码 hin 叼
    xq546247083
        26
    xq546247083  
       2020-01-13 17:15:37 +08:00
    用字典
    ncwtf
        27
    ncwtf  
       2020-01-13 17:17:16 +08:00
    <input id="radio_tmp" type="radio" name="cycle_type" lay-filter="cycle_type" style="display:none">

    var value = field.value;

    var radioId = 'cycle_type';
    var titleArr= ["", "日", "周", "半月", "月", "季", "半年", "年"]

    for(var i = 1;i < titleArr.length;i++) {
    var rt = $("#radio_tmp").clone();
    rt.attr("id", radioId + i);
    rt.attr("value", i);
    rt.attr("title", titleArr[i]);
    rt.prop("checked", i == value);
    rt.attr("style", "");

    $("#html").append(rt);
    }

    老式 jQuery 法,后端专用
    kuoruan
        28
    kuoruan  
       2020-01-13 17:20:14 +08:00
    楼上动不动就 let const 和 箭头函数的,莫非都是默认楼主用 babel 的?
    ncwtf
        29
    ncwtf  
       2020-01-13 17:25:28 +08:00
    @kuoruan 我刚搜了下,浏览器不支持这种写法吗?我看写 vue 的都这么写 js
    meepo3927
        30
    meepo3927  
       2020-01-13 17:29:09 +08:00
    友情提示:记得把 let 和 const 换成 var
    shintendo
        31
    shintendo  
       2020-01-13 17:33:08 +08:00
    @kuoruan 正儿八经进了语言标准的东西,怎么就不能用了,又不是草案语法。讨论个写法问题还得考虑 ie 兼容吗
    purensong
        32
    purensong  
       2020-01-13 17:34:50 +08:00
    @ncwtf var value = field.value; field 没定义啊
    sagaxu
        33
    sagaxu  
       2020-01-13 17:35:50 +08:00 via Android
    @kuoruan 2015 年之后的主流浏览器都支持这么写,至于 5 年前的老浏览器,项目不一定非要兼容
    ncwtf
        34
    ncwtf  
       2020-01-13 17:45:14 +08:00
    @purensong lz 也没定义啊
    wangyzj
        35
    wangyzj  
       2020-01-13 17:58:45 +08:00
    你一后端,这样就挺优雅了
    kumasama
        36
    kumasama  
       2020-01-13 18:13:21 +08:00
    哈哈,一看就是后端码农写的---
    kumasama
        37
    kumasama  
       2020-01-13 18:15:33 +08:00
    别用 es6 的写法呢,不兼容
    secondwtq
        38
    secondwtq  
       2020-01-13 19:01:21 +08:00
    语言只是表达计算的工具,就算楼主的项目不能用 ES6+,人肉 babel 把楼上的 Snippet 改改也能用。
    busfool
        39
    busfool  
       2020-01-13 19:28:26 +08:00 via Android
    你这是凑行数吧。感觉可以加 id 或者 class,再改变元素属性。
    aimiyooo
        40
    aimiyooo  
       2020-01-13 20:41:47 +08:00
    恭喜你,可以和蚂蚁金服 pk 行数了
    Jackliu
        41
    Jackliu  
       2020-01-13 22:47:07 +08:00
    欢迎来我司 因为我司每天统计代码行数
    danhahaha
        42
    danhahaha  
       2020-01-13 22:49:15 +08:00
    用毛笔?
    Dkngit
        43
    Dkngit  
       2020-01-13 23:05:24 +08:00
    function getHTML(value) {
    const arr = ['日', '周', '半月', '月', '季', '半年', '年'];
    let html = "";
    arr.forEach((item, index) => {
    html += "<input id=\"cycle_type\" type=\"radio\" name=\"cycle_type\" value=\"" + (index + 1) + "\" " + value === (index + 1) ? 'checked' : '' + " title=\"" + item + "\" lay-filter=\"cycle_type\">"
    });
    return html
    }
    DFFZMXJ
        44
    DFFZMXJ  
       2020-01-13 23:21:43 +08:00
    return ['日', '周', '半月', '月', '季', '半年', '年'].map(
    (title, index) => `<input id="cycle_type" type="radio" name="cycle_type" value="${index+1}" ${field.value===index+1?'checked':''} title="日" lay-filter="cycle_type">`
    ).join('');
    Stictonotus
        45
    Stictonotus  
       2020-01-13 23:29:11 +08:00 via iPad
    所以为什么要拼接字符串构建 HTML 呢,前端构建字符串 HTML 前期确实能用,但是是一大坨,后期的扩展性可维护性也很低。比如如果你后期要加东西的话,还得考虑前面的逻辑,然后再对着那一坨 HTML 改。但是如果你动态声明,每个属性显而易见,要改什么属性直接在后面加个操作就行了。前面的 #27 #14 都有解决的代码。
    但是如果你确实要构建 HTML,那建议你使用循环,一个一个复制粘贴可能是上古写法。
    JerryCha
        46
    JerryCha  
       2020-01-14 00:40:23 +08:00
    vue.js 请
    sugars
        47
    sugars  
    PRO
       2020-01-14 08:34:31 +08:00
    @ncwtf 并不是所有浏览器支持 es6 等新的 js 语法,有些浏览器老的版本不兼容,所以才需要使用一个转换的工具就是楼上有人提到的 babel 了,它能将新的 js 语法转换成所有浏览器都支持的最原生的 js 语法
    sugars
        48
    sugars  
    PRO
       2020-01-14 08:56:29 +08:00   1
    按楼主的意思写了几个版本,见笑了

    beingWH
        49
    beingWH  
       2020-01-14 09:48:47 +08:00
    看了以上的答案,还是觉得 C#才够得上优美两个字。。。
    $"<input id='cycle_type' type='radio' name='cycle_type' value='1' {(field.value == "1"?"checked":null)} title='日' lay-filter='cycle_type'><input id='cycle_type' type='radio' name='cycle_type' value='2' {(field.value == "2" ? "checked" : null)} title='周' lay-filter='cycle_type'><input id='cycle_type' type='radio' name='cycle_type' value='3' {(field.value == "3" ? "checked" : null)} title='半月' lay-filter='cycle_type'><input id='cycle_type' type='radio' name='cycle_type' value='4' {(field.value == "4" ? "checked" : null)} title='月' lay-filter='cycle_type'><input id='cycle_type' type='radio' name='cycle_type' value='5'{(field.value == "5" ? "checked" : null)} title='季' lay-filter='cycle_type'><input id='cycle_type' type='radio' name='cycle_type' value='6'{(field.value == "6" ? "checked" : null)} title='半年' lay-filter='cycle_type'><input id='cycle_type' type='radio' name='cycle_type' value='7' {(field.value == "7" ? "checked" : null)} title='年' lay-filter='cycle_type'>"
    happy7902
        50
    happy7902  
       2020-01-14 09:59:47 +08:00 via iPhone
    这就是互联网程序员的水平?
    lands
        51
    lands  
       2020-01-14 15:04:01 +08:00
    用这种写法, 离一年 4 亿行代码的目标又近了一步
    vagranth
        52
    vagranth  
       2020-01-14 15:37:41 +08:00
    1. 把那些"日 /周 /月……"常量写在数组里
    2. 根据数组,for 循环生成 html
    3. 循环时,当 value 匹配,增加 checked 属性
    lllllliu
      nbsp; 53
    lllllliu  
       2020-01-14 18:18:35 +08:00
    ```Javascript
    /**
    * @name createRadioGroup
    * @description createRadioGroup
    * @author v2er
    * @date 2020-01-14
    * @param {String} name "Diy"
    * @param {Array} data [{title:"date",value:1,checked:false}]
    * @returns {String} "HtmlCode"
    */
    function createRadioGroup(name,data){
    if(data.length == 0) return;
    var html = [];
    for(var i = 0; i < data.length ; i ++){
    var input = window.document.createElement("input")
    input.type = "radio"
    input.name = name
    input.value = data[i].value
    input.title = data[i].title
    input.defaultChecked = data[i].checked
    html.push(input.outerHTML)
    }
    return html.join("")
    }
    var data = [
    {title:"年",value:1,checked:true},
    {title:"月",value:1,checked:false},
    {title:"日",value:1,checked:false},
    ]
    createRadioGroup("date",data);
    //<input type="radio" name="date" value="1" title="年" checked=""><input type="radio" name="date" value="1" title="月"><input type="radio" name="date" value="1" title="日">"
    ```
    wangkiliaosi8899
        54
    wangkiliaosi8899  
       2020-01-18 17:08:00 +08:00
    看样子楼主深谙命令式编程的精髓;

    function resolve(value){
    const time = ['日','周','半月','月','季','半年','年'];
    if(!Number.isInteger(value) || value>time.length){
    throw new Error(`参数错误:需要 1~7 的整数`);
    }
    return Array.from(Array(time.length)).reduce((result, _c, index)=>{
    const template = `<input
    id="cycle_type_${index}"
    type="radio"
    name="cycle_type"
    value="${index+1}"
    ${index+1===value?"checked":''}
    title="${time[index]}"
    lay-filter="cycle_type">`;
    return result+template
    },'')
    }

    console.log(resolve(2));
    关于     帮助文档     自助推广系统     博客     API     FAQ     Solana     6109 人在线   最高记录 6679       Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 33ms UTC 03:17 PVG 11:17 LAX 20:17 JFK 23:17
    Do have faith in what you're doing.
    ubao snddm index pchome yahoo rakuten mypaper meadowduck bidyahoo youbao zxmzxm asda bnvcg cvbfg dfscv mmhjk xxddc yybgb zznbn ccubao uaitu acv GXCV ET GDG YH FG BCVB FJFH CBRE CBC GDG ET54 WRWR RWER WREW WRWER RWER SDG EW SF DSFSF fbbs ubao fhd dfg ewr dg df ewwr ewwr et ruyut utut dfg fgd gdfgt etg dfgt dfgd ert4 gd fgg wr 235 wer3 we vsdf sdf gdf ert xcv sdf rwer hfd dfg cvb rwf afb dfh jgh bmn lgh rty gfds cxv xcv xcs vdas fdf fgd cv sdf tert sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf shasha9178 shasha9178 shasha9178 shasha9178 shasha9178 liflif2 liflif2 liflif2 liflif2 liflif2 liblib3 liblib3 liblib3 liblib3 liblib3 zhazha444 zhazha444 zhazha444 zhazha444 zhazha444 dende5 dende denden denden2 denden21 fenfen9 fenf619 fen619 fenfe9 fe619 sdf sdf sdf sdf sdf zhazh90 zhazh0 zhaa50 zha90 zh590 zho zhoz zhozh zhozho zhozho2 lislis lls95 lili95 lils5 liss9 sdf0ty987 sdft876 sdft9876 sdf09876 sd0t9876 sdf0ty98 sdf0976 sdf0ty986 sdf0ty96 sdf0t76 sdf0876 df0ty98 sf0t876 sd0ty76 sdy76 sdf76 sdf0t76 sdf0ty9 sdf0ty98 sdf0ty987 sdf0ty98 sdf6676 sdf876 sd876 sd876 sdf6 sdf6 sdf9876 sdf0t sdf06 sdf0ty9776 sdf0ty9776 sdf0ty76 sdf8876 sdf0t sd6 sdf06 s688876 sd688 sdf86