搜尋

首頁  >  問答  >  主體

javascript - 關於prototype的問題?

我用原型鏈來寫一個省市區連動的方法,我將變數放進初始的函數中,以便我用原型鏈拓展時使用。初始化時沒問題的,但在我用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();
PHP中文网PHP中文网2751 天前536

全部回覆(2)我來回復

  • ringa_lee

    ringa_lee2017-05-19 10:26:13

    回呼函數需要正確的 this 環境。

    把這行

    this.selectCity.onchange = this.changeCity;

    改成

    this.selectCity.onchange = this.changeCity.bind(this);

    回覆
    0
  • 滿天的星座

    滿天的星座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是指你的實例物件),從而達到你所需要的效果。

    回覆
    0
  • 取消回覆