使用 AJAX 动态加载 WordPress 帖子

AJAX 在过去几年中风靡一时,这是有充分理由的.AJAX(异步 JavaScript 和 XML)是一种与服务器进行"对话"并在不重新加载页面的情况下显示结果的方式.

这项技术使我们能够刷新"点赞"计数器、将商品添加到购物车、创建动态表单等等——所有这些都无需重新加载页面.

在这篇博文中,我将向您展示如何使用 AJAX 以 25 个默认主题为基础加载帖子.

我们将看看为什么要使用 AJAX,并从一个简单的示例开始,将 AJAX 加载功能构建到 25 中.

注意:如果您在尝试在您的网站上设置 AJAX 时遇到任何问题,我们可以提供帮助!我们的 支持团队 24/7 可以帮助您解决任何 WordPress 问题(不仅仅是关于我们自己的插件的问题!),因此无论您遇到 AJAX 问题还是想要一些关于如何操作的建议CSS调整,取得联系!

为什么要使用 AJAX?

当 WordPress 在 WordPress 网站上加载帖子的第一页时,它会从数据库中请求它们,并使用我们添加的标记使用循环来显示它们.除此之外,还会加载导航菜单、小部件、图形和其他媒体、javascript 文件、样式表和一堆其他东西.

Network requests.
请注意,每次页面加载都会发出 72 个请求.

如上图所示(取自 Chrome 开发者工具),加载了相当数量的资产.这里有优化的空间,脚本之类的一些资产会被缓存,但即使这样也很多.

当我们的帖子的第二页被加载时,一切都会再次发生.WordPress 检索帖子并使用我们的标记显示它们.它还会重新加载页面的所有外围元素.在许多情况下(但不是全部),这是对带宽的浪费并且不利于用户体验.毕竟,没有人喜欢等待页面加载.

使用 AJAX 动态加载 WordPress 帖子

入门:创建子主题

在修改二十五之前,我们应该创建一个子主题.这确保我们可以继续更新主题而不会丢失我们的更改.您可以阅读所有关于如何做 in out 指南如何创建 WordPress 子主题.. p>

你好 AJAX!

让我们从一个演示 AJAX 工作原理的简单示例开始.我们将定位页面底部分页条内的链接,以便当您单击页码时,它将使用 AJAX 动态加载该页面.当点击分页链接时,我们将向服务器发送请求并提醒结果.

Pagination
我们将定位分页部分内的数字链接.

让我们的 Javascript 排队

我们的第一个调用端口是创建 JavaScript 文件并通过我们主题的 functions.php 文件将其加入队列.

我在其中创建了一个 js 文件夹和一个 ajax-pagination.js 文件.完成相同操作后,打开函数文件并将脚本添加到已经存在的 theme_enqueue_assets() 函数中:

加载要点 5ca270c7c9ddd18e57b4

如果您对排队感到困惑,请阅读我们关于以正确方式向 WordPress 添加脚本和样式的文章.简而言之,我们已经告诉了 WordPress 我们想给我们的脚本起什么名字(参数一),它的位置(参数二),先决条件是什么(参数三),版本号(参数四)并且我们想将它加载到页脚中(参数五).

请注意,在将样式表排入队列时,我使用了 get_template_directory_uri().这个函数总是指向父主题的目录.在将我们的脚本排入队列时,我使用了 get_stylesheet_directory_uri().如果在子主题中使用,这将指向子主题的目录.

由于我们在页脚中加载脚本,您可以将 alert( 'Script Is Enqueued' ) 粘贴到 ajax-pagination.js 并重新加载页面以检查它是否有效.如果是这样,则应正确警告文本.

创建事件

下一个任务是创建一个触发 AJAX 调用的事件.在我们的例子中,事件是点击特定链接.为了定位链接,我们需要了解一些关于它周围的元素类和 ID.

Pagination Source
Chrome 开发工具的分页源代码.

如果您想知道我是如何显示这个的,我在 Mac 上按了 Shift + Command + C(Shift + Control + C on Windows),将鼠标悬停在我要检查的元素上并单击它.

这告诉我,我们的分页链接有 page-numbers 类,下一个链接 next 类,这些都包含在一个 nav 元素中,其类为nav-links.此处未显示的是上一个链接,除了常规的 page-numbers 类之外,它还具有 prev 类.

暂时,我们不用担心所有这些,让我们只定位分页容器中的任何链接.我们可以像这样创建一个简单的警报:

加载要点 5ca270c7c9ddd18e57b4

请注意,所有内容都包含在匿名函数中.我建议你也这样做.看看这个线程为什么这很有帮助.我创建了一个点击事件,阻止了默认功能触发(即加载页面),并且我已经警告了一些文本.

创建 AJAX 调用

我们应该从服务器端获取一些动态数据,而不是使用客户端数据(提醒预设文本).我们需要做少量的准备工作.原因如下:我们需要为 AJAX 调用提供一个可以使用的 URL.我们的 Javascript 文件不了解我们的环境,所以我们不能在其中使用像 get_stylesheet_directory_uri() 这样的东西.但是,我们可以使用本地化技术将变量传递给我们的 JavaScript.现在让我们在函数文件中这样做:

加载要点 5ca270c7c9ddd18e57b4

通过在 my_enqueue_assets() 函数中添加此代码,我们将定义 ajaxpagination 对象(参数 2).该对象将根据 wp_localize_script() 函数中作为第三个参数提供的数组接收其成员.换句话说,一旦我们添加了这段代码,我们应该能够使用 ajaxpagination.ajaxurl 来定义我们用来处理 AJAX 调用的 admin-ajax.php 的 URL.

这样做的原因是本地化函数在我们的 JavaScript 加载之前输出了这个对象的定义.它看起来像这样:

加载要点 5ca270c7c9ddd18e57b4

回到我们的 JavaScript 文件,我们现在拥有构建 AJAX 调用所需的一切.方法如下:

加载要点 5ca270c7c9ddd18e57b4

如您所见,我们在这里使用的是 $.ajax() 函数.post 和 get 方法有一些特殊的功能,但我更喜欢使用这个功能,因为它很灵活.您可以阅读 jQuery 文档 中的所有参数.

使用 url 参数我们传递我们想要发送数据的脚本的 URL.这应该是可以在 wp-admin 目录中找到的 admin-ajax.php 文件.我们在上面通过 wp_localize_script() 函数定义了这一点.

type 设置为 post.我们也可以使用 get,我们的查询不太敏感,但我更喜欢发布数据,除非用户需要访问参数.

data 参数是一个包含您要传递的数据的对象.在我们的例子中,我将能够访问一个 $_POST['action'] 变量,其值为 ajax_pagination.当然,您可以传递任意数量的应用程序.

AJAX Call Alert
如果没有写服务器端代码则返回0.

最后,success 参数是一个提醒我们 AJAX 调用结果的函数.我们将在下面让它变得更漂亮,现在这足以进行测试了.如果您现在尝试单击链接,它实际上可以工作,但不会很有用,因为我们还没有定义服务器端代码.事实上,你应该看到 alerted 的是 0.

那么为什么会这样呢?当我说"我们还没有定义服务器端代码"时,我并不完全真实.我们没有,但 WordPress 有.我们正在使用的 admin-ajax.php 文件中有一些内容.如果您查看该文件的源代码,您应该会发现该脚本在某些情况下使用了 die( '0' ).

如果我们不提供一个动作,admin-ajax.php 脚本就会死掉并返回 0.如果我们提供了一个动作,但我们没有钩入所需的 WordPress 钩子,则不会发生任何事情,并且在文件的最后我们会死掉再次返回 0.总而言之,我们正在已经与服务器通信.

与 WordPress 通信

要从 WordPress 获得有意义的答案,我们需要定义一些 WordPress 操作.这是使用设置模式完成的.让我们继续我们主题的函数文件中的示例:

加载要点 5ca270c7c9ddd18e57b4

我已经将一个函数挂钩到两个挂钩上.采用 wp_ajax_[action_name] 格式的钩子仅对登录用户执行.采用 wp_ajax_norpiv_[action_name] 格式的钩子仅对未登录的用户执行.这样做的最大好处是您可以非常轻松地分离功能.

我上面提到的动作名称是指我们在 Javascript (action: 'ajax_pagination') 中的 AJAX 调用中定义的动作——它们必须匹配.函数名可以是任何你喜欢的名称,为了清楚起见,我使用了 my_ajax_pagination.

函数本身可以包含您想要的任何内容.您可以注销用户、获取他们的数据、发布帖子等等.无论您想返回 Javascript,您必须回显.在上面的示例中,我已经呼应了博客的标题,通过 get_bloginfo() 函数动态拉入.

最后一步是使用die().如果我们不定义这个,在文件末尾的 admin-ajax.php 中定义的 die 函数将会启动,你最终会回显 0 in addition 你正在回显的任何其他内容.如果您尝试上面的代码,您现在应该会看到返回的网站标题.

概述

我们的基本示例到此结束!在我们继续通过 AJAX 拉入帖子之前,让我们快速回顾一下执行 AJAX 操作所需的步骤:

  • 如果您还没有 Javascript 文件,请将其排入队列
  • 使用 wp_localize_script() 传递 admin-ajax.php 文件的 URL
  • 在 Javascript 中创建 AJAX 调用
  • 使用适当的挂钩名称挂钩函数
  • 编写可能将数据返回给 Javascript 的函数

使用 AJAX 加载帖子

现在是多汁的东西!我通过为它编写 JavaScript 代码开始了这个项目.事不宜迟,这里是基本版本.我们很快会通过一些调整后的用户体验对其进行扩展.

加载要点 5ca270c7c9ddd18e57b4

这与我们的基本示例大致相同.您会注意到的第一件事是,我添加了一种方法来检测用户想要请求哪个页面.每个链接都有一个隐藏的 span 元素(它用于屏幕阅读器).我对元素进行了克隆,以确保不修改原始元素,删除跨度并将其余部分解析为整数.这给了我们需要的页码.

我还需要知道使用的查询参数.在主页上这很简单,它只是 paged 参数,因为我们正在使用默认查询.如果我们从存档页面(如类别存档)开始,我们还需要知道类别名称.

我们将使用之前学习的本地化方法传递查询变量.现在我们将使用 ajaxpagination.query_vars,即使它还没有定义.最后,如果成功,我们会从主容器中删除所有 article 元素,我们会删除分页元素并将 AJAX 调用的返回值附加到主容器中.

此返回值将包含帖子和新的导航元素.请注意,我已将参数的名称从 response 更改为 html,因为它更有意义.最后,我们使用本地化数组来传递原始查询参数.

以下函数应该放在我们的 my_enqueue_assets() 函数中,替换我们之前的本地化:

加载要点 5ca270c7c9ddd18e57b4

我们现在需要做的就是充实 my_ajax_pagination() 函数.无论此功能回显什么,都将替换我们页面上的内容.这是最终代码,下面有解释:

加载要点 5ca270c7c9ddd18e57b4

使用我们传递的参数,我们构建了一个自定义查询.这基本上涉及获取我们传递的查询变量并确保我们传递的页码覆盖 paged 参数.然后我们使用最终的 数组来创建一个新查询.

我们需要使 $GLOBALS['wp_query'] 变量等于我们的新帖子对象.我们需要这样做的原因是 the_posts_pagination() 函数使用了这个全局变量.

接下来,请注意我在 editor_max_image_size 过滤器中添加了一个函数,并在接下来的几行中将其删除.这是出乎意料的事情.我实际上创建了一个 WordPress Trac Ticket.我们可能会看到一些进展!问题来了:

在帖子中加载图片后,它们看起来都很好.但是,如果您在没有这些过滤器的情况下完成本教程,您的图像将会更窄,只有 660 像素宽,而不是必要的 825 像素.原因是加载图像的函数最终调用了一个名为 image_constrain_size_for_editor() 的函数.此功能可确保帖子编辑器中的图像不会太宽.为了确定天气是否应该减小尺寸,它使用 is_admin() 函数.由于我们的代码通过 admin-ajax.php 运行,这在技术上是在管理中,WordPress 会缩小我们的图像,错误地认为我们在编辑器中使用它们.

幸运的是,我们可以使用 editor_max_image_size 过滤器来确定编辑器的最大尺寸.由于我们希望保持一切原样,除了在 AJAX 调用期间,我们使用自定义值 (array( 825, 510 )) 添加过滤器,然后立即将其删除,以确保它不会在其他任何地方造成麻烦.

下一步是使用我们的查询来列出我们的帖子.我从父主题中的 index.php 文件中复制了很多内容.如果没有帖子,我们使用旨在处理该问题的模板,否则我们遍历帖子并使用帖子显示模板.最后我们使用我们在索引文件中看到的相同的分页格式.

关于 AJAX 调用的注意事项

请务必记住,AJAX 调用始终被视为来自管理员.这意味着草稿、预定和私人帖子可能会通过此调用返回.如果您不希望这种情况发生,则需要使用适当的参数(例如 post_status)来控制行为.

更好的用户体验

对于这样的 AJAX 解决方案,关注用户体验非常重要.我在本地环境中工作,因此加载速度非常快,但在生产服务器上,图像和其他资产可能需要更多时间才能加载.

因此,您至少应该添加一个加载器或加载文本,并禁用对导航元素的进一步点击.我们将通过使帖子和导航在用户单击并显示文本"正在加载新帖子"后立即消失来处理这些问题.当成功事件触发时,我们删除加载文本并显示帖子.这是我们更新的 AJAX 调用:

加载要点 5ca270c7c9ddd18e57b4

我们现在有一个单独的 beforeSendsuccess 函数.前者在您单击链接后立即执行,然后将 AJAX 调用发送到服务器.后者在我们从服务器接收到数据后执行.

在发送呼叫之前,我们会删除文章和导航.这可以确保用户在等待加载时不能继续点击导航链接.接下来我们滚动到文档的顶部.然后,我们附加一个加载通知,让用户清楚地知道发生了什么.我在未找到的页面上使用了与二十五岁相同的标记.在成功函数中,我们移除加载器并加载我们的内容,全部完成!

AJAX 陷阱

AJAX 非常强大;除了加载帖子之外,您还可以通过 AJAX 调用执行各种操作.使用时有很多危险和注意事项,以下是一些:

安全可能是一个主要问题.例如,如果您想通过 AJAX 删除帖子,您需要确保用户具有意图和权限(使用 nonces).使用常规方法时,WordPress 在某些情况下具有内置保护,但使用 AJAX 您通常必须自己考虑这一点.

优雅降级是 AJAX 的另一个方面,尽管它变得不那么重要了.基本上:没有 JavaScript,没有 AJAX.如果您严重依赖 AJAX,禁用它的用户将无法使用我们的应用程序.Javascript 已经变得如此普遍,以至于这几乎无关紧要,但在某些情况下可能会出现.在这种情况下,您需要确保点击实际链接也能正常工作.

用户体验经常被忽视.AJAX 功能确实很酷,但可靠运行的网站更酷.用户习惯于在点击链接时加载页面.你需要让一切都变得非常透明,用户应该知道发生了什么以及为什么.您应该使用 AJAX 来增强您的工作,而不是尽可能多地炫耀.

概述

如您所见,实现 AJAX 需要一些准备和练习,但一旦成为第二天性,您就会发现它很容易实现.您可能花了一些时间来阅读这篇文章,而且第一次完成它需要更多的时间,但我在大约 15 分钟内编写了整个示例.

AJAX 是其中一种可能比较困难的技术,因为它几乎涵盖了 WordPress 等框架中使用的所有编程语言.必须遵守诸如钩子和本地化之类的约定,从而使事情变得更加有趣.

熟能生巧.如果您开始使用 AJAX,我保证您会爱上它.

标签:

3
订阅评论
提醒
0 评论
内联反馈
查看所有评论