// 描述
// CheckGroup是一个选择组件类,支持单选和多选
// 选项参数格式、调用方式以及效果如下
// 选项参数格式:
// var options = [{ text: '选项a', value: 'a' }, { text: '选项b', value: 'b' }, { text: '选项c', value: 'c' }, { text: '选项d', value: 'd' }];
// 实例化单选组件:
// var item = new CheckGroup(document.getElementById('jsCheckGroup'), options);
// item.val(['a']);
// 实例化多选组件:
// var item = new CheckGroup(document.getElementById('jsCheckGroup'), options, true);
// item.val(['a']);
// 具体功能和需求如下:
// 1、单选组件请在 div.checkgroup 元素加上class radius
// 2、选中时,请在对应选项dom元素加上class selected
// 3、点击单选选项,如果未选中当前选项则选中当前选项并取消其他选项,否则取消当前选项
// 4、点击多选选项,如果未选中当前选项则选中当前选项,否则取消当前选项
// 5、给定的options中, text和value属性的值均为非空字符串
// 6、val方法的参数和返回值均为数组(单选时数组长度不超过)
// 7、请阅读代码,并根据注释完成对应代码(方法initHtml、toggleEl、isSelected、val)
// 8、请不要手动修改html和css
// 9、不要使用第三方插件
1.自己的练习
<style>
.checkgroup .item {
height: 42px;
line-height: 42px;
padding: 0 10px;
margin: 10px 0;
border: 1px solid #c7c7c7;
border-radius: 6px;
}
.checkgroup.radius .item {
border-radius: 21px;
}
.checkgroup .item.selected {
border: 1px solid #08b292;
background: #08b292;
color: #ffffff;
}
</style>
<div id="jsCheckGroup">
<div class="checkgroup radius">
<div data-val="a" class="item selected">选项a</div>
<div data-val="b" class="item">选项b</div>
<div data-val="c" class="item">选项c</div>
<div data-val="d" class="item">选项d</div>
</div>
</div>
function CheckGroup(renderTo, options, isMultiple) {
var that = this;
that.renderTo = renderTo;
that.options = options;
that.isMultiple = !!isMultiple;
that.initHtml();
that.initEvent();
}
CheckGroup.prototype.initHtml = fInitHtml;
CheckGroup.prototype.initEvent = fInitEvent;
CheckGroup.prototype.toggleEl = fToggleEl;
CheckGroup.prototype.isSelected = fIsSelected;
CheckGroup.prototype.val = fVal;
function fInitHtml() {
var that = this
// 请补全代码,拼接html字符串
var sHtml = '';
for (var i = 0; i < that.options.length; i++) {
sHtml += `<div data-val="${that.options[i].value}" class="item">${that.options[i].text}</div>`
}
sHtml = '<div class="checkgroup">' + sHtml + '</div>'
that.renderTo.innerHTML = sHtml;
// 请补全代码,获取checkgroup的dom元素引用
that.el = document.querySelector('.checkgroup');
that.el.classList.add('radius')
}
function fInitEvent() {
var that = this;
that.el && that.el.addEventListener('click', function (event) {
var item = event.target;
item.classList.contains('item') && that.toggleEl(item);
});
}
function fToggleEl(item) {
// 根据当前是单选还是多选,以及当前元素是否选中,高亮/取消 指定的选项dom元素
var that = this;
if (that.isSelected(item)) {
// 请补全代码: 如果当前item已经被选择
item.classList.remove('selected')
} else if (that.isMultiple) {
// 请补全代码: 如果是多选
that.el.classList.remove('radius')
item.classList.add('selected')
} else {
// 请补全代码:如果当前item没有被选择,且为单选
for(var i = 0; i < that.el.children.length; i++) {
that.el.children[i].className = 'item'
}
item.classList.add('selected')
}
}
function fIsSelected(item) {
// 请补全代码,判断item是否选中
return item.classList.contains('selected')
}
function fVal(values) {
var that = this;
if (arguments.length === 0) {
// 请补全代码,获取高亮的选项元素
var items = document.querySelectorAll('.selected');
// 请补全代码,获取高亮的选项元素的data-val
var result = [];
for(var i = 0; i < items.length; i++) {
result.push(items[i].dataset.val)
}
return result;
}
!that.isMultiple && values.length > 1 && (values.length = 1);
// 请补全代码,获取所有的选项元素
var items = document.querySelectorAll('.item');
// 请补全代码,在指定元素上加上高亮的class
values.forEach(item => {
that.toggleEl(document.querySelector(`.item[data-val="${item}"]`))
})
}
2.题解
function CheckGroup(renderTo, options, isMultiple) {
var that = this;
that.renderTo = renderTo;
that.options = options;
that.isMultiple = !!isMultiple;
that.initHtml();
that.initEvent();
}
CheckGroup.prototype.initHtml = fInitHtml;
CheckGroup.prototype.initEvent = fInitEvent;
CheckGroup.prototype.toggleEl = fToggleEl;
CheckGroup.prototype.isSelected = fIsSelected;
CheckGroup.prototype.val = fVal;
function fInitHtml() {
var that = this;
// 请补全代码,拼接html字符串
var sHtml = `<div class="checkgroup">`;
that.options.forEach(item => {
sHtml += `<div data-val="${item.value}" class="item">${item.text}</div>`;
});
sHtml += "</div>";
that.renderTo.innerHTML = sHtml;
// 请补全代码,获取checkgroup的dom元素引用
that.el = document.querySelector(".checkgroup");
if (!that.isMultiple) {
that.el.classList.add("radius");
}
}
function fInitEvent() {
var that = this;
that.el && that.el.addEventListener("click", function (event) {
var item = event.target;
item.classList.contains("item") && that.toggleEl(item);
});
}
function fToggleEl(item) {
// 根据当前是单选还是多选,以及当前元素是否选中,高亮/取消���亮指定的选项dom元素
var that = this;
if (that.isSelected(item)) {
// 请补全代码
item.classList.remove("selected");
} else if (that.isMultiple) {
// 请补全代码
item.classList.add("selected");
} else {
// 请补全代码
let selected = document.querySelector(".item.selected")
selected && selected.classList.remove("selected");
item.classList.add("selected");
}
}
function fIsSelected(item) {
// 请补全代码,判断item是否选中
return item.classList.contains("selected");
}
function fVal(values) {
var that = this;
if (arguments.length === 0) {
// 请补全代码,获取高亮的选项元素
var items = document.querySelectorAll(".selected");
// 请补全代码,获取高亮的选项元素的data-val
return [].slice.call(items).map(function (item) {
return item.getAttribute('data-val');
});
//return [...items].reduce((c, v) => {
// return [...c, v.dataset["val"]];
//}, []);
}
!that.isMultiple && values.length > 1 && (values.length = 1);
// 请补全代码,获取所有的选项元素
let els = document.querySelectorAll(".item");
values.forEach(item => {
let el = document.querySelector(`.item[data-val="${item}"]`);
that.toggleEl(el);
});
// if(!that.isMutiple){
// document.querySelector('.item.selected').classList.remove('selected')
// }
//values.forEach(item=>{
// document.querySelector(`.item[data-val="${item}"]`).classList.toggle('selected')
// })
// 请补全代码,在指定元素上加上高亮的class
}