在保持当前窗口位置的情况下重新加载JavaScript页面

7

如何使用Javascript刷新页面而不返回页面顶部。

我的页面使用计时器进行刷新,但问题是每次重新加载时它都会返回到顶部。它应该能够在重新加载时保留当前页面位置。

附加的鼠标事件可以作为您建议的一部分,如果有必要。我实际上正在考虑使用#idname来刷新目标,但我的HTML元素没有ID,只有类。

4个回答

11

如果你使用 JavaScript,这段代码可以解决问题。

var cookieName = "page_scroll";
var expdays = 365;

// An adaptation of Dorcht's cookie functions.

function setCookie(name, value, expires, path, domain, secure) {
    if (!expires) expires = new Date();
    document.cookie = name + "=" + escape(value) + 
        ((expires == null) ? "" : "; expires=" + expires.toGMTString()) +
        ((path    == null) ? "" : "; path=" + path) +
        ((domain  == null) ? "" : "; domain=" + domain) +
        ((secure  == null) ? "" : "; secure");
}

function getCookie(name) {
    var arg = name + "=";
    var alen = arg.length;
    var clen = document.cookie.length;
    var i = 0;
    while (i < clen) {
        var j = i + alen;
        if (document.cookie.substring(i, j) == arg) {
            return getCookieVal(j);
        }
        i = document.cookie.indexOf(" ", i) + 1;
        if (i == 0) break;
    }
    return null;
}

function getCookieVal(offset) {
    var endstr = document.cookie.indexOf(";", offset);
    if (endstr == -1) endstr = document.cookie.length;
    return unescape(document.cookie.substring(offset, endstr));
}

function deleteCookie(name, path, domain) {
    document.cookie = name + "=" +
        ((path   == null) ? "" : "; path=" + path) +
        ((domain == null) ? "" : "; domain=" + domain) +
        "; expires=Thu, 01-Jan-00 00:00:01 GMT";
}

function saveScroll() {
    var expdate = new Date();
    expdate.setTime(expdate.getTime() + (expdays*24*60*60*1000)); // expiry date

    var x = document.pageXOffset || document.body.scrollLeft;
    var y = document.pageYOffset || document.body.scrollTop;
    var data = x + "_" + y;
    setCookie(cookieName, data, expdate);
}

function loadScroll() {
    var inf = getCookie(cookieName);
    if (!inf) { return; }
    var ar = inf.split("_");
    if (ar.length == 2) {
        window.scrollTo(parseInt(ar[0]), parseInt(ar[1]));
    }
}

此方法通过使用 cookie 来记住滚动位置。

现在只需添加:

onload="loadScroll()" onunload="saveScroll()"
将其添加到您的 body 标签中,一切都会很好。 来源:http://www.huntingground.freeserve.co.uk/main/mainfram.htm?../scripts/cookies/scrollpos.htm

我正在使用PHP,还有其他的想法吗?谢谢。 - JCm
4
好的,现在它使用纯JavaScript了。尽情享用吧。 - Mark Kramer
有没有办法让这个在´iframe´内加载的页面正常工作?我在网站上使用´iframe´添加了一个处于预览模式的谷歌文档,并且我需要每隔x秒为用户刷新它,而不会影响他在文档中的位置。 - FanaticD
我对你的答案进行了一些编辑,以清理代码风格。它应该完全相同。 - 4castle

2
如果页面上有一组特定的部分可以作为初始“滚动到”点,那么您可以为这些部分分配CSS ID,并在末尾附加ID哈希值刷新页面。例如,window.location = http://example.com#section2将重新加载页面并自动滚动到具有ID“section2”的元素。
如果不是那么具体,您可以使用jQuery的.scrollTop()方法在window上获取刷新前的当前滚动位置:$(window).scrollTop()。然后,您可以将其附加到刷新URL中,并在页面上包含JS以检查它,以便在页面加载时自动滚动到正确的位置:
获取当前滚动位置
var currentScroll = $(window).scrollTop();
window.location = 'http://example.com#' + currentScroll;

必须在DOM准备就绪时运行的JS,以检查当前滚动哈希值

$(function(){
    if(window.location.hash !== ''){
        var scrollPos = parseInt(window.location.hash.substring(1),10);
        $(window).scrollTo(scrollPos);
    }
});

如果您不喜欢在地址栏中修改URL(因为出于某种原因,您真的想要隐藏您所做的事情),那么可以将scrollTo()值存储在cookie中而不是URL中。

我真的很喜欢这个快速技巧。现在我想,本地/ DOM 存储可能是另一个你可以使用的想法。去谷歌一下吧。 - AmbrosiaDevelopments
本地存储的问题在于它只能通过HTML5使用。如果您的用户群体包括使用ie8的人,则依赖HTML5并不是一个好主意,直到ie8消失为止。 - maxedison
抱歉,我在考虑在选项卡成为常规功能之前非常有用的window.name能力。 - AmbrosiaDevelopments
同时,在iPad的隐私模式下是不支持本地存储的......如果你还要支持这个设备选项的话。 - Ashwin Hegde

1

您可以使用基于cookie的方法来实现:

<html>
    <head>
        <script type="text/javascript">
            var refreshPeriod = 120; // 120 Seconds

            function refresh()
            {
                document.cookie = 'scrollTop=' + filterScrollTop();
                document.cookie = 'scrollLeft=' + filterScrollLeft();
                document.location.reload(true);
            }

            function getCookie(name)
            {
                var start = document.cookie.indexOf(name + "=");
                var len = start + name.length + 1;

                if(((!start) && (name != document.cookie.substring(0, name.length))) || start == -1)
                    return null;

                var end = document.cookie.indexOf(";", len);

                if(end == -1)
                    end = document.cookie.length;

                return unescape(document.cookie.substring(len, end));
            }

            function deleteCookie(name)
            {
                document.cookie = name + "=" + ";expires=Thu, 01-Jan-1970 00:00:01 GMT";
            }

            function setupRefresh()
            {
                var scrollTop = getCookie("scrollTop");
                var scrollLeft = getCookie("scrollLeft");

                if (!isNaN(scrollTop))
                {
                    document.body.scrollTop = scrollTop;
                    document.documentElement.scrollTop = scrollTop;
                }

                if (!isNaN(scrollLeft))
                {
                    document.body.scrollLeft = scrollLeft;
                    document.documentElement.scrollLeft = scrollLeft;
                }

                deleteCookie("scrollTop");
                deleteCookie("scrollLeft");

                setTimeout("refresh()", refreshPeriod * 1000);
            }

            function filterResults(win, docEl, body)
            {
                var result = win ? win : 0;

                if (docEl && (!result || (result > docEl)))
                    result = docEl;

                return body && (!result || (result > body)) ? body : result;
            }

            // Setting the cookie for vertical position
            function filterScrollTop()
            {
                var win = window.pageYOffset ? window.pageYOffset : 0;
                var docEl = document.documentElement ? document.documentElement.scrollTop : 0;
                var body = document.body ? document.body.scrollTop : 0;
                return filterResults(win, docEl, body);
            }

            // Setting the cookie for horizontal position
            function filterScrollLeft()
            {
                var win = window.pageXOffset ? window.pageXOffset : 0;
                var docEl = document.documentElement ? document.documentElement.scrollLeft : 0;
                var body = document.body ? document.body.scrollLeft : 0;
                return filterResults(win, docEl, body);
            }
        </script>
    </head>
    <body onload="setupRefresh()">
        <!-- content here -->
    </body>
</html>

或者你可以使用表单方法来实现:

<html>
    <head>
        <script type="text/javascript">
            // Saves scroll position
            function scroll(value)
            {
                var hidScroll = document.getElementById('hidScroll');
                hidScroll.value = value.scrollTop;
            }

            // Moves scroll position to saved value
            function scrollMove(el)
            {
                var hidScroll = document.getElementById('hidScroll');
                document.getElementById(el).scrollTop = hidScroll.value;
            }
        </script>
    </head>
    <body onload="scrollMove('divScroll');" onunload="document.forms(0).submit()";>
        <form>
            <input type="text" id="hidScroll" name="a"><br />
            <div id="divScroll" onscroll="scroll(this);"
                 style="overflow:auto;height:100px;width:100px;">
                <!-- content here -->
            </div>
        </form>
    </body>
</html>

这取决于您的应用程序的要求和限制。


0
我建议使用ajax仅刷新您想要更改的页面部分。我的意思是,根据ajax调用的响应,只需使用javascript替换内容。我建议您查看jQuery的ajaxget方法。
如果您可以提供有关您尝试做什么的更多信息,也许我可以提供更多帮助。无论如何,希望这能有所帮助。
祝好!

好的先生,我想要刷新的页面实际上是已经包含在<iframe>标签中的页面的一部分。现在,我使用<iframe>页内容<head>标签中包含的JavaScript刷新<iframe>的内容。<iframe>内部的页面加载来自我的数据库的一个表格。它默认加载当天的当前数据或所选日期的数据。我的数据库查询参数可以在页面的GET变量中找到。每次刷新页面时,我会保留URL中的GET变量,以便以相同的数据加载页面。 - JCm
我看到你在使用PHP,但是我对PHP一无所知。不过,你能否通过HTTP GET请求以JSON格式返回表格数据呢?这样你只需要从JavaScript中调用该请求并刷新表格即可。 - Chango

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接