Динамическое обновление и смена контента при переходе по URL без перезагрузки страницы сайта HTML5, JavaScript, PHP, jQuery

Как при переходе по странице сайта динамически обновить контент на странице, без перезагрузки сайта, используя HTML5, JavaScript, PHP, jQuery

Динамическое обновление и смена контента при переходе по URL без перезагрузки страницы сайта HTML5, JavaScript, PHP, jQuery
4 месяца назад

Динамическое обновление и смена контента при переходе по URL без перезагрузки страницы сайта HTML5, JavaScript, PHP, jQuery

Современные тенденции и подходы в веб-разработке открывают новые возможности использования динамики переходов по URL – без перезагрузки страниц. Данный способ, заключается в создании алгоритма, при котором пользователь, просматривая сайт не обновляет страницу целиком, а подгружает лишь некоторые её части и блоки, что значительно увеличивает скорость загрузки сайта и зрительно способствует лучшему восприятию.

В свою бытность подобные задачи, реализовывались посредством использования фреймов, однако пользователи переходя по ссылкам, перемещались по страницам скачкообразно, нарушая видимое место перехода, которое надо было снова искать. Зрительно это выглядело не совсем красиво, да и URL адрес основного фрейма никак не менялся, оставался прежним. Скопировать такую ссылку было нельзя.

В данной статье мы поговорим о том, как используя HTML5, JavaScript, PHP и jQuery реализовать динамическую подгрузку контента, со сменой URL, при этом не перезагружая страницу сайта целиком.

А теперь давайте приступим! Создадим и откроем файл index.php и пропишем туда нужную нам разметку:
cont.php
<?php
    include("class.php");
?>
<!doctype html>
<html lang="ru">
<head>

<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<meta http-equiv="x-ua-compatible" content="ie=edge">
<meta name=viewport content="width=device-width, initial-scale=1"> 

<link rel="stylesheet" href="style.css" type="text/css" media="screen">

<script src="jquery-3.2.1.min.js"></script>
<script src="history.js"></script>
<script src="document.js"></script>

<title><?php echo $data->title(); ?></title>
</head>
<body>

<div id="footer-l">
    <div id="page-l">
    <div id="logo">logo</div>
    <nav><ul class="nav"><?php echo $data->menu(); ?></ul></nav>
    </div>
</div>

<div id="footer-r">
    <div class="content"><?php echo($data->content($data->state(),$data->title())); ?></div>
</div>

</body>
</html>
В представленном коде как мы видим ничего сложного нет, в файле index.php содержится в основном html-разметка страницы.

$data->title() – вывоз функции названия страницы

$data->menu() – меню сайта

$data->content() – вывод основного содержимого блока content

А теперь создадим и откроем файл class.php и пропишем:
class.php
<?php

$menu = array(
    '1' => array("name" => "Главная", "page" => "./"),
    '2' => array("name" => "О нас", "page" => "./about"),
    '3' => array("name" => "Контакты", "page" => "./contacts")
);

class load_page_vars {

    function title(){

        global $menu;
        $item = $menu;

        $str = '';
        $i=0;
        foreach($item as $k => $value)
        {
            $i++;
            if($item[$i]["page"] == ".".$this->state())
            {
                return $item[$i]["name"];
            }        
        }
    }

    function menu(){

        global $menu;

        $str = '';
        $i=0;
        foreach($menu as $k => $value)
        {
            $i++;
            $str.= "<li><a href='".$menu[$i]["page"]."' ".($menu[$i]["page"] == ".".$this->state() ? 'class="selected"' : '')." title='".$menu[$i]["name"]."'>".$menu[$i]["name"]."</a></li>";
        }
        //$this->state($page_title);
        return $str;
    }



    function content($page, $name){

        $post = array(
            'page' => ".".$page,
            'name' => $name,
            'password' => 'bar',
            'submit' => TRUE,
        );
         
        $data = http_build_query($post);

        $opts = array(
                  'http' => array(
                      'method' => 'POST',
                      'header' => "Content-type: application/x-www-form-urlencoded\r\nContent-Length: " . strlen($data) . "\r\n",
                      'content' => $data,
                  )
               );

        $context  = stream_context_create($opts);

        $url = $this->siteURL()."/content.php";
        $content = file_get_contents($url,FALSE,$context);

        return $content;
    }

    function state() {
        $request = substr($_SERVER['PHP_SELF'], 0, strrpos($_SERVER['PHP_SELF'], '/'));
        $str_repl = str_replace($request, '', $_SERVER['REQUEST_URI']);
        return $str_repl;
    }

    function siteURL()
    {
        if (isset($_SERVER['HTTPS']) &&
            ($_SERVER['HTTPS'] == 'on' || $_SERVER['HTTPS'] == 1) ||
            isset($_SERVER['HTTP_X_FORWARDED_PROTO']) &&
            $_SERVER['HTTP_X_FORWARDED_PROTO'] == 'https') {
          $protocol = 'https://';
        }
        else {
          $protocol = 'http://';
        }

        $siteUrl = $protocol.$_SERVER["HTTP_HOST"].$_SERVER["PHP_SELF"];

        return dirname($siteUrl);

    }

}

$data = new load_page_vars();



?>
В class.php содержатся функции, отвечающие за вывод названия страницы, меню, контент
document.js
window.onload = function() {

    function reAnswer(state, title){
        $.ajax ({
            url: "content.php",
            type: "POST",
            data: {page: state, name:title},
            success: function (result) { $(".content").html(result);
             }
        });
    }

    function handlerAnchors() {
        $("ul.nav li a").removeClass('selected');
        $(this).addClass('selected');

        var state = {
            title: this.getAttribute( "title" ),
            url: this.getAttribute( "href", 2 )
        }

        history.pushState( state, state.title, state.url );
        document.title = state.title;
        reAnswer(state.url, state.title);

        return false;
    }

    var anchors = document.getElementsByTagName( 'a' );
    for( var i = 0; i < anchors.length; i++ ) {
        anchors[ i ].onclick = handlerAnchors;
    }

     window.onpopstate = function( e ) {
         $("ul.nav li a").removeClass('selected');
         $('ul.nav li a[href$="' + history.state.url + '"]').addClass('selected');
         document.title = history.state.title;
         reAnswer(history.state.url, history.state.title);
    }
}
Функция reAnswer отправляет файлу content.php POST массив с данными нужной нам страницы. При успешной отправки и получении данных, функция success, выводит в блок .content описание страницы, согласно введенному URL адресу.

Функция handlerAnchors вызывается при клике и смене адреса страницы. Она содержит массив state, в который записываются адреса и названия посещенных страниц.

history.pushState записывает в историю браузера адреса страниц, которые позволяют пользователям использовать браузерную кнопку назад.

Для наиболее лучшего восприятия, добавим немного стилизации.
style.css
@import url('https://fonts.googleapis.com/css?family=Open+Sans|Roboto');

html, body {
    height: 100%;
}

body {
    color: #4f4f5a;
    font-family: 'Roboto', sans-serif;
    font-size: 16px;
    padding: 0;
    margin: 0;
}

.nav {
    margin-top: 50px;
    padding: 0;
}
.nav:after {
    content: "."; 
    display: block;
    height: 0; 
    clear: both; 
    visibility: hidden;
}

.nav li {
    margin: 0 10px 0 0;
    padding: 0;
    list-style: none;
}

.nav li a {
    padding: 10px 15px;
    margin: 3px 0;
    display: table;
    color: #000;
    font-size: 18px;
    text-decoration: none;
}

.nav a:hover {
    background: #f6f6f6;
    -webkit-border-radius: 2px;
    -moz-border-radius: 2px;
    border-radius: 2px;  
}

.nav a:focus {
    outline: none;
}

.nav .selected {
    background: #f6f6f6;
    color: #000;
    text-decoration: none;
    -webkit-border-radius: 2px;
    -moz-border-radius: 2px;
    border-radius: 2px;
}

.content {
    width: calc(100% - 180px);
    margin: 70px 70px 70px auto;
    padding: 20px;
    height: 300px;
    overflow: auto;
    border: 1px solid #f3f3f3;
    background: #FFF;
    color: #000;
}

.content p {
    margin: 0 0 10px;
}

#page-l {
    padding: 30px;
}

#logo {
    display: table;
    margin: 20px 0;
    background: #f66035;
    color: #fff;
    font-weight: bold;
    padding: 5px;
    font-size: 26px;
    -webkit-border-radius: 2px;
    -moz-border-radius: 2px;
    border-radius: 2px;
}

#footer-l {
    float: left;
    width: 300px;
    height: 100%;
    background: #fff;
    -webkit-box-shadow: -6px 0px 15px 0px rgba(0,0,0,0.75);
    -moz-box-shadow: -6px 0px 15px 0px rgba(0,0,0,0.75);
    box-shadow: -6px 0px 15px 0px rgba(0,0,0,0.75);
}

#footer-r {
    float: left;
    width: calc(100% - 302px);

}

#footer-r:after {
    display : table;
    content : " ";
    clear : both;
}

@media (max-width:550px) {
#footer-l, #footer-r {
    width: 100%;
}
#footer-l {
    #border: 0 none;
    height: auto;
}
.content {
    width: calc(100% - 40px);
    margin: 0;
    border: 0 none;
}
}
content.php
<?php

switch ($_POST["page"]) {
    case "./":
        echo "<h1>".$_POST["name"]."</h1>";
        echo "<p>Текст...</p>";
    break;

    case "./about":
        echo "<h1>".$_POST["name"]."</h1>";
        echo "<p>Текст...</p>";
    break;

    case "./contacts":
        echo "<h1>".$_POST["name"]."</h1>";
        echo "<p>Текст...</p>";
    break;
}

?>
В файл content.php посредством POST запроса отправляется массив, согласно которому switch выводит нужную нам информацию на страницу.
.htaccess
<IfModule mod_rewrite.c>

# Enables mod_rewrite
RewriteEngine on

RewriteCond %{THE_REQUEST} ^[A-Z]{3,9}\ /(.*)index\.php($|\ |\?)
RewriteRule ^ /%1 [R=301,L]

# Sets the base folder of the State sample
RewriteBase  /webdevelopment/dynamic-page

RewriteCond  %{REQUEST_FILENAME}    !-f
RewriteCond  %{REQUEST_FILENAME}    !-d
RewriteRule  .* index.php

</IfModule>
621
Демо
Комментарии
  • Arlo 3 недели назад
    Thank you very much, this is the best version of the code.
    Ответить