<script>
// 根据数组动态生成页面
const arr = [{
id: 1,
name: '1',
sex: '5',
age: '1',
city: '小饼'
},{
id: 2,
name: '1',
sex: '3',
age: '10',
city: '羊肉串'
}
];
// 城市数组
const cityArr = ['猪肉串', '羊肉串', '板筋', '牛肉串', '小饼'];
// 获取标签对象
const oTbody = document.querySelector('tbody');
// 获取 新增相关 标签对象
const oAdd = document.querySelector('.add');
// 确定按钮
const oBtnEnsure = oAdd.querySelectorAll('button')[0];
// 重置按钮
const oBtnReset = oAdd.querySelectorAll('button')[1];
// 桌号
const oIptName = oAdd.querySelector('[name="name"]');
// 单价
const oIptAge = oAdd.querySelector('[name="age"]');
// 数量
const oIptSex = oAdd.querySelectorAll('[name="sex"]');
// 菜品
const oSelCity = oAdd.querySelector('[name="city"]');
// 获取 修改相关 标签对象
const oChange = document.querySelector('.change');
// 确定按钮
const oBtnEnsureChange = oChange.querySelectorAll('button')[0];
// 取消按钮
const oBtnCancelChange = oChange.querySelectorAll('button')[1];
// 桌号
const oIptNameChange = oChange.querySelector('[name="name"]');
// 单价
const oIptAgeChange = oChange.querySelector('[name="age"]');
// 数量
const oIptSexChange = oChange.querySelectorAll('[name="sex"]');
// 菜品
const oSelCityChange = oChange.querySelector('[name="city"]');
// 菜品option
const oOptChange = oChange.querySelectorAll('option');
// 定义一个变量
// 存储 修改标签 对应的索引下标
let index;
// 调用函数动态渲染生成页面
setPage();
// 封装函数 动态渲染生成页面
function setPage() {
// 空数组 生成 对应的 空内容
if (arr.length === 0) {
oTbody.innerHTML = '<tr><td colspan="7">没有匹配数据</td></tr>';
return;
}
let str = '';
arr.forEach(function (item, key) {
str += `
<tr>
<td>${item.id}</td>
<td>${item.name}</td>
<td>${item.city}</td>
<td>${item.age}</td>
<td>${item.sex}</td>
<td><button name="del" index="${key}">删除</button></td>
<td><button name="change" index="${key}">修改</button></td>
</tr>
`;
})
oTbody.innerHTML = str;
}
// 新增
// 给确定按钮添加点击事件
oBtnEnsure.addEventListener('click', function () {
// 弹出确认框,点击确定之后,再执行程序
// 也就是 window.confirm() 的返回值是true,再执行程序
if (window.confirm('您确定要添加吗?')) {
// 获取数据
// 获取 姓名
let name = oIptName.value;
console.log(name);
// 获取 年龄 转化为数值类型
let age = oIptAge.value - 0;
// 获取 城市
// 通过 数组 将 城市对应的数值 转化为具体的中文数据
let city = cityArr[oSelCity.value];
// 获取 性别
let sex = oIptSex.value;
// ==================== for (let i = 0; i <= oIptSex.length - 1; i++) {
// if (oIptSex[i].checked) {
// sex = oIptSex[i].value;
// break;
// }
// }
//这里也可以用forEach,但是forEach会从头循环到尾,不如用for循环,可以在找到满足条件之后终止循环
// oIptSex.forEach(function (item) {
// if (item.checked) {
// sex = item.value;
// }
// })
// 新增id 是 原始数据中 最后一个数据单元id值 +1
let id = arr[arr.length - 1].id + 1;
// 生成一个对象,写入数组的末位
arr.push({
id: id,
name: name,
sex: sex,
age: age,
city: city
})
console.log(arr);
// 再次调用函数,动态渲染生成新的页面
setPage();
}
})
// 给重置按钮添加点击事件
oBtnReset.addEventListener('click', function () {
oIptName.value = '';
oIptAge.value = '';
for (let i = 0; i <= oIptSex.length - 1; i++) {
oIptSex[i].checked = false;
}
oSelCity.value = 0;
})
// 给<tbody>标签添加点击事件
// 通过事件委托实现项目需求
oTbody.addEventListener('click', function (e) {
// 根据 e.target不同的name,判断点击的是什么标签,执行不同程序
// 删除程序
if (e.target.getAttribute('name') === 'del') {
// 弹出确认框,点击确定后再执行删除程序
if (!window.confirm('您确定要删除吗?')) {
return;
}
// 在数组中按照点击删除按钮存储的索引下标,删除一个单元
arr.splice(Number(e.target.getAttribute('index')), 1);
// 根据新数组,动态渲染生成页面
setPage();
// 修改程序
} else if (e.target.getAttribute('name') === 'change') {
// 让修改的div标签出现
oChange.style.display = 'flex'; // css样式中用了弹性盒子,所以这里要用display:flex
// 给变量赋值存储修改标签对应的索引下标
index = Number(e.target.getAttribute('index'));
// 显示要修改的原始数据
// 姓名、年龄,直接赋值
oIptNameChange.value = arr[index].name;
oIptAgeChange.value = arr[index].age;
// 循环遍历存储性别的 input伪数组
// 哪个标签的 value和数组对象中 sex的键值相同,就添加 checked,默认选中。
for (let i = 0; i <= oIptSexChange.length - 1; i++) {
if (oIptSexChange[i].value === arr[index].sex) {
// 给对应的性别得 input标签添加选中效果
oIptSexChange[i].checked = true;
// 终止循环
break;
}
}
// 循环遍历 城市option伪数组
// select>option标签 的 内容 和 数组arr中对应的对象的city数据相同
// 给 这个 select>option标签 添加 选中效果
for (let i = 0; i <= oOptChange.length - 1; i++) {
if (oOptChange[i].innerHTML === arr[index].city) {
oOptChange[i].selected = true;
}
}
}
})
// 给修改页面里面的 确定按钮添加点击事件
oBtnEnsureChange.addEventListener('click', function () {
// 弹出确认框,点击确定再执行程序
if (window.confirm('您确定要修改吗?')) {
// 获取 修改标签中的数据数值
// 获取 姓名
let name = oIptNameChange.value;
// 获取 年龄,转化为数值类型
let age = oIptAgeChange.value - 0;
// 获取 城市
// 通过数组,将城市对应的数值转化为具体的中文数据
let city = cityArr[oSelCityChange.value];
// 获取 性别
let sex = oIptSexChange.value;
for (let i = 0; i <= oIptSexChange.length - 1; i++) {
if (oIptSexChange[i].checked) {
sex = oIptSexChange[i].value;
break;
}
}
// 修改点击的修改标签中 存储的索引下标对应的数组中的对象所存储的数据
arr[index].name = name;
arr[index].age = age;
arr[index].sex = sex;
arr[index].city = city;
// 调用函数 根据新的数组动态渲染生成页面
setPage();
// 让 修改 页面 再次隐藏
oChange.style.display = 'none';
}
})
// 给修改的取消按钮添加点击事件
oBtnCancelChange.addEventListener('click', function () {
// 让修改 页面 隐藏
oChange.style.display = 'none';
})
</script>
针对第一个问题,出现"undefined"的问题通常是因为访问了一个不存在的变量或者属性的值,也可能是函数没有返回任何值。解决该问题的方法是要进行变量或属性的存在性检查,避免访问不存在的变量或属性。可以使用if语句或者三元运算符来进行判断,同时也可以使用默认参数来避免出现undefined的情况。
针对第二个问题,要将表格居中显示,可以通过CSS样式来实现。具体来说,可以使用margin属性来设置水平和垂直居中,也可以使用flex布局来实现居中显示。下面是两种具体的实现方式:
1.使用margin实现表格居中显示
table {
margin: auto;
}
2.使用flex布局实现表格居中显示
.container {
display: flex;
justify-content: center;
align-items: center;
}
table {
width: 80%;
}
以上代码中,将table标签包裹在一个容器中,容器设置为flex布局,justify-content和align-items属性都设置为center,实现了水平和垂直居中。同时设置table的宽度为80%,避免宽度太大而超出屏幕。
table {
margin: auto;
}