Skip to content
本文总阅读量

状态模式

HTML

HTML
<html>
<boty><boty>
</html>

JS

JS
// 模拟不指定下个状态
window.external.upload  =  function  (state)  {
    console.log('state-->>>',  state);  // 可能为 sign、uploading、done、error
};


var  plugin  =  (function  ()  {
    var  plugin  =  document.createElement('embed');
    plugin.style.display  =  'none';
    plugin.type  =  'application/txftn-webkit';


    plugin.sign  =  function  ()  {
        console.log('开始文件扫描');
    }
    
    plugin.pause  =  function  ()  {
        console.log('暂停文件上传');
    };


    plugin.uploading  =  function  ()  {
        console.log('开始文件上传');
    };


    plugin.del  =  function  ()  {
        console.log('删除文件上传');
    }


    document.body.appendChild(plugin);
    
    plugin.done  =  function  ()  {
        console.log('文件上传完成');
    }


    return  plugin;
})();




var  Upload  =  function  (fileName)  {
    this.plugin  =  plugin;
    this.fileName  =  fileName;
    this.button1  =  null;
    this.button2  =  null;
    
    this.signState  =  new  SignState(this);
    this.uploadingState  =  new  UploadingState(this);
    this.pauseState  =  new  PauseState(this);
    this.doneState  =  new  DoneState(this);
    this.errorState  =  new  ErrorState(this);
    this.currState  =  this.signState;  // 设置当前状态
}


Upload.prototype.init  =  function  ()  {
    var  that  =  this;
    this.dom  =  document.createElement('div');
    this.dom.innerHTML  = '文件名称:'  +  this.fileName  +  '扫描中 删除 ';
    document.body.appendChild(this.dom);
    this.button1  =  this.dom.querySelector('[data-action="button1"]'); 
    this.button2  =  this.dom.querySelector('[data-action="button2"]');
    this.bindEvent();
};


// 按钮点击事件
Upload.prototype.bindEvent  =  function  ()  {
    var  self  =  this;
    this.button1.onclick  =  function  ()  {
        self.currState.clickHandler1();
    }
    this.button2.onclick  =  function  ()  {
        self.currState.clickHandler2();
    }
};


Upload.prototype.sign  =  function  ()  {
    this.plugin.sign();
    this.currState  =  this.signState;
};


Upload.prototype.uploading  =  function  ()  {
    this.button1.innerHTML  =  '正在上传,点击暂停';
    this.plugin.uploading();
    this.currState  =  this.uploadingState;
};


Upload.prototype.pause  =  function  ()  {
    this.button1.innerHTML  =  '已暂停,点击继续上传';
    this.plugin.pause();
    this.currState  =  this.pauseState;
};


Upload.prototype.done  =  function  ()  {
    this.button1.innerHTML  =  '上传完成';
    this.plugin.done();
    this.currState  =  this.doneState;
};


  
Upload.prototype.error  =  function  ()  {
    this.button1.innerHTML  =  '上传失败';
    this.currState  =  this.errorState;
};


Upload.prototype.del  =  function  ()  {
    this.plugin.del();
    this.dom.parentNode.removeChild(this.dom);
};


var  StateFactory  =  (function  (param)  {
    var  State  =  function  ()  {  }
    State.prototype.clickHandler1  =  function  ()  {
        throw  new  Error('子类必须重写父类的 clickHandler1 方法');
    }


    State.prototype.clickHandler2  =  function  ()  {
        throw  new  Error('子类必须重写父类的 clickHandler2 方法');
    }


    return  function  (param)  {
        var  F  =  function  (uploadObj)  {  // 实例化 区分uploadObj
            this.uploadObj  =  uploadObj
        }
        F.prototype  =  function  ()  {}  
        for  (var  i  in  param)  {
            F.prototype[i]  =  param[i];
        }
        return  F
    }
})()


// 避免js没有抽象类问题重写方法
var  SignState  =  StateFactory({
    clickHandler1:  function  ()  {
            console.log('扫描中,点击无效...');
    },
    clickHandler2:  function  ()  {
        console.log('文件正在上传中,不能删除');
    }
})


var  UploadingState  =  StateFactory({
    clickHandler1:  function  ()  {
        this.uploadObj.pause();
    },
    clickHandler2:  function  ()  {
        console.log('文件正在上传中,不能删除');
    }
});


  
var  PauseState  =  StateFactory({
    clickHandler1:  function  ()  {
        this.uploadObj.uploading();
    },
    clickHandler2:  function  ()  {
        this.uploadObj.del();
    }
});


var  DoneState  =  StateFactory({
    clickHandler1:  function  ()  {
        console.log('文件已完成上传, 点击无效');
    },
    clickHandler2:  function  ()  {
        this.uploadObj.del();
    }
});


var  ErrorState  =  StateFactory({
    clickHandler1:  function  ()  {
        console.log('文件上传失败, 点击无效');
    },
    clickHandler2:  function  ()  {
        this.uploadObj.del();
    }
});


var  uploadObj  =  new  Upload('JavaScript 设计模式与开发实践');
uploadObj.init()
window.external.upload  =  function  (state)  {
    uploadObj[state]();
};


window.external.upload('sign');


// 延迟
setTimeout(function  ()  {
    window.external.upload('uploading');
},  1000);


setTimeout(function  ()  {
    window.external.upload('done');
},  5000);

输出