首页   注册   登录
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 · 41 天前 · 3753 次点击
    这是一个创建于 41 天前的主题,其中的信息可能已经有所发展或是发生改变。

    如下所示,一段拼接的 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   41 天前 via Android
    能用就行
    dongisking
        2
    dongisking   41 天前   ❤️ 1
    你是个后端吧
    IMFFA
        3
    IMFFA   41 天前
    @dongisking 没错,我是个后端 o(╥﹏╥)o
    puzzle9
        4
    puzzle9   41 天前 via Android
    @dongisking 赞同
    tabris17
        5
    tabris17   41 天前   ❤️ 2
    不要拼接 HTML,直接操作 DOM
    sagaxu
        6
    sagaxu   41 天前 via Android   ❤️ 2
    请教一下,怎么把这坨屎换一个优雅的吃法
    Kakus
        7
    Kakus   41 天前
    把值放数组里面,用下标存取数据
    learnshare
        8
    learnshare   41 天前
    后端通常有模板化的写法,不需要拼接字符串
    berforest
        9
    berforest   41 天前
    写的好看有球用,用户又看不到
    violetlai
        10
    violetlai   41 天前
    var someJson ={

    }
    $.each(someJson, function (k, v) {
    //判断条件
    if (){
    var ele = ""//html 拼接
    }
    //直接加到 html 里面
    $("#html").append(ele)
    })
    2pen
        11
    2pen   41 天前
    var checked = [false,false,false,false]; checked[value] = true
    13725151469wy
        12
    13725151469wy   41 天前   ❤️ 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   41 天前   ❤️ 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   41 天前   ❤️ 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 的。这种既乱又不好进行扩展。
    13725151469wy
        15
    13725151469wy   41 天前
    我来领打脸了,没有跑过就放代码,后面看到的不要抽我脸
    =====
    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   41 天前   ❤️ 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   41 天前
    编程珠玑中吐槽了这种写法。用数组。建立适用的数据结构让程序更加优美。
    IMFFA
        18
    IMFFA   41 天前
    @13725151469wy 哈哈哈,至少你写的结构比我好看多了,不要在意细节
    IMFFA
        19
    IMFFA   41 天前
    感谢各位大胸弟,又学到了不少
    jeodeng
        20
    jeodeng   41 天前
    嗯...config 里面 checked: null 可以去掉...习惯预设属性了
    @jeodeng
    243560619
        21
    243560619   41 天前
    用 map
    zcreg
        22
    zcreg   41 天前
    不管前后端都要活用数组与 MAP,代码要像裙子越短越好
    sagaxu
        23
    sagaxu   41 天前 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   41 天前
    hhh
    ncwtf
        25
    ncwtf   41 天前
    @sagaxu 这段代码 hin 叼
    xq546247083
        26
    xq546247083   41 天前
    用字典
    ncwtf
        27
    ncwtf   41 天前
    <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   41 天前
    楼上动不动就 let const 和 箭头函数的,莫非都是默认楼主用 babel 的?
    ncwtf
        29
    ncwtf   41 天前
    @kuoruan 我刚搜了下,浏览器不支持这种写法吗?我看写 vue 的都这么写 js
    meepo3927
        30
    meepo3927   41 天前
    友情提示:记得把 let 和 const 换成 var
    shintendo
        31
    shintendo   41 天前
    @kuoruan 正儿八经进了语言标准的东西,怎么就不能用了,又不是草案语法。讨论个写法问题还得考虑 ie 兼容吗
    purensong
        32
    purensong   41 天前
    @ncwtf var value = field.value; field 没定义啊
    sagaxu
        33
    sagaxu   41 天前 via Android
    @kuoruan 2015 年之后的主流浏览器都支持这么写,至于 5 年前的老浏览器,项目不一定非要兼容
    ncwtf
        34
    ncwtf   41 天前
    @purensong lz 也没定义啊
    wangyzj
        35
    wangyzj   41 天前
    你一后端,这样就挺优雅了
    kumasama
        36
    kumasama   41 天前
    哈哈,一看就是后端码农写的---
    kumasama
        37
    kumasama   41 天前
    别用 es6 的写法呢,不兼容
    secondwtq
        38
    secondwtq   41 天前
    语言只是表达计算的工具,就算楼主的项目不能用 ES6+,人肉 babel 把楼上的 Snippet 改改也能用。
    busfool
        39
    busfool   41 天前 via Android
    你这是凑行数吧。感觉可以加 id 或者 class,再改变元素属性。
    aimiyooo
        40
    aimiyooo   41 天前
    恭喜你,可以和蚂蚁金服 pk 行数了
    Jackliu
        41
    Jackliu   41 天前
    欢迎来我司 因为我司每天统计代码行数
    danhahaha
        42
    danhahaha   41 天前
    用毛笔?
    Dkngit
        43
    Dkngit   41 天前
    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   41 天前
    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   41 天前 via iPad
    所以为什么要拼接字符串构建 HTML 呢,前端构建字符串 HTML 前期确实能用,但是是一大坨,后期的扩展性可维护性也很低。比如如果你后期要加东西的话,还得考虑前面的逻辑,然后再对着那一坨 HTML 改。但是如果你动态声明,每个属性显而易见,要改什么属性直接在后面加个操作就行了。前面的 #27 #14 都有解决的代码。
    但是如果你确实要构建 HTML,那建议你使用循环,一个一个复制粘贴可能是上古写法。
    JerryCha
        46
    JerryCha   41 天前
    vue.js 请
    sugars
        47
    sugars   41 天前
    @ncwtf 并不是所有浏览器支持 es6 等新的 js 语法,有些浏览器老的版本不兼容,所以才需要使用一个转换的工具就是楼上有人提到的 babel 了,它能将新的 js 语法转换成所有浏览器都支持的最原生的 js 语法
    sugars
        48
    sugars   41 天前   ❤️ 1
    按楼主的意思写了几个版本,见笑了

    beingWH
        49
    beingWH   41 天前
    看了以上的答案,还是觉得 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   41 天前 via iPhone
    这就是互联网程序员的水平?
    lands
        51
    lands   40 天前
    用这种写法, 离一年 4 亿行代码的目标又近了一步
    vagranth
        52
    vagranth   40 天前
    1. 把那些"日 /周 /月……"常量写在数组里
    2. 根据数组,for 循环生成 html
    3. 循环时,当 value 匹配,增加 checked 属性
    lllllliu
        53
    lllllliu   40 天前
    ```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   36 天前
    看样子楼主深谙命令式编程的精髓;

    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));
    关于   ·   FAQ   ·   API   ·   我们的愿景   ·   广告投放   ·   感谢   ·   实用小工具   ·   3661 人在线   最高记录 5168   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 26ms · UTC 05:09 · PVG 13:09 · LAX 21:09 · JFK 00:09
    ♥ Do have faith in what you're doing.