以即时点击样式执行 PJAX 调用(仅在链接悬停时加载所需的内容)

Doing PJAX calls in Instantclick style (loading only required content on hover of the links)

本文关键字:加载 悬停 链接 样式 执行 调用 PJAX      更新时间:2023-09-26

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

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

我想要的是即时点击只拉取所需的内容,如 PJAX,有些事情,比如在悬停链接时触发 PJAX 请求(有或不支持 Instantclick) - 从进入链接并单击单击发布有延迟,此时 PJAX 可以完成工作并立即将内容调高 100%。

有没有办法做到这一点?

谢谢

假设您的锚标记具有一个名为"data-pjax"的属性,并且容器div 名为"content",这应该可以工作:

        if ($.support.pjax) {
            $('a[data-pjax]').on('mouseover', function(event) {
                var container = $('#content');
                $.pjax.click(event, {container: container});
            });
        }

我修改了几年前为样式指南编写的代码,将其添加到 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

好的,

我分析了库jquery.pjax.js和Instantclick,它们耦合了很多,试图集成它们。

因此,一个

困难的解决方案是将一个库的功能集成到另一个库中,但不幸的是,我没有足够的 knoledge 来做到这一点。

我可以提出的是基于先前解决方案的黑客攻击。

主要思想是在鼠标悬停时触发单击事件,但容器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());
        });
    }
});
现在,从

我的角度来看,解决方案绝对是不完整的,原因如下:

  • 即时点击甚至照顾触摸手机,此解决方案没有
  • 如果您关闭了很多链接,并且用户只是"与他们一起玩"而不单击顶部,则JS将继续清理并要求良好的内容,但在栏中,您会看到地址不断变化

即使是这些问题,解决方案也可以"足够好",如果你只想实现快速的感觉。实际上,如果用户直接转到链接并单击UX很棒。

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