题解 | #选择组件#
选择组件
https://www.nowcoder.com/practice/ed0bd346dc9c4184aacda183484a3a6f
// CheckGroup是一个选择组件类,支持单选和多选
// 选项参数格式:
// var options = [{text: '选项a', value: 'a'}, {text: '选项b', value: 'b'}, {text: '选项c', value: 'c'}, {text: '选项d', value: 'd'}];
// 给定的options中, text和value属性的值均为非空字符串
// 实例化单选组件:
// var item = new CheckGroup(document.getElementById('jsCheckGroup'), options);
// item.val(['a']);
// 实例化多选组件:
// var item = new CheckGroup(document.getElementById('jsCheckGroup'), options, true);
// item.val(['a']);
// 选中的dom元素className = 'item selected'
// 单选组件className = 'checkgroup radius'
// 单选时, 如果点击的dom元素没有selected类, 则添加selected类, 并移除其他选项元素的selected类;如果有selected类,则移除selected类
// 点击多选选项,如果未选中当前选项则添加selected类,否则移除selected类
function CheckGroup(renderTo, options, isMultiple) {
var that = this; // CheckGroup实例
that.renderTo = renderTo;
that.options = options;
that.isMultiple = !!isMultiple; // 针对无参数传入的情况,!!undefined == false
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.isMultiple ? '' : 'radius'}">
${that.options.reduce((divhtml, cur) => divhtml + `<div data-val="${cur.value}" class="item">${cur.text}</div>`, '')}
</div>`
that.renderTo.innerHTML = sHtml;
// 请补全代码,获取checkgroup的dom元素引用
that.el = this.renderTo.querySelector('.checkgroup');
}
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 {
// 请补全代码
item.parentNode.querySelector('.selected') && item.parentNode.querySelector('.selected').classList.remove('selected')
item.classList.add('selected')
}
}
function fIsSelected(item) {
// 请补全代码,判断item是否选中
return item.classList.contains('selected');
}
// val方法的参数和返回值均为数组(单选时数组长度不超过)
function fVal(values) {
var that = this; // 实例
if (arguments.length === 0) {
// 请补全代码,获取高亮的选项元素
var items = jsCheckGroup.querySelectorAll('.selected');
// 请补全代码,获取高亮的选项元素的data-val
var result = [].map.call(items, item => item.dataset.val)
return result;
}
!that.isMultiple && values.length > 1 && (values.length = 1); // 单选组件,只能选一个
// 请补全代码,获取所有的选项元素
var items = jsCheckGroup.querySelectorAll('.item');
// 请补全代码,在指定元素上加上高亮的class
[].forEach.call(items, item => {
if (values.includes(item.dataset.val)) {
that.toggleEl(item)
}
})
}
