欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

JS實(shí)現(xiàn)兩個(gè)跨域頁面實(shí)現(xiàn)量子糾纏互動效果

 更新時(shí)間:2023年12月15日 09:11:29   作者:River_何  
這篇文章主要為大家詳細(xì)介紹了如何利用JavaScript實(shí)現(xiàn)兩個(gè)跨域頁面實(shí)現(xiàn)量子糾纏互動效果,文中的示例代碼講解詳細(xì),感興趣的小伙伴可以跟隨小編一起學(xué)習(xí)一下

本文約定:

A頁面:假設(shè)為a.com

B頁面:假設(shè)為b.com

一、同域頁面實(shí)現(xiàn)量子糾纏的一般方案

最近前端圈的量子糾纏交互動效爆火,相信大家都了解了其中的實(shí)現(xiàn)原理,這里我再簡單的介紹下,不了解的同學(xué)的可以學(xué)習(xí)一波。

原理就是,通過監(jiān)聽窗口的位置、大小等信息,然后實(shí)時(shí)地保存到localStorage中,另一個(gè)頁面通過監(jiān)聽strorage的改變,進(jìn)而動態(tài)地改變頁面上物體的位置和顯示效果。

示例代碼如下:

// 將當(dāng)前頁面的中心位置坐標(biāo)保存到localStorage中
const savePageInfo = () => {
    const centerX = window.innerWidth / 2 + window.screenLeft;
    const centerY = window.innerHeight / 2 + window.screenTop;
    const data = { centerX, centerY };
    window.localStorage.setItem(pageId,  JSON.stringify(data));
};

// localStorage被修改后的回調(diào)
const onStorage = (e) => {
    console.log("otherPageInfo", JSON.parse(e.newValue));
}

const onReady = () => {
    savePageInfo();
    window.addEventListener("resize", savePageInfo);
    window.addEventListener("storage", onStorage);
}

window.addEventListener("ready", onReady);

在這個(gè)案例中,由于兩個(gè)頁面是相同域下的,所以另外一個(gè)頁面可以通過監(jiān)聽strorage的改變,獲取到前一個(gè)頁面保存進(jìn)去的值,然后進(jìn)行交互,這里不得不佩服作者的奇思妙想。

那么問題來了,如果兩個(gè)頁面是跨域的,單獨(dú)打開的兩個(gè)頁面又如何進(jìn)行實(shí)時(shí)地通信呢?有同學(xué)會說用WebSocket,呃...,是可以實(shí)現(xiàn),但我們討論的是純前端的實(shí)現(xiàn),借助后端就沒啥意思了。

二、跨域頁面實(shí)現(xiàn)量子糾纏的終極方案

兩個(gè)跨域頁面想要通信就必須使用可以進(jìn)行跨域通信的API,大家肯定都想到了,對,使用window.postMessage,但是A頁面要給B頁面發(fā)送消息,那么postMessage的window對象就必須是B頁面的window對象,而A和B兩個(gè)頁面是在兩個(gè)單獨(dú)的瀏覽器窗口中分別打開的,A頁面如何獲取到B頁面的window對象呢?

直接說結(jié)論,終極方案就是,在A頁面中通過Iframe嵌入display為none的B頁面,A頁面監(jiān)聽窗口的位置、大小的改變,然后將窗口信息通過postMessage發(fā)送消息給B頁面,剛才說了要給B頁面發(fā)送消息就必須拿到B頁面的window對象,那么如何拿到呢,就是通過Iframe.contentWindow,B頁面通過監(jiān)聽A頁面發(fā)送的message拿到信息,然后保存到window.localStorage中。這里有同學(xué)會好奇了,既然B頁面拿到了信息,為啥還要保存到localStorage中,為啥不直接使用呢?你聽我狡辯...,啊不,你聽我說,這里拿到信息的B頁面只是A頁面中嵌入的B頁面,不是用戶打開的另一個(gè)窗口中的B頁面,所以這時(shí)剩下的工作就是將嵌入的B頁面中的信息發(fā)送給另一個(gè)窗口的B頁面,就大功告成了。兩個(gè)都是B頁面,就不存在跨域啦,就使用上面那個(gè)方案,通過監(jiān)聽strorage的改變獲取就行了。

示例代碼如下:

A頁面

const postInfo = () => {
    const bIframe = document.getElementById("bIframe");
    if (bIframe) {
        const centerX = window.innerWidth / 2 + window.screenLeft;
        const centerY = window.innerHeight / 2 + window.screenTop;
        const data = { centerX, centerY  };
        bIframe.contentWindow?.postMessage(
            JSON.stringify(data),
            "http://b.com"
        );
    }
};

const onMessage = (e) => {
    if (e.origin !== "http://b.com") return;
    if (e.data) {
        window.localStorage.setItem("bPageInfo", e.data);
    }
};

const onStorage = (e) => {
    if (e.key === "bPageInfo") {
        console.log("bPageInfo", JSON.parse(e.newValue));
    }
};

const onReady = () => {
    window.addEventListener("message", onMessage, false);
    if (window.self === window.top) {
        window.addEventListener("storage", onStorage);
        window.addEventListener("resize", postInfo);
    }
    postInfo();
}

window.addEventListener("ready", onReady);

在A頁面中嵌入B頁面

<iframe
    id="bIframe"
    src="http://b.com"
    style="display: none"
/>

B頁面

const postInfo = () => {
    const aIframe = document.getElementById("aIframe");
    if (aIframe) {
        const centerX = window.innerWidth / 2 + window.screenLeft;
        const centerY = window.innerHeight / 2 + window.screenTop;
        const data = { centerX, centerY  };
        aIframe.contentWindow?.postMessage(
            JSON.stringify(data),
            "http://a.com"
        );
    }
};

const onMessage = (e) => {
    if (e.origin !== "http://a.com") return;
    if (e.data) {
        window.localStorage.setItem("aPageInfo", e.data);
    }
};

const onStorage = (e) => {
    if (e.key === "aPageInfo") {
        console.log("aPageInfo", JSON.parse(e.newValue));
    }
};

const onReady = () => {
    window.addEventListener("message", onMessage, false);
    if (window.self === window.top) {
        window.addEventListener("storage", onStorage);
        window.addEventListener("resize", postInfo);
    }
    postInfo();
}

window.addEventListener("ready", onReady);

三、實(shí)戰(zhàn)案例

Visualization Collection網(wǎng)站中已經(jīng)實(shí)現(xiàn)了量子糾纏的效果,大家可以去玩一玩,該網(wǎng)站中的量子糾纏效果作為隱藏款案例,點(diǎn)擊網(wǎng)站左上角頭部的文字,即可觸發(fā),一般我不說的。

體驗(yàn)地址(PC端):hepengwei.cn

源碼地址:github.com/hepengwei/visualization-collection

四、美中不足

大家也看到了,上面GIF圖中演示的還是同域頁面實(shí)現(xiàn)量子糾纏的效果,這里非常遺憾地告訴大家,跨域頁面實(shí)現(xiàn)量子糾纏只能在本地運(yùn)行的情況下才可實(shí)現(xiàn),部署到線上就不行了,監(jiān)聽storage的回調(diào)不會執(zhí)行,后面我也試過各種辦法,比如在定時(shí)器里循環(huán)去獲取localStorage中的值,使用Service Worker等均無法實(shí)現(xiàn),這應(yīng)該是瀏覽器為了安全考慮進(jìn)行了限制。

如果有想要看兩個(gè)跨域頁面在本地實(shí)現(xiàn)量子糾纏效果的同學(xué),可以自行到我GitHub上下載visualization-collection和michelle-design這兩個(gè)項(xiàng)目代碼,然后在本地運(yùn)行,就可以看到效果啦。

五、結(jié)語

該終極方案與我的另一篇文章《兩個(gè)跨越頁面進(jìn)行跳轉(zhuǎn)傳參的終極方案》中的終極方案有異曲同工之妙,都是通過在原先的頁面中無痕嵌入另一個(gè)頁面,然后通過myIframe.contentWindow.postMessage來發(fā)送消息,如此實(shí)現(xiàn)跨域信息的傳遞。兩個(gè)不同窗口打開的同域頁面,則通過將信息保存到localStorage,另一頁面通過監(jiān)聽storage改變的方式傳遞信息。

到此這篇關(guān)于JS實(shí)現(xiàn)兩個(gè)跨域頁面實(shí)現(xiàn)量子糾纏互動效果的文章就介紹到這了,更多相關(guān)JS跨域頁面互動內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

最新評論