2

PJAX 通过加载请求页面的唯一必需内容来完成这项工作,而不是再次加载所有常见模式并将接收到的内容放置在布局中 - 就像具有所有后退按钮和历史功能的 Angular JS 的单页面应用程序一样。

Instantclick (instantclick.io) 是另一个有趣的,它在链接悬停时请求页面并将内容加载到缓存中,并在用户释放点击时替换内容,但这会加载整个页面。

我想要的是 Instantclick 仅拉取所需的内容,例如 PJAX,例如在链接悬停时触发 PJAX 请求(支持或不支持 Instantclick) - 进入链接并单击以单击释放存在延迟,并且在这一次 PJAX 可以完成工作并立即将内容提升 100%。

有没有办法做到这一点?

谢谢

4

3 回答 3

1

假设您的锚标记有一个名为“data-pjax”的属性并且容器 div 被命名为“内容”,这应该可以工作:

        if ($.support.pjax) {
            $('a[data-pjax]').on('mouseover', function(event) {
                var container = $('#content');
                $.pjax.click(event, {container: container});
            });
        }
于 2015-01-31T16:38:00.673 回答
1

我已经修改了我之前为样式指南所做的代码,添加了 pjax 导航。我喜欢您的请求的想法,这不是一个坏主意,但这需要一些选项,例如不缓存页面上的每个链接、检测外部页面等,但请随意使用它。还有一些控制台调试,它有点原始,并且使用jQuery

var SPAajaxloading = function () {

    var $links = $('#nav a');
    var historyCache = {};


    var getCache = function (url) {
        return historyCache[url];
    };
    var setCache = function (url, content) {
        historyCache[url] = content;
    };
    var setContent = function (content, URL) {
        $('#content').html(content);
        history.pushState(null, null, URL);
    };

    var getFragmentContent = function (responsecontent) {
        var $fakediv = $('<div>');
        $fakediv.html(responsecontent);
        return $fakediv.find('#content').html();
    };

    var getPageContent = function (URL, caching) {
        return $.ajax({
            url: URL
        }).promise().done(function (response) {
            var _content = getFragmentContent(response);
            !caching && setContent(_content, URL);
            setCache(URL, _content);
        });
    };


    var linkbinding = function (e) {
        e.preventDefault();
        var _URL = this.href;

        var cachedContent = getCache(_URL);
        //todo refactor this with popstate
        if (e.type === 'click' && cachedContent) {
            console.info('content inserted via cache');
            setContent(cachedContent, _URL);
        }
        else {

            // if mouseenter and cache is here, do nothing
            if (e.type === 'mouseenter' && cachedContent) {
                console.info('nothing to do, caching already done');
            }
            else {
                console.info('putting content in cache?', e.type === 'mouseenter');
                getPageContent(_URL, e.type === 'mouseenter')
            }
        }
    };

    $links.on('mouseenter click', linkbinding);

    setCache(location.href, $('#content').html());

    $(window).on('popstate', function () {
        var _URL = location.href;
        var content = getCache(_URL);
        if (content) {
            setContent(content, _URL);
        }
        else {
            getPageContent(_URL)
        }
    });

};

我刚刚在 gisthub 上发布了它,如果你想改进它,或者为什么不在 PJAX 加载上启动另一个 github 项目,请告诉我,我愿意在这方面走得更远! https://gist.github.com/romuleald/bc7d4a941f42f8e4bc0e

于 2015-04-15T09:48:33.893 回答
0

好的,我分析了 jquery.pjax.js 和 Instantclick 这两个库,它们非常耦合以尝试集成它们。

所以一个困难的解决方案是将一个库的功能集成到另一个库中,但不幸的是我没有足够的知识。

我可以提出的是基于先前解决方案的 hack。

主要思想是在鼠标悬停时触发点击事件,但容器是display:none. 比单击我们将内容从 移动#hidden-container#container

html代码将是:

<div id="container"></div>
<div style="display:none" id="hidden-conainer"></div>

相反,js将是:

$(document).ready(function(){
    if ($.support.pjax) {
        $('a').on('mouseover', function(event) {
            // clean idden-conainer 
            $('#hidden-conainer').empty();

            var container = $('#hidden-conainer');
            $.pjax.click(event, {container: container});
        }).on('click', function(event) {
            event.preventDefault();
            $('#container').html($('#hidden-conainer').html());
        });
    }
});

由于这些原因,从我的角度来看,现在作为解决方案绝对是不完整的:

  • Instantclick 甚至可以处理带有触摸的移动设备,此解决方案没有
  • 如果您关闭了很多链接并且用户只是“与他们一起玩”而不点击顶部,则 js 会不断清理并需要好的内容,但在栏中您会看到地址不断变化

即使是那些问题,如果您只想获得快速的感觉,它也可能是“足够好”的解决方案。实际上,如果用户直接访问链接并单击 UX,那就太好了。

除此之外,为鼠标悬停创建缓存可能会很好,因此即使用户试图强调界面,您也不会一直进行相同的调用。

于 2015-04-13T12:44:51.463 回答