我用原型鏈來寫一個省市區連動的方法,我將變數放進初始的函數中,以便我用原型鏈拓展時使用。初始化時沒問題的,但在我用onchange選擇省或市時就出問題了,selectProvince和selectCity的屬性options找不到,我在往上查找了一下,發現selectProvince和selectCity在用onchange時根本沒有檢測到,我明明在AddressInit裡面初始化了,但卻沒偵測到,求解?
程式碼:
//這是一小段的json
var provinceList = [{
name: '北京',
cityList: [{
name: '市辖区',
areaList: ['东城区', '西城区', '崇文区', '宣武区', '朝阳区', '丰台区', '石景山区', '海淀区', '门头沟区', '房山区', '通州区', '顺义区', '昌平区', '大兴区', '怀柔区', '平谷区']
}, {
name: '县',
areaList: ['密云县', '延庆县']
}]
}];
//這是html
<select class="select-input" name="selectProvince" id="selectProvince"></select>
<select class="select-input" name="selectCity" id="selectCity"></select>
<select class="select-input" name="selectArea" id="selectArea"></select>
//這是js
var AddressInit = function(selectProvince, selectCity, selectArea, defaultProvince, defaultCity, defaultArea){
this.selectProvince = document.getElementById(selectProvince);
this.selectCity = document.getElementById(selectCity);
this.selectArea = document.getElementById(selectArea);
this.defaultProvince = defaultProvince || '';
this.defaultCity = defaultCity || '';
this.defaultArea = defaultArea || '';
}
AddressInit.prototype = {
constructor: AddressInit,
//初始化
init: function(){
for (var i = 0; i < provinceList.length; i++) {
this.selectAddOption(this.selectProvince, provinceList[i].name, provinceList[i]);
}
this.selected(this.selectProvince, this.defaultProvince);
this.changeProvince();
this.selectProvince.onchange = this.changeProvince;
},
//判断是否有选中的值
selected: function(select,str){
for(var i = 0; i < select.options.length; i++) {
if (select.options[i].value == str) {
select.selectedIndex = i;
return;
}
}
},
//添加option
selectAddOption: function(select, str, obj) {
var option = document.createElement("option");
select.options.add(option);
option.innerText = str;
option.value = str;
option.obj = obj;
},
//改变省
changeProvince: function(){
console.log(selectCity);
this.selectCity.options.length = 0;
this.selectCity.onchange = null;
if (this.selectProvince.selectedIndex == -1) return;
var item = this.selectProvince.options[this.selectProvince.selectedIndex].obj;
for (var i = 0; i < item.cityList.length; i++) {
this.selectAddOption(this.selectCity, item.cityList[i].name, item.cityList[i]);
}
this.selected(this.selectCity, this.defaultCity);
this.changeCity();
this.selectCity.onchange = this.changeCity;
},
//改变市
changeCity: function(){
this.selectArea.options.length = 0;
if (this.selectCity.selectedIndex == -1) return;
var item = this.selectCity.options[this.selectCity.selectedIndex].obj;
for (var i = 0; i < item.areaList.length; i++) {
this.selectAddOption(this.selectArea, item.areaList[i], null);
}
this.selected(this.selectArea, this.defaultArea);
}
}
var ccc = new AddressInit('selectProvince', 'selectCity', 'selectArea');
ccc.init();
ringa_lee2017-05-19 10:26:13
回呼函數需要正確的 this 環境。
把這行
this.selectCity.onchange = this.changeCity;
改成
this.selectCity.onchange = this.changeCity.bind(this);
滿天的星座2017-05-19 10:26:13
如樓上所言,是this指向出了問題:
this.selectProvince.onchange = this.changeProvince;
你的意思是指select的change事件的處理函數為 this.changeProvince
, 即對其的一個引用。
實際也就是如下:
document.getElementById(selectProvince).onchange = function(){
console.log(selectCity);
this.selectCity.options.length = 0; // 触发时报错this.selectCity为undefined 因为this是dom元素
this.selectCity.onchange = null; // 触发时报错this.selectCity为undefined
if (this.selectProvince.selectedIndex == -1) return; // 触发时报错this.selectProvince为undefined 下面的this基本都有问题 事件处理函数中this为dom元素,而不是你的实例对象。
var item = this.selectProvince.options[this.selectProvince.selectedIndex].obj;
for (var i = 0; i < item.cityList.length; i++) {
this.selectAddOption(this.selectCity, item.cityList[i].name, item.cityList[i]);
}
this.selected(this.selectCity, this.defaultCity);
this.changeCity();
this.selectCity.onchange = this.changeCity;
}
看得出問題了嗎?事件處理函數中的this
指的是dom对象,即document.getElementById(selectProvince)
它上面當然沒有你需要的東西了。
可以如樓上所言的換為this.selectCity.onchange = this.changeCity.bind(this)
this.selectCity.onchange = this.changeCity;
这样写 只是表示selectCity.onchange 也是 this.changeCity
这个函数,在js中,this的指向是实际运行时才决定,在onchange事件触发时,this.changeCity
函数内的this
为dom元素,所以就出错了。bind
方法可以替换函数内的this
指向,產生一個新的函數。
即this.changeCity.bind(this)
这句在运行时,已经将this.changeCity
函数内的this
替换为了当前的this
(這個this是指你的實例物件),從而達到你所需要的效果。