页面之间未共享本地存储



我有一个带有2页的Epub3书以及一个目录页面。我正在Mac OSX上的苹果书中查看这本书。这两个页面并排出现。第一页如下:

<?xml version="1.0" encoding="UTF-8"?>
<html xmlns="http://www.w3.org/1999/xhtml" xmlns:epub="http://www.idpf.org/2007/ops">
    <head>
        <meta charset="utf-8" />
        <meta name="viewport" content="width=500, height=600"/>
    </head>
    <body>
<p id="result"></p>
<script>
//<![CDATA[
  var current_page = "1";
  var other_page = "2";
  var t = 0;
  setInterval(function() {
    var d = new Date();
    var storage = localStorage; 
    storage.setItem("t"+ current_page, d.toLocaleString());
    document.getElementById("result").innerHTML = storage.getItem("t"+ current_page) +" "+storage.getItem("t"+ other_page);    
  }, 1000);
//]]>
</script>
    </body>
</html>

,第二页中唯一不同的是:

  var current_page = "2";
  var other_page = "1";

因此,每一秒钟,第1页将当前时间保存到本地存储为t1,而第2页对于值t2的作用相同。同时,在将其值显示为屏幕之前,这两个页面都从本地存储中读取t1t2。但是,在iBooks中,第1页仅设法在重新加载页面时显示t2的当前值 - 就像当我翻转到目录时,然后再次返回第1页和第2页。对于t1,第2页发生了类似的事情。

所以在时间21:10:00,第1页可能显示:

08/09/19,21:09:18 08/09/19,21:08:58

和第2页:

08/09/19,21:09:22 08/09/19,21:08:01

我也尝试使用会话数据,但是第1页无法读取t2,并且第2页无法读取t1。因此,这将显示为:

08/09/19,21:09:18 null

我可以想到几个应用程序,对于页面而言,相互通信非常有用。

例如,如果视频在一个页面上播放,则如果启动了另一个页面上的视频,则将其停止将很有用。通常,这是使用会话存储进行的。这与我自己的用例以及我开始探索此问题的原因有关。

同样,如果在第1页上要求用户输入故事的主字符的名称,则该条目在输入后应立即出现在第2页上。

除本地或会话存储以外,还有其他方法可以在EPUB3中相互通信吗?

我不知道epub3,没有Mac可以测试,但是以下是我想到的四个可能的解决方案:

cookie

对于该用例,它的性能不如localStorage,但是如果您没有很多选择,那么它比没有更好。

函数可以创建,读取和删除cookie(信用https://stackoverflow.com/a/a/28230846/9150652(:

function setCookie(name,value,days) {
    var expires = "";
    if (days) {
        var date = new Date();
        date.setTime(date.getTime() + (days*24*60*60*1000));
        expires = "; expires=" + date.toUTCString();
    }
    document.cookie = name + "=" + (value || "")  + expires + "; path=/";
}
function getCookie(name) {
    var nameEQ = name + "=";
    var ca = document.cookie.split(';');
    for(var i=0;i < ca.length;i++) {
        var c = ca[i];
        while (c.charAt(0)==' ') c = c.substring(1,c.length);
        if (c.indexOf(nameEQ) == 0) return c.substring(nameEQ.length,c.length);
    }
    return null;
}
function eraseCookie(name) {   
    document.cookie = name+'=; Max-Age=-99999999;';  
}

用法用于您的示例:

<script>
//<![CDATA[
  var current_page = "1";
  var other_page = "2";
  var t = 0;
  setInterval(function() {
    var d = new Date();
    setCookie("t"+ current_page, d.toLocaleString(), 100); // 100 days
    document.getElementById("result").innerHTML = getCookie("t"+ current_page) +" "+getCookie("t"+ other_page);    
  }, 1000);
//]]>
</script>

广播channel

BroadCastChannel是一个非常新的功能,因此"书籍"应用程序可能不会支持它。但这是一个概念:

<script>
//<![CDATA[
  var broadcaster = new BroadcastChannel('test');
  var current_page = "1";
  var other_page = "2";
  var t = 0;
  setInterval(function() {
    var d = new Date();
    // Send message to all other tabs with BroadcastChannel('test')
    bc.postMessage({
        senderPage: "t"+ current_page,
        date: d.toLocaleString()
    });
  }, 1000);
  broadcaster.onmessage = (result) => {
      if(result.senderPage == "t"+ other_page) { // If the message is from the other page
        // Set HTML to current date + sent Date from other page
        var d = new Date();
        document.getElementById("result").innerHTML = d.toLocaleString() +" "+result.date;    
      }
  };
//]]>
</script>

某种后端

如果以上都没有作用,则您可能没有其他选择,只能使用某种后端来提供和保存数据

如果仅适合您,我建议您使用免费的firebase或mongodb地图集,因为它们都可以为自己的免费层提供一些价值。

如果您使用后端进行操作,则可以使用类似的事情来完成:

<script>
//<![CDATA[
  var current_page = "1";
  var other_page = "2";
  var lastLocalDate = new Date();
  const serverUrl = "http://someUrl.com/endpoint/"
  // Gets the latest date of the other page via ajax
  function getUpdate() {
    var xmlhttp = new XMLHttpRequest();
    xmlhttp.onreadystatechange = function() {
        if (xmlhttp.readyState == XMLHttpRequest.DONE) {
            // If successful, update HTML
            if (xmlhttp.status == 200) {
                document.getElementById("result").innerHTML = lastLocalDate.toLocaleString() +" "+xhr.responseText;
            }
            // Update the date of this page anyways
            sendUpdate();
        }
    };
    // GET request with parameter requestingPage, which is the other page
    xmlhttp.open("GET", serverUrl, true);
    xmlhttp.send(`requestingPage=${other_page}`);
  }
  // Sends the current date of this page to the webserver
  function sendUpdate() {
    var xmlhttp = new XMLHttpRequest();
    // No need to check if successful, just update the page again
    xmlhttp.onreadystatechange = function() {
        if (xmlhttp.readyState == XMLHttpRequest.DONE) {
            getUpdate();
        }
    };
    lastLocalDate = new Date();
    // POST request with parameters page and date
    xmlhttp.open("POST", serverUrl, true);
    xmlhttp.send(`sendingPage=${current_page}&data=${lastLocalDate.toLocaleString()}`);
  }
  // Start with sending an update (so that lastLocalDate is at least sent once to the server)
  sendUpdate();
//]]>
</script>

和后端中的某些方法需要看起来像这样(请注意,这不是任何语言中的有效代码(:

@GET
function getDate(requestingPageId)
    find latest entry with page.id == requestingPageId
    return page.date
@POST
function saveDate(savingPage, savingDate)
    store new page element with 
        page.id = savingPage
        page.date = savingDate

和数据库中的一个收集看起来像这样:

[
    {
        id: 1,
        date: "date"
    },{
        id: 2,
        date: "date"
    },{
        id: 2,
        date: "date"
    },{
        id: 1,
        date: "date"
    },
    // ...
]

窗口参考

如果书籍应用程序从第一个选项卡打开第二个选项卡,则可能值得研究:

  • window.postmessage((
    • 及其功能:
    • window.open(( 打开第二个选项卡并获取对它的引用
    • 和窗口。开放器获取对开瓶器的引用

相关内容

  • 没有找到相关文章

最新更新