我的项目页面是复合结构的,使用layui-iframe版的框架,最外面的页面保持不变,然后里面可以打开多个tap。
然后在子iframe里面,调用top.layer.open可以打开一个弹窗,但是当我直接用新的页面打开iframe,调用top.layer.open却不生效。实际上对实际的项目来说影响不大,因为用户都是打开主页,然后用tab的形式打开iframe,不会有这个问题,但是却让我这个强迫症十分不爽。这个问题存在好久了,然后今天终于忍不住死磕了三个小时终于找到原因了,甚至影响了我的任务,不过终于解决这个问题后气顺多了,哈哈。
直接上代码,顺便分享自己找源码的过程。这里不得不吐槽,js框架的代码全是这种单个字母的变量,十分难读,只能祭出debug大发。
在console页面,先选择环境,因为这里直接用页面打开iframe页面,所以这个top就是我的环境,如果有多个iframe就会有多个环境,例如
然后在console页面输入layer.open
直接点击这个方法就能调到source里面。
如果是这种压缩版没有回车排版的min.js文件可以点击source里面的格式化图标
layer.js里面,layer.open是在这里定义的。
o.run = function(t) {
i = t,
n = i(e),
l.html = i("html"),
r.open = function(e) {
var t = new s(e);
return t.index
}
}
s = function(e) {
var t = this;
t.index = ++r.index,
t.config = i.extend({}, t.config, o.config, e),
document.body ? t.creat() : setTimeout(function() {
t.creat()
}, 30)
};
使用debug大法找到s方法,然后可以看出关键是t.creat方法
把鼠标移到方法上点击,就可以移到指定位置
s.pt.creat = function() {
var e = this
, t = e.config
, a = e.index
, s = t.content
, f = "object" == typeof s
, c = i("body");
if (!t.id || !i("#" + t.id)[0]) {
switch ("string" == typeof t.area && (t.area = "auto" === t.area ? ["", ""] : [t.area, ""]),
t.shift && (t.anim = t.shift),
6 == r.ie && (t.fixed = !1),
t.type) {
case 0:
t.btn = "btn"in t ? t.btn : o.btn[0],
r.closeAll("dialog");
break;
case 2:
var s = t.content = f ? t.content : [t.content || "http://layer.layui.com", "auto"];
t.content = '';
break;
case 3:
delete t.title,
delete t.closeBtn,
t.icon === -1 && 0 === t.icon,
r.closeAll("loading");
break;
case 4:
f || (t.content = [t.content, "body"]),
t.follow = t.content[1],
t.content = t.content[0] + '',
delete t.title,
t.tips = "object" == typeof t.tips ? t.tips : [t.tips, !0],
t.tipsMore || r.closeAll("tips")
}
if (e.vessel(f, function(n, r, u) {
c.append(n[0]),
f ? function() {
2 == t.type || 4 == t.type ? function() {
i("body").append(n[1])
}() : function() {
s.parents("." + l[0])[0] || (s.data("display", s.css("display")).show().addClass("layui-layer-wrap").wrap(n[1]),
i("#" + l[0] + a).find("." + l[5]).before(r))
}()
}() : c.append(n[1]),
i(".layui-layer-move")[0] || c.append(o.moveElem = u),
e.layero = i("#" + l[0] + a),
t.scrollbar || l.html.css("overflow", "hidden").attr("layer-full", a)
}).auto(a),
i("#layui-layer-shade" + e.index).css({
"background-color": t.shade[1] || "#000",
opacity: t.shade[0] || t.shade
}),
2 == t.type && 6 == r.ie && e.layero.find("iframe").attr("src", s[0]),
4 == t.type ? e.tips() : e.offset(),
t.fixed && n.on("resize", function() {
e.offset(),
(/^\d+%$/.test(t.area[0]) || /^\d+%$/.test(t.area[1])) && e.auto(a),
4 == t.type && e.tips()
}),
t.time <= 0 || setTimeout(function() {
r.close(e.index)
}, t.time),
e.move().callback(),
l.anim[t.anim]) {
var u = "layer-anim " + l.anim[t.anim];
e.layero.addClass(u).one("webkitAnimationEnd mozAnimationEnd MSAnimationEnd oanimationend animationend", function() {
i(this).removeClass(u)
})
}
t.isOutAnim && e.layero.data("isOutAnim", !0)
}
}
然后重点是这个if判断,如果该页面有这个id的元素,那么就不会生成弹窗,而我之前设置layer.open的弹窗id是和页面上的元素是重复的。那么为什么在主页面时就不会这样呢,因为我用的是top.layer.open,而在主页面使用时top指的就是主页面,而主页面并没有这个id的元素,所以可以弹窗了。
因此只要要让layer.open(option)里面的id不要和页面元素的id重复就行了,统一加上layer_前缀,避免重复就解决这个问题了