我们的一个项目本来是面对直接客户的,所以一开始并没有打开做sdk。后来客户多了,有就客户提出要在我们的项目上做二次开发,而且时间也比较紧,重新开发一套sdk肯定是来不及了的,只能用现有的项目做成iframe的形式提供给客户,但iframe交互是个大问题,没办法直接进行交互,只能用postMessage给iframe发消息,iframe再通过事件返回交互产生的结果。如果就这样交给客户肯定是不好交差的,那就做个简易版本的sdk吧。
选用的打包工具是rollup,语言是typescript,直接上代码吧。
export default class {
private listenerList: any = {
//插件事件数组
onload: function (e: any) {},
clickXX: function (e: any) {}
};
private event: any = {
dispatch: function (eventKey: string) {
var args = Array.prototype.slice.call(arguments, 1);
this.listenerList[eventKey].apply(this, args);
return this;
},
listener: function (eventKey: string, callback: any) {
if (typeof eventKey === "string" && typeof callback === "function") {
this.listenerList[eventKey] = callback;
}
return this;
},
};
private options: any | {};
public on: any;
private emit: any;
private iframe: HTMLIFrameElement | any;
constructor(options: any | {}) {
this.options = {
...options,
};
let scriptTags = document.getElementsByTagName("script");
let src = "";
for (let i = 0; i < scriptTags.length; i++) {
if (scriptTags[i].src.indexOf("xxx.min.js") >= 0) {
src = scriptTags[i].src;
break;
}
}
let { key } = this.getURLQuery(src);
if (!key) {
console.log("Key不能为空!");
return;
}
this.on = this.event.listener;
this.emit = this.event.dispatch;
this.iframe = document.createElement("iframe");
this.init(key);
this.addEvent();
}
private init(key: string): void {
let tid: number = Date.now();
let sdk_domain_path: string = "https://www.xxxx.com/";
this.iframe.src = sdk_domain_path + key + "?tid=" + tid;
this.iframe.id = "map-iframe";
this.iframe.style.border = "none";
this.iframe.style.width = "100%";
this.iframe.style.height = "100%";
if (this.options.container) {
if (typeof this.options.container == "string") {
document.querySelector(this.options.container).appendChild(this.iframe);
} else {
this.options.container.appendChild(this.iframe);
}
} else {
document.body.appendChild(this.iframe);
}
this.iframe.onload = () => {
if (this.iframeLoad && this.onLoad) {
this.emit("onload", {});
}
};
}
private addEvent(): void {
window.addEventListener(
"message",
(e) => {
const data = e.data;
if (data && typeof data === "string") {
let messageData = JSON.parse(data);
if (messageData.type === "clickXX") {
// 单击某个组件事件
this.emit("clickXX", {
event: messageData.evt,
});
}
}
},
false
);
}
private getURLQuery(url: string = location.href): any {
const obj = {};
const reg = /([^?&=]+)=([^?&=]+)/g;
let res = reg.exec(url);
while (res) {
obj[res[1]] = res[2];
res = reg.exec(url);
}
return obj;
}
//某个方法
public FunXXX(): void {
let messageData = {
type: "funXXX",
};
this.iframe.contentWindow.postMessage(JSON.stringify(messageData), "*");
}
}
将上面的代码用rollup打包工具打包好发给客户就可以了。