Open zhangxinxu opened 4 years ago
const select = document.querySelector('select')
// 1
console.log(select.form)
// 2
console.log(select.selectedIndex)
// 3
console.log(select[2].value)
// 4
select.onchange = function(v) {
console.log(v)
}
select = new Proxy(select, {
get (target, props) {
return target[props]
},
set (target, props, value) {
target.value = value
if (props === "value") {
var event = document.createEvent('Event');
event.initEvent('change', true, false);
target.dispatchEvent(event);
}
return value
}
});
select.value = 'xxx'
// 1
select.form;
// 2
select.selectedIndex;
// 3
select[2].value;
// 4
const props = Object.getOwnPropertyDescriptor(HTMLSelectElement.prototype, 'value');
Object.defineProperty(HTMLSelectElement.prototype, 'value', {
...props,
set(v) {
props.set.call(this, v);
this.dispatchEvent(new InputEvent('change'));
}
})
// 第1题
select.form
// 第2题
select.selectedIndex
// 第3题
select[2].value
// 第4题
Object.defineProperty(select, 'value', {
set (val) {
let options = Array.from(select.options)
let curSelect = select.selectedIndex
for (let i = 0; i < options.length; i++) {
if (options[i].value === val) {
if (i !== curSelect) {// 判断是否与当前选中值有所不同
select.selectedIndex = i
select.dispatchEvent(new Event('change'))
}
break
}
}
},
get () {
return select.selectedOptions[0].value // 避免直接访问select.value
}
})
{
let select = document.querySelector('select')
console.log(select.form)
console.log(select.selectedIndex)
console.log(select[2].value)
select = new Proxy(select, {
get (target, key) {
return target[key]
},
set (target, key, value) {
target.value = value
target.dispatchEvent(new InputEvent('change'))
return value
}
})
}
<form id="form1" action="">
<div>
<select name="hi" id="select1">
<option value="apple">apple</option>
<option value="bar">bar</option>
<option value="car" selected>car</option>
<option value="dar">dar</option>
</select>
</div>
</form>
<fieldset form="form1">
<div>
<select name="hi2" id="select2">
<option value="apple2">apple2</option>
<option value="bar2">bar2</option>
<option value="car2">car2</option>
</select>
</div>
</fieldset>
(function () {
const objSel1 = document.getElementById('select1');
const objSel2 = document.getElementById('select2');
// 第一题
// 找到控件对应的 form 元素
const getFormByControl = function (objControl) {
// 能找到 form 对象
if (objControl.form) {
return objControl.form;
}
// control 元素不在form 元素内部
const objForm = null;
let objParent = objControl.parentElement;
while (objParent && objParent.tagName.toLowerCase() !== 'body') {
const strParentTagName = objParent.tagName.toLowerCase();
if (strParentTagName === 'fieldset') {
return objParent.form;
}
objParent = objParent.parentElement;
}
return objForm;
};
console.log(getFormByControl(objSel1));
console.log(getFormByControl(objSel2));
// 第二题
console.log(objSel1.selectedIndex);
console.log(objSel2.selectedIndex);
// 第三题
console.dir(objSel1[2].value);
console.dir(objSel2[2].value);
// 第四题
objSel1.addEventListener('change', function () {
console.log('change', this.value);
});
Object.defineProperty(objSel1, 'value', {
get: function () {
return this[this.selectedIndex] ? this[this.selectedIndex].value : '';
},
set: function (val) {
// 选中找到的索引值
const getSelectedIndex = function (objSelect, val) {
for (let i = 0, len = objSelect.length; i < len; i++) {
if (objSelect[i].value === val) {
return i;
}
}
// 没找到返回-1;
return -1;
}
this.selectedIndex = getSelectedIndex(this, val);
// 触发 onchange
this.dispatchEvent(new Event('change'));
}
});
objSel1.value = 'bar';
})();
// 1
select.form;
// 2
select.selectedIndex;
// 3
select.options[2].value
// const selector = document.getElementById('#selector')
// 1 获取 selector 的 form 父元素
selector.form
// 2 获取 selector 选中的 selectedIndex
selector.selectedIndex
// 3 获取 selector 第 3 个 options 元素的 value 属性值
selector.options[2].value
// 4 设置 value ,触发 onchange 事件
Object.defineProperty(selector, 'value', {
get: function () {
// selectedIndex 为正说明选择有结果,否则就无结果
return this.selectedIndex >= 0 ? this.options[this.selectedIndex].value : ''
},
set: function (value) {
let options = Array.from(selector.options)
let optionsValue = options.map(option => option.value)
// 找到目标 index, 更改 index 为目标 index
this.selectedIndex = optionsValue.indexOf(value)
// 触发事件
let event = new InputEvent('change')
this.dispatchEvent(event)
},
})
selector.onchange = (e) => {
console.log(e.target.value)
}
selector.value = 'b'
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>DOM49</title>
</head>
<body>
<form action="GET">
<select name="selector" id="selector">
<option value="a">a</option>
<option value="b">b</option>
<option value="c">c</option>
<option value="d">d</option>
<option value="e">e</option>
</select>
</form>
</body>
</html>
var select=document.getElementById('sel')
// 1
console.log(select.form)
//2
console.log(select.selectedIndex)
//3
console.log(select.options[2].value)
//4
Object.defineProperty(select, 'value', {
set (val) {
for (let i = 0; i < select.options.length; i++) {
if (select.options[i].value === val && i !== select.selectedIndex) {
select.selectedIndex = i
select.dispatchEvent(new Event('change'))
break
}
}
},
get () {
return select.selectedIndex ? select.selectedIndex.value : '';
}
})
var selectElm = document.querySelector('select');
selectElm.form
selectElm.selectedIndex
// 或者
selectElm.options.selectedIndex
selectElm.options[2].value
测试要点:
Object.defineProperty(HTMLSelectElement.prototype, 'value', {
set(newVal) {
const curOptIndex = [...this.options].findIndex(opt =>
opt.value == newVal // 使用弱类型判断,以涵盖 1 == '1' 类似情况
);
if (curOptIndex !== this.selectedIndex) { // 非上次选中项
this.selectedIndex = curOptIndex;
this.dispatchEvent(new Event('change')); // 派发事件
}
}
});
// 兼容 IE9+
Object.defineProperty(HTMLSelectElement.prototype, 'value', {
set: function(newVal) {
var curOptIndex = -1;
[].slice.call(this.options).some(function(opt, idx) {
return opt.value == newVal && ~(curOptIndex = idx)
});
if (curOptIndex !== this.selectedIndex) {
var evt;
if (typeof Event === 'function') {
evt = new Event('change')
} else {
evt = document.createEvent('Event');
evt.initEvent('change', true, true);
}
this.selectedIndex = curOptIndex;
this.dispatchEvent(evt);
}
}
});
已知页面上有一个
<select>
下拉框元素,假设该元素的DOM对象是select
,请问:<form>
元素;<options>
元素的value
属性值,代码该如何书写?select.value = 'xxx'
并不能让<select>
下拉框元素触发change
事件,实现使用value
属性赋值的时候,下拉框元素change
事件可以被触发。本题考点想要满分不容易。大家提交回答的时候,注意缩进距离,起始位置从左边缘开始;另外,github自带代码高亮,所以请使用下面示意的格式。
其他 本期小测没有直播,也没有打分,但是会反馈要点。