使用PHP+AJAX讓W(xué)ordPress動(dòng)態(tài)加載文章的教程
為什么要?jiǎng)討B(tài)加載文章?
1. 快速向訪客展示頁(yè)面
文章很容是包含大量文字和多媒體資源 (如: 圖片, 視頻, 音樂), 加載這些內(nèi)容需要占用很多的時(shí)間. 如果你的頁(yè)面上存在大量文章, 當(dāng)訪客發(fā)現(xiàn)頁(yè)面久久沒有加載完成就感到不耐煩. 這是動(dòng)態(tài)加載文章的主要目的.
2. 讓文章列表化
使頁(yè)面上的文章成為一個(gè)列表, 減少頁(yè)面的空間占用, 訪客可以方便的移動(dòng)到頁(yè)面下方, 提高舊文章被點(diǎn)擊的幾率. 并且你可以在頁(yè)面上放置更多的文章而不用擔(dān)心頁(yè)面過長(zhǎng).
為什么不動(dòng)態(tài)加載文章?
1. 對(duì)搜索引擎不友好
搜索引擎優(yōu)化的目的是將有價(jià)值的東西盡量多的向搜索爬蟲展示, 包括最新的文章內(nèi)容. 只有標(biāo)題的文章讓爬蟲只知道這個(gè)文章而不知其文章側(cè)重, 使用 JavaScript 輸出的文章內(nèi)容未必可以被抓取和分析. 這些對(duì) SEO 來說都是不好的.
后來發(fā)現(xiàn), 如果你的網(wǎng)站有固定的文章類型, 沒有畢業(yè)在文章列表頁(yè)顯示太多文章內(nèi)容, 表示影響不大.
2. 增加了請(qǐng)求次數(shù)
雖然將文章折疊起來, 我們一般還是會(huì)想辦法向訪客顯示前面的幾篇文章. 這樣對(duì)用戶是友好的, 但是要增加請(qǐng)求的次數(shù)和數(shù)據(jù)庫(kù)訪問的次數(shù).
后來我有選擇地顯示部分文章內(nèi)容, 而且不是通過異步加載的方式, 也就是說, 這個(gè)問題是可以通過簡(jiǎn)單的修改解決掉的.
3. 一些插件失效
因?yàn)樾枰远x方法抓取文章, 如果不添加特殊處理, 很可能令部分 WordPress 插件失效.
可以通過特殊處理解決掉, 以后文章中會(huì)提及.
動(dòng)態(tài)加載文章的設(shè)計(jì)思路
1. 找到頁(yè)面上所有文章
為每個(gè)文章添加一個(gè)展開/折疊按鈕
2. 向文章添加展開/折疊按鈕
點(diǎn)擊按鈕, 如果文章內(nèi)容沒有加載, 加載并展開文章內(nèi)容.
點(diǎn)擊按鈕, 如果文章內(nèi)容已經(jīng)加載, 則展開/折疊文章內(nèi)容.
3. 加載文章內(nèi)容
將文章的 id 發(fā)往后臺(tái), 在數(shù)據(jù)庫(kù)中找到相應(yīng)的文章內(nèi)容并進(jìn)行格式化, 返回響應(yīng)顯示在頁(yè)面上.
JavaScript 處理代碼分析
1. 找到頁(yè)面上所有文章
/ 在文檔加載完畢的時(shí)候遍歷所有匹配文章的元素 jQuery(document).ready(function(){ jQuery('div.post').each(function() { // 如果元素相應(yīng)位置是文章 ID var id = jQuery(this).attr('id'); if(/^post\-[0-9]+$/.test(id)) { // 則為每個(gè)文章添加一個(gè)展開/折疊按鈕 ... } }); });
toggle.toggle(function() { // 展開 // 如果文章內(nèi)容為空, 加載文章內(nèi)容 if(jQuery('#' + id + ' .content').text() == '') { ... } // 顯示文章內(nèi)容, 并切換按鈕樣式 jQuery('#' + id + ' .content').slideDown(); jQuery(this).removeClass('collapse').addClass('expand'); }, function() { // 折疊 // 隱藏文章內(nèi)容, 并切換按鈕樣式 jQuery('#' + id + ' .content').slideUp(); jQuery(this).removeClass('expand').addClass('collapse'); // 將按鈕追加到文章標(biāo)題前方 }).prependTo(jQuery('#' + id + ' h2'));
3. 加載文章內(nèi)容
// 取得文章 ID var postId = id.slice(5); // 使用 AJAX 獲取并處理文章內(nèi)容 jQuery.ajax({ type: 'GET' ,url: '?action=load_post&id=' + postId ,cache: false ,dataType: 'html' ,contentType: 'application/json; charset=utf-8' // 取得返回內(nèi)容之前顯示加載信息 ,beforeSend: function(data){loadPostContent(id, '<p class="ajax-loader">Loading...</p>');} // 獲取文章內(nèi)容成功, 更新文章內(nèi)容 ,success: function(data){loadPostContent(id, data);} // 獲取文章內(nèi)容失敗, 顯示出錯(cuò)提示 ,error: function(data){loadPostContent(id, '<p>Oops, failed to load data.</p>');} });
后臺(tái)處理
處理思路
從前臺(tái)傳到后臺(tái)的參數(shù)有兩個(gè), 一個(gè)是 action ID, 用于確定使用的接口, 另一個(gè)是文章的 ID, 用于獲取文章對(duì)應(yīng)的內(nèi)容.
下面我們來分析一下wp-includes/post-template.php 的 get_the_content 方法.
function get_the_content($more_link_text = null, $stripteaser = 0) { global $id, $post, $more, $page, $pages, $multipage, $preview; // 設(shè)定 "查看全文" 的鏈接文案 if ( null === $more_link_text ) $more_link_text = __( '(more...)' ); // 返回內(nèi)容 $output = ''; // More 標(biāo)簽是否存在的標(biāo)記位 $hasTeaser = false; // 如果文章要求輸入密碼, 并且在 Cookie 中找不到處理過的信息, 則返回要求輸入密碼的查看表單 if ( post_password_required($post) ) { $output = get_the_password_form(); return $output; } // 請(qǐng)求的文章片段對(duì)應(yīng)的頁(yè)面大于最大頁(yè)數(shù) (即文章片段不存在), 則返回最大頁(yè)碼的文章片段 if ( $page > count($pages) ) $page = count($pages); // 文章內(nèi)容是最后分頁(yè)中的文章片段 $content = $pages[$page-1]; // 如果文中有 More 標(biāo)簽, 要求切斷文章并輸出 "查看全文" 鏈接, 則重定義文章內(nèi)容, 標(biāo)記 More 標(biāo)簽存在 if ( preg_match('/<!--more(.*?)?-->/', $content, $matches) ) { $content = explode($matches[0], $content, 2); if ( !empty($matches[1]) && !empty($more_link_text) ) $more_link_text = strip_tags(wp_kses_no_null(trim($matches[1]))); $hasTeaser = true; } else { $content = array($content); } // 如果進(jìn)行了文章切斷處理, 且不存在分頁(yè)要求, if ( (false !== strpos($post->post_content, '<!-- noteaser -->') && ((!$multipage) || ($page==1))) ) $stripteaser = 1; // 獲取文章內(nèi)容的第一部分; 如果在獨(dú)立文章存在 Read more 和切斷處理, 則文章內(nèi)容為空 $teaser = $content[0]; if ( ($more) && ($stripteaser) && ($hasTeaser) ) $teaser = ''; $output .= $teaser; // 如果文章分為多個(gè)片段, 在獨(dú)立文章中拼接上第二部分, 摘要內(nèi)容中顯示 "閱讀全文" 鏈接 if ( count($content) > 1 ) { if ( $more ) { $output .= '<span id="more-' . $id . '"></span>' . $content[1]; } else { if ( ! empty($more_link_text) ) $output .= apply_filters( 'the_content_more_link', ' <a href="' . get_permalink() . "#more-$id\" class=\"more-link\">$more_link_text</a>", $more_link_text ); $output = force_balance_tags($output); } } if ( $preview ) // preview fix for javascript bug with foreign languages $output = preg_replace_callback('/\%u([0-9A-F]{4})/', create_function('$match', 'return "&#" . base_convert($match[1], 16, 10) . ";";'), $output); // 返回文章內(nèi)容 return $preview; }
處理方法
如果我們暫時(shí)不考慮輸入密碼, 分頁(yè)等功能; 另外, 因?yàn)?More 和切斷功能不應(yīng)該在展開文章內(nèi)容中存在, 響應(yīng)處理可以變得很簡(jiǎn)單. 我們要做的事就這么幾個(gè):
1. 做出 action 對(duì)應(yīng)的接口
2. 獲取指定文章的內(nèi)容
3. 格式化文章內(nèi)容
4. 返回文章內(nèi)容
多說無用, 直接上代碼, 加注釋:
function load_post() { // 如果 action ID 是 load_post, 并且傳入的必須參數(shù)存在, 則執(zhí)行響應(yīng)方法 if($_GET['action'] == 'load_post' && $_GET['id'] != '') { $id = $_GET["id"]; $output = ''; // 獲取文章對(duì)象 global $wpdb, $post; $post = $wpdb->get_row($wpdb->prepare("SELECT * FROM $wpdb->posts WHERE ID = %d LIMIT 1", $id)); // 如果指定 ID 的文章存在, 則對(duì)他進(jìn)行格式化 if($post) { $content = $post->post_content; $output = balanceTags($content); $output = wpautop($output); } // 打印文章內(nèi)容并中斷后面的處理 echo $output; die(); } } // 將接口加到 init 中 add_action('init', 'load_post');
- php+ajax實(shí)現(xiàn)文章自動(dòng)保存的方法
- php+ajax+jquery實(shí)現(xiàn)點(diǎn)擊加載更多內(nèi)容
- php+mysql結(jié)合Ajax實(shí)現(xiàn)點(diǎn)贊功能完整實(shí)例
- php AJAX POST的使用實(shí)例代碼
- php基于jquery的ajax技術(shù)傳遞json數(shù)據(jù)簡(jiǎn)單實(shí)例
- PHP+ajax 無刷新刪除數(shù)據(jù)
- php+ajax實(shí)現(xiàn)無刷新分頁(yè)的方法
- PHP中運(yùn)用jQuery的Ajax跨域調(diào)用實(shí)現(xiàn)代碼
- PHP Ajax實(shí)現(xiàn)頁(yè)面無刷新發(fā)表評(píng)論
- PHP+Ajax實(shí)現(xiàn)的博客文章添加類別功能示例
相關(guān)文章
Laravel第三方包報(bào)class not found的解決方法
今天小編就為大家分享一篇Laravel第三方包報(bào)class not found的解決方法,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來看看吧2019-10-10使用PHP連接數(shù)據(jù)庫(kù)_實(shí)現(xiàn)用戶數(shù)據(jù)的增刪改查的整體操作示例
下面小編就為大家?guī)硪黄褂肞HP連接數(shù)據(jù)庫(kù)_實(shí)現(xiàn)用戶數(shù)據(jù)的增刪改查的整體操作示例。小編覺得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧2017-09-09Zend Framework教程之Zend_Layout布局助手詳解
這篇文章主要介紹了Zend Framework教程之Zend_Layout布局助手用法,結(jié)合實(shí)例形式詳細(xì)分析了Layout布局的相關(guān)實(shí)現(xiàn)技巧,需要的朋友可以參考下2016-03-03PHP單例模式是什么 php實(shí)現(xiàn)單例模式的方法
PHP單例模式是什么?這篇文章主要介紹了php實(shí)現(xiàn)單例模式的方法,告訴大家為什么使用單例模式,感興趣的朋友可以參考一下2016-05-05安裝docker和docker-compose實(shí)例詳解
在本篇文章里小編給大家分享的是關(guān)于安裝docker和docker-compose的具體實(shí)例和代碼,需要的朋友們可以學(xué)習(xí)下。2019-07-07實(shí)現(xiàn)WordPress主題側(cè)邊欄切換功能的PHP腳本詳解
這篇文章主要介紹了實(shí)現(xiàn)WordPress主題側(cè)邊欄切換功能的PHP腳本詳解,包括為WordPress主題添加管理選項(xiàng)的方法,需要的朋友可以參考下2015-12-12超詳細(xì)的php用戶注冊(cè)頁(yè)面填寫信息完整實(shí)例(附源碼)
這篇文章主要介紹了一個(gè)超詳細(xì)的php用戶注冊(cè)頁(yè)面填寫信息完整實(shí)例,內(nèi)容包括郵箱自動(dòng)匹配、密碼強(qiáng)度驗(yàn)證以及防止表單重復(fù)等,小編特別喜歡這篇文章,推薦給大家。2015-11-11