请教 ES6变量的结构赋值中,自定义弹框的例子2
// 初始化一个弹出框
// 创建DOM元素
// 把弹出框插入DOM元素,再把DOM元素插入到页面中
// 显示DOM元素
(function(window, document) {
let Msg = function(options) {
this._init(options);
};
Msg.prototype._init = function({ content = '', confirm = null,
cancel = null, userHtml = false, contentStyle = { }, contentFontSize = '1.5em'}) {
this.content = content;
this.confirm = confirm;
this.cancel = cancel;
this.userHtml = userHtml;
this.contentStyle = contentStyle;
this.contentFontSize = contentFontSize;
this._createElement();
this._show([this._el, this._overlay]);
this._bind([this._el, this._overlay]);
};
Msg.prototype._bind = function([el, overlay]){
// 这个方法在_bind方法内部使用,所以写在内部。??事件冒泡机制 11111111
const hideMsg = function(){
el.style.transform = 'translate(-50%, -50%) scale(0, 0)';
overlay.style.opacity = 0;
setTimeout(() => {
document.body.removeChild(el);
document.body.removeChild(overlay);
}, 300);
// 这个定时器跟下面confirm事件冲突了,因为事件执行完后el这个DOM元素已经没有了,confirm冒泡到el,取消事件就没办法进行了,只要在confirm事件里加阻止事件冒泡event.stopPropagation();就行了
};
const _this = this;
// console.log(this) 这个this指向Msg对象
const cancel = function(e){
// console.log(this) 这个this指向this._el = wrap这个DOM元素,实际上指向算了吧或×这两个按钮,因为事件冒泡指向了wrap,所以要用const _this = this保留this;
_this.cancel && _this.cancel.call(_this, e); //33333
hideMsg();
}
const confirm = function(e){
console.log(this)
_this.confirm && _this.confirm.call(_this, e);
hideMsg();
alert('注册成功');
event.stopPropagation();
}
overlay.addEventListener('click', cancel)
// 事件冒泡机制,父元素监听下面所有子元素的点击事件
el.addEventListener('click', cancel);
// confirm确认事件比较特殊,加个冒泡。
el.querySelector('.msg-footer-confirm-button').addEventListener('click', confirm);
}
Msg.prototype._createElement = function(){
let wrap = document.createElement("div");
wrap.className = 'msg__wrap';
wrap.innerHTML = `<div class="msg-header">
<span>确认删除</span>
<span class="msg-header-close-button">×</span>
</div>
<div class="msg-body">
<div class="msg-body-icon">
<div class="msg-body-icon-wrong"></div>
</div>
<div class="msg-body-content"></div>
</div>
<div class="msg-footer">
<button class="msg-footer-btn msg-footer-cancel-button">算了吧</button>
<button class="msg-footer-btn msg-footer-confirm-button">好的</button>
</div>`;
// 在<div class="msg-body-content"></div>这里插入文本或者DOM元素
let contentDom = wrap.querySelector('.msg-body .msg-body-content');
const contentStyle = {
fontSize: this.contentFontSize,
...this.contentStyle
}
for(let i in contentStyle){
if(contentStyle.hasOwnProperty(i)){
contentDom.style[i] = contentStyle[i];
}
}
if(this.userHtml){
contentDom.innerHTML = this.content;
}else{
contentDom.innerText = this.content;
}
let overlay = document.createElement('div');
overlay.className = 'msg__overlay';
this._el = wrap;
this._overlay = overlay;
// console.log(typeof this._el)
}
Msg.prototype._show = function([el, overlay]){
document.body.appendChild(el);
document.body.appendChild(overlay);
// 异步操作,最后一步scale放大。
setTimeout(() => {
el.style.transform = 'translate(-50%, -50%) scale(1, 1)';
overlay.style.opacity = 1;
}, 0);
}
window.$Msg = Msg;
})(window, document);看看我注释的地方对不对,还有检查一下代码。
// 1、hideMsg这个方法只能在_bind方法内部使用,所以写在内部??为什么不挂到Msg对象上?
// 2、什么时候用let ,什么时候用const,我知道let是变量,const是常量,但是const定义引用类型时,自身也能改变,我的感觉所有的常量都能使用let定义,能举几个常用的例子对比一下吗?
3、const _this = this; _this.cancel && _this.cancel.call(_this, e); 这一步的意义到底在哪里?我利用了事件冒泡机制监听wrap下的所有点击事件,confirm事件我阻止了事件冒泡,所以我是能知道this的最终指向的。去掉这一步,然后我在事件内外打印了this,外面的指向Msg对象,里面的指向3个按钮,好像也没有影响。
正在回答 回答被采纳积分+1
一看就是个特别爱动脑、爱思考的同学,学习编程这一点也是非常重要的,老师也希望能够跟你有更多的技术方面的探讨,关于同学的疑问,解答如下:

关于“ _this.cancel && _this.cancel.call(_this, e);”同学的理解也是正确的,因为前面const _this = this;之后,_this改变了指向,所以_this.cancel && _this.cancel.call(_this, e);的整体指向也改变了,但是我们做一个测试,如下:
html代码如下:



也就是说 _this.cancel && _this.cancel.call(_this, e);整句代码的意思是判断是否有cancel,如果有,就显示“取消了,”,如果没有就不显示,不写_this.cancel && _this.cancel.call(_this, e);这句代码,的确不影响弹框的取消功能,但是,却无法显示“取消了,”这几个提示文字了。就好比确定事件里面不写_this.confirm && _this.confirm.call(_this, e);这句代码,点击弹窗中的“好的”按钮,不会显示
是一个道理。
希望可以帮到你!
1、“hideMsg这个方法只能在_bind方法内部使用,所以写在内部”这么理解是可以的,关于“为什么不挂到Msg对象上?”解释如下:
$Msg是自定义的对象,new的实例化对象的语法,在js中为$Msg赋值为Msg,而Msg的原型上面定义了很多方法,并且方法里面也有很多属性,所以实例化$Msg就相当于实例化Msg,这样实例化的时候可以调用这些属性和方法。
2、大部分情况下const的使用率比let高,由于const一旦定义就不可改变,所以一般为了代码的性能和稳定性,建议使用const,除非一定要改变变量的值,再使用let
3、关于 const _this = this,当前代码中的this是指向实例,相当于父级,指向指不到子级中,所以需要一个变量 _this存储this得指向,_this.cancel && _this.cancel.call(_this,e);这句代码的作用是获取用户是不是点击确认按钮了,然后执行一下操作
希望可以帮到你,如果还有哪里不懂,可以继续提问
祝学习愉快~
同学你好,1、是的哦,因为其他的地方不使用,可以不挂载到Msg对象上。
2、let声明的是变量,也就是能够改变的量。
使用const声明的是常量,保存的是内存地址,可以给对象或数组添加属性或元素,但是不能重新复写,也就是重新赋值。
如果分不清楚什么时候用let,什么时候用const,都使用let定义也没有问题。
3、&&是逻辑运算符,是逻辑与;
这句话的意思,是_this.cancel若是存在的话为真,否则为假。&&逻辑与运算符,若第一个为假的话,就直接返回了,为真的话,会接着执行第二个,就执行了_this.cancel.call(_this, e);
(1)外面的this指向的是Msg这个对象,但是在cancel这个函数中,this是不能使用Msg对象的,所以使用一个变量(_this)来保存这个this(指向Msg对象的this),

(2)cancel是_init的这个cancel哦,使用this的话,是可以挂载到实例化对象上的。

所以应该使用指向实例化对象的this去访问它。
希望能帮助到你,祝学习愉快!
- 参与学习 人
- 提交作业 239 份
- 解答问题 10739 个
本阶段带你深入前端开发的肌理,通过ES6基础知识和前端主流高级框架的学习,助你快速构建企业级移动webAPP应用,进入职场的终极battle
了解课程
恭喜解决一个难题,获得1积分~
来为老师/同学的回答评分吧
0 星