首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >在用户停止阅读时获取积分

在用户停止阅读时获取积分
EN

Stack Overflow用户
提问于 2018-06-13 15:46:04
回答 5查看 316关注 0票数 15

用户A进入我的在线杂志。她开始读一篇很长的文章,然后在读到一半时她决定停下来。她关闭浏览器,几个小时后才返回网站。现在,当她再次打开同一篇文章时,我希望页面从她离开的地方开始。

镜像用户A实际上是一个注册用户,我该如何实现?更具体地说,我想存储屏幕上第一个可见行(基本上是左上角)的第一个字符的字符数(作为int)。

编辑:只是为了进一步澄清,你可以认为像Instapaper或Pocket这样的应用程序也面临着类似的问题(包括移动应用程序和web应用程序)。

EN

回答 5

Stack Overflow用户

发布于 2018-06-13 15:57:41

更新的答案

我真的不确定如何才能做到这一点。我建议使用localStorage存储文档滚动的数量。

您可以获得文档滚动的距离和文档关闭时的尺寸,如果重新加载时文档的宽度相同,则可以滚动到相同的点。如果不是,您可以通过计算读取的width * scrollTop卷并将其除以当前宽度来估计用户停止的点。

下面是一个伪代码,可以帮助你理解这个概念:

代码语言:javascript
复制
if oldWidth == currentWidth
    set scroll = oldScroll
else
    set scroll = oldScroll * oldWidth / currentWidth

以下是上述伪代码的JavaScript示例,但首先需要注意以下几点:

代码片段中不允许使用

  • localStorage,因此当前代码在此处将不起作用。如果要进行测试,则必须将其复制到其他地方。leavePage()方法的末尾有一条return null语句,这是因为有些浏览器在没有返回语句的情况下无法运行函数

代码语言:javascript
复制
if (document.readyState === "complete") enterPage();
else addEventListener("load", enterPage);
addEventListener("beforeunload", leavePage);

function enterPage() {
  var magazineDom = document.querySelector("#magazine");
  if (magazineDom instanceof HTMLElement) {
    magazineDom.textContent = "Lorem Ipsum".repeat(800);
    //onRender();
  }
}

function onRender() {
  var magazineContainerDom = document.querySelector("#magazine-container");
  var magazineDom = document.querySelector("#magazine");
  if (magazineContainerDom instanceof HTMLElement && magazineDom instanceof HTMLElement) {
    var info = getMagazineInfo(magazineDom.getAttribute("magazine"));
    if (info) {
      var currentWidth = magazineDom.scrollWidth;
      if (currentWidth == info.width) magazineContainerDom.scrollTop = info.top;
      else magazineContainerDom.scrollTop = info.top * info.width / currentWidth;
    }
  }
}

function leavePage() {
  var magazineContainerDom = document.querySelector("#magazine-container");
  var magazineDom = document.querySelector("#magazine");
  if (magazineContainerDom instanceof HTMLElement && magazineDom instanceof HTMLElement) {
    setMagazineInfo(magazineDom.getAttribute("magazine"), magazineContainerDom.scrollTop, magazineDom.scrollWidth);
  }
  return null;
}

function getMagazineInfo(name) {
  return JSON.parse(localStorage.magazines || "{}")[name];
}

function setMagazineInfo(name, top, width) {
  var magazines = JSON.parse(localStorage.magazines || "{}");
  magazines[name] = {
    top: top,
    width: width
  };
  localStorage.magazines = JSON.stringify(magazines);
}
代码语言:javascript
复制
body {
  position: fixed;
  bottom: 0;
  right: 0;
  left: 0;
  top: 0;
}

#magazine-container {
  overflow-y: auto;
  height: 100%;
  width: 100%;
}

#magazine {
  max-width: 500px;
  margin: auto;
}
代码语言:javascript
复制
<body>
  <div id="magazine-container">
    <div id="magazine" magazine="First Document">

    </div>
  </div>
</body>

票数 10
EN

Stack Overflow用户

发布于 2018-06-17 02:30:08

我玩得很开心。该脚本正在创建一个行数组。可以在数组中搜索存储在Cookie中或更好地存储在本地存储中的项。

看见

代码语言:javascript
复制
function findLine4(str)

希望你能在下面为你的问题找到一些想法。请不要介意,这只是一些肮脏的脚本。

代码语言:javascript
复制
<html>
<body>
    <div id="containerWrapper"></div>
    <div id="testWrapper"></div>

    <div id="originDiv" style="background:#fee;">
    Lorem ipsum dolor sit amet, consectetuer adipiscing 
elit. Aenean commodo ligula eget dolor. Aenean massa 
<strong>strong</strong>. Cum sociis natoque penatibus 
et magnis dis parturient montes, nascetur ridiculus 
mus. Donec quam felis, ultricies nec, pellentesque 
eu, pretium quis, sem. Nulla consequat massa quis 
enim. Donec pede justo, fringilla vel, aliquet nec, 
vulputate eget, arcu. In enim justo, rhoncus ut, 
imperdiet a, venenatis vitae, justo. Nullam dictum 
felis eu pede <a class="external ext" href="#">link</a> 
mollis pretium. Integer tincidunt. Cras dapibus. 
Vivamus elementum semper nisi. Aenean vulputate 
eleifend tellus. Aenean leo ligula, porttitor eu, 
consequat vitae, eleifend ac, enim. Aliquam lorem ante, 
dapibus in, viverra quis, feugiat a, tellus. Phasellus 
viverra nulla ut metus varius laoreet. Quisque rutrum. 
Aenean imperdiet. Etiam ultricies nisi vel augue. 
Curabitur ullamcorper ultricies nisi.
<br /><br /><br />
    Lorem ipsum dolor sit amet, consectetuer adipiscing 
elit. Aenean commodo ligula eget dolor. Aenean massa 
<strong>strong</strong>. Cum sociis natoque penatibus 
et magnis dis parturient montes, nascetur ridiculus 
mus. Donec quam felis, ultricies nec, pellentesque 
eu, pretium quis, sem. Nulla consequat massa quis 
enim. Donec pede justo, fringilla vel, aliquet nec, 
vulputate eget, arcu. In enim justo, rhoncus ut, 
imperdiet a, venenatis vitae, justo. Nullam dictum 
felis eu pede <a class="external ext" href="#">link</a> 
mollis pretium. Integer tincidunt. Cras dapibus. 
Vivamus elementum semper nisi. Aenean vulputate 
eleifend tellus. Aenean leo ligula, porttitor eu, 
consequat vitae, eleifend ac, enim. Aliquam lorem ante, 
dapibus in, viverra quis, feugiat a, tellus. Phasellus 
viverra nulla ut metus varius laoreet. Quisque rutrum. 
Aenean imperdiet. Etiam ultricies nisi vel augue. 
Curabitur ullamcorper ultricies nisi.
    </div>

</body>
<script>
    (function init() {
        var i;
        var originDiv = document.getElementById("originDiv");
        var allowedWidth = originDiv.scrollWidth;

        function testBreak(testDiv, strTest) {
            testDiv.innerHTML = strTest + "..."; // Yepp, that's the point. No clue, how to fix this.
            return testDiv.scrollWidth > allowedWidth;
        }

        function tokenizeText() {
            return originDiv.innerHTML.trim()
                .split(/([\s]*<[a-zA-Z]+.*>.*<\/.*>[.,;:-]*[\s]*)|[\s]+/ig)
                .filter(function(a){return typeof(a) != 'undefined'})
                .map(function(a){return a.trim()}); 
        }

        function createLineArray() {
            var testDiv = originDiv.cloneNode(true);
            testDiv.innerHTML = "";
            testDiv.setAttribute("style", "white-space:nowrap;background:#ccc;visibility:hidden;");
            document.getElementById("testWrapper").appendChild(testDiv);

            var htmlWords = tokenizeText();
            var lines = [];
            var currLine = '';
            for(i = 0; i < htmlWords.length; i++) {
                currLine += htmlWords[i] + ' ';
                if(testBreak(testDiv, currLine)) {
                    lines.push(currLine.substr(0, currLine.length - htmlWords[i].length - 1));
                    currLine = '';
                    i--;
                }
            }
            lines.push(currLine);       
            return lines;
        }

        function createNewDiv(html) {
            var newDiv = document.createElement("DIV");
            newDiv.setAttribute("style", "background:#ddf");
            newDiv.setAttribute("id", "newContainer");  
            newDiv.innerHTML = html;
            return newDiv;  
        }

        (function doInit() {
            var lines = createLineArray();
            var formattedText = '';
            for (i = 0; i < lines.length; i++) {
                formattedText += '<div class="line'+i+'">' + lines[i] + '</div>';
            }           
            document.getElementById("containerWrapper").appendChild(createNewDiv(formattedText));
            // originDiv.style.display="none";
        })();

        (function findLine4(str) {
            //TODO: tokenize str and search for matching tokens.
            var nodes = document.getElementById("newContainer").childNodes;
            for(i = 0; i < nodes.length; i++) {
                if(nodes[i].textContent.indexOf(str) != -1) {
                    setTimeout(function() {
                        window.scrollTo(0, nodes[i].offsetTop);
                    },1);
                    break; 
                }
            }
        })("elementum semper");

        /* 
            I personally would prefer a timer instead of a listener here. 
        */
        window.addEventListener("scroll", function(evt) {
            var sct = window.scrollY;
            var nodes = document.getElementById("newContainer").childNodes;
            for(var i = 0; i < nodes.length; i++) {
                if(nodes[i].offsetTop > sct) {
                    console.log("line " + i + ": " + nodes[i].innerHTML);
                    break;
                }
            }
        }, true);       

    })();


</script>
</html>
票数 4
EN

Stack Overflow用户

发布于 2018-06-19 19:34:12

您可以只存储传递的句号数量,例如实际读取的行数。下一次,当用户再次打开网页时,您可以跳过所有这些句号(行),选择下一行并滚动到完整文本的那一行。

或者,如果您希望它更具体,那么您可以存储句号的数量和使用lastread键读取的单词数量的组合,如(“localStorage”,"f20w5")表示第20行后的第5个单词。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/50831722

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档