IMFFA
V2EX  ›  JavaScript

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

By IMFFA at 2020 年 1 月 13 日 · 7208 次点击

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

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

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

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));
推荐关注
› Meteor
› JSLint - a JavaScript code quality tool
› jsFiddle
› D3.js
› WebStorm
推荐书目
› JavaScript 权威指南第 5 版
› Closure: The Definitive Guide
© 2026 V2EX · 244ms · 3.9.8.5