Создание одностраничного приложения без фреймворка

  1. Идея
  2. Настройка
  3. Продукты JSON
  4. products.json
  5. index.html
  6. Код JavaScript
  7. script.js
  8. Заключение
  9. Bootstrap Studio

Идея одностраничных приложений (SPA) состоит в том, чтобы создать плавный просмотр, подобный тому, который есть в нативных настольных приложениях. Весь необходимый код для страницы загружается только один раз, и ее содержимое динамически изменяется с помощью JavaScript. Если все сделано правильно, страница не должна перезагружаться, если пользователь не обновляет ее вручную.

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

Примечание. Чтобы запустить этот пример после его загрузки, вам необходим локально работающий веб-сервер, такой как Apache. Наша демонстрационная программа использует AJAX, поэтому она не будет работать, если вы просто дважды щелкнете index.html по соображениям безопасности.

Идея

Мы не будем использовать каркас, но мы будем использовать две библиотеки - jQuery для манипулирования DOM и обработки событий, и Рули для шаблонов. Вы можете легко опустить их, если хотите быть еще более минимальными, но мы будем использовать их для повышения производительности, которое они обеспечивают. Они будут здесь еще долго после того, как хип-клиентские рамки дня будут забыты.

Приложение, которое мы будем создавать, извлекает данные о продукте из файла JSON и отображает его, отображая сетку продуктов с Рули , После начальной загрузки наше приложение останется на том же URL-адресе и будет прослушивать изменения в хэш- части с событием hashchange . Чтобы перемещаться по приложению, мы просто изменим хеш. Это имеет то преимущество, что история браузера будет работать без дополнительных усилий с нашей стороны.

Настройка

Папка нашего проекта

Как вы можете видеть, в нашей папке проекта не так много. У нас есть обычная настройка веб-приложения - файлы HTML, JavaScript и CSS, сопровождаемые файлом products.json с данными о товарах в нашем магазине и папкой с изображениями товаров.

Продукты JSON

Файл .json используется для хранения данных о каждом продукте для нашего SPA. Этот файл может быть легко заменен серверным скриптом для извлечения данных из реальной базы данных.

products.json

[{"id": 1, "name": "Sony Xperia Z3", "price": 899, "specs": {"производитель": "Sony", "хранилище": 16, "os": "Android" , "camera": 15}, "description": "Lorem ipsum dolor sit amet, consitteur adipiscing elit. Nullam tristique ipsum в efficitur pharetra. Maecenas luctus ante в neque maximus, sed viverra sem posuere. Vestibulum lectus nisi, laoreet , feugiat at odio. Etiam eget tellus arcu. "," rating ": 4," image ": {" small ":" /images/sony-xperia-z3.jpg "," large ":" / images / sony- xperia-z3-large.jpg "}}, {" id ": 2," name ":" Iphone 6 "," price ": 899," specs ": {" производитель ":" Apple "," хранилище ": 16, "os": "iOS", "camera": 8}, "description": "Lorem ipsum dolor sit amet, consittetur adipiscing elit. Nullam tristique ipsum в efficitur pharetra. Maecenas luctus ante в neque maximus, sed viverra sem posuere Vestibulum lectus nisi, laoreet vel suscipit nec, feugiat at odio. Etiam eget tellus arcu. "," Rating ": 4," image ": {" small ":" /images/iphone6.jpg "," large ":" / изображения / IP hone6-large.jpg "}}]

HTML

В нашем html-файле у нас есть несколько div, использующих один и тот же класс "page". Это разные страницы (или как они называются в состояниях SPA), которые может показать наше приложение. Однако при загрузке страницы все они скрыты с помощью CSS, и для их отображения требуется JavaScript. Идея состоит в том, что одновременно может быть видна только одна страница, и наш сценарий должен решить, какая она есть.

index.html

<div class = "main-content"> <div class = "all-products page"> <h3> Наши продукты </ h3> <div class = "filters"> <form> Флажки здесь </ form> </ div > <ul class = "products-list"> <script id = "products-template" type = "x-handlebars-template"> {{#each this}} <li data-index = "{{id}} "> <a href="#" class="product-photo"> <img src =" {{image.small}} "height =" 130 "alt =" {{name}} "/> </a> <h2> <a href="#"> {{name}} </a> </ h2> <ul class = "product-description"> <li> <span> Производитель: </ span> {{specs. производитель}} </ li> <li> <span> Хранилище: </ span> {{specs.storage}} ГБ </ li> <li> <span> ОС: </ span> {{specs.os}} </ li> <li> <span> Камера: </ span> {{specs.camera}} Mpx </ li> </ ul> <button> Купить сейчас! </ button> <p class = "product-price "> {{price}} $ </ p> <div class =" highlight "> </ div> </ li> {{/ each}} </ script> </ ul> </ div> <div class = "страница одного продукта"> <div class = "overlay"> </ div> <div class = "preview-large"> <h3> Представление одного продукта </ h3> <img src = "" /> <p> </ p> <span class = "close"> & times; </ span> </ div> </ div> <div class = "error page"> <h3> Sor что-то пошло не так: (</ h3> </ div> </ div>

У нас есть три страницы: все продукты (список продуктов), один продукт (страница отдельного продукта) и ошибка .

Страница всех продуктов состоит из заголовка, формы, содержащей флажки для фильтрации, и тега <ul> с классом «список продуктов». Этот список создается с помощью рулей, используя данные, хранящиеся в products.json, создавая <li> для каждой записи в json. Вот результат:

Продукты

Один продукт используется для отображения информации только об одном продукте. Он пуст и скрыт при загрузке страницы. Когда соответствующий хеш-адрес достигнут, он заполняется данными о продукте и показывается.

Страница ошибок состоит только из сообщения об ошибке, которое сообщит вам, когда вы достигли ошибочного адреса.

Код JavaScript

Во-первых, давайте сделаем быстрый предварительный просмотр функций и того, что они делают.

script.js

$ (function () {checkboxes.click (function () {// Флажки в нашем приложении служат для фильтров. // Здесь при каждом щелчке мы добавляем или удаляем критерии фильтрации из объекта фильтров. // Затем мы вызываем это функция, которая записывает критерии фильтрации в хэш URL. createQueryHash (filters);}); $ .getJSON ("products.json", function (data) {// Получить данные о наших продуктах из products.json. // Вызов функция, которая преобразует эти данные в HTML. generateAllProductsHTML (data); // Вручную инициировать хэш-обмен для запуска приложения. $ (window) .trigger ('hashchange');}); $ (window) .on ('hashchange' , function () {// При каждом изменении хеша функция рендеринга вызывается с новым хешем. // Так происходит навигация нашего приложения. render (decodeURI (window.location.hash));}); функция render (url) {// Эта функция решает, какой тип страницы отображать //, в зависимости от текущего значения хеша URL.} function generateAllProductsHTML (data) {// Использует Handlebars для создания списка продуктов с использованием пр. Овидимые данные. // Эта функция вызывается только один раз при загрузке страницы. } function renderProductsPage (data) {// Скрывает и показывает продукты на странице «Все продукты» в зависимости от полученных данных. } function renderSingleProductPage (index, data) {// Показывает страницу отдельного продукта с соответствующими данными. } function renderFilterResults (filters, products) {// Создает объект с отфильтрованными продуктами и передает его в renderProductsPage. renderProductsPage (результаты); } function renderErrorPage () {// Показывает страницу ошибки. } function createQueryHash (filters) {// Получить объект фильтров, превратить его в строку и записать в хеш. }});

Помните, что концепция SPA заключается в том, чтобы во время работы приложения не происходило никаких нагрузок. Вот почему после начальной загрузки страницы мы хотим остаться на той же странице, где все, что нам нужно, уже получено сервером.

Однако мы все еще хотим иметь возможность пойти куда-нибудь в приложении и, например, скопировать URL-адрес и отправить его другу. Если мы никогда не изменим адрес приложения, они просто получат приложение так, как оно выглядит в начале, а не то, что вы хотели бы поделиться с ними. Чтобы решить эту проблему, мы записываем информацию о состоянии приложения в URL как #hash. Хэши не приводят к перезагрузке страницы и легко доступны и управляются.

На каждом hashchange мы называем это:

function render (url) {// Получить ключевое слово из URL. var temp = url.split ('/') [0]; // Скрыть ту страницу, которая отображается в данный момент. $ ('. main-content .page'). removeClass ('visible'); var map = {// Домашняя страница. '': function () {// Очистить объект фильтров, снять все флажки, показать все продукты filters = {}; checkboxes.prop ( 'проверено', ложь); renderProductsPage (продукции); }, // Страница отдельных продуктов. '#product': function () {// Получить индекс продукта, который мы хотим показать, и вызвать соответствующую функцию. var index = url.split ('# product /') [1] .trim (); renderSingleProductPage (индекс, продукты); }, // Страница с отфильтрованными продуктами '#filter': function () {// Захватить строку после ключевого слова # filter /. Вызовите функцию фильтрации. url = url.split ('# filter /') [1] .trim (); // Попробуем разобрать объект filters из строки запроса. try {filters = JSON.parse (url); } // Если это не правильный json, вернитесь на домашнюю страницу (остальная часть кода не будет выполнена). catch (err) {window.location.hash = '#'; } renderFilterResults (фильтры, продукты); }}; // Выполнить нужную функцию в зависимости от ключевого слова url (хранится в temp). if (map [temp]) {map [temp] (); } // Если ключевое слово не указано выше - отобразить страницу с ошибкой. else {renderErrorPage (); }}

Эта функция учитывает начальную строку нашего хэша, решает, какую страницу нужно показать, и вызывает соответствующие функции.

Например, если хеш равен '#filter / {"storage": ["16"], "camera": ["5"]}', наше кодовое слово будет #filter. Теперь функция рендера знает, что мы хотим видеть страницу со списком отфильтрованных продуктов, и перейдет к ней. Остальная часть хэша будет проанализирована в объекте, и будет показана страница с отфильтрованными продуктами, что приведет к изменению состояния приложения.

Это вызывается только один раз при запуске и превращает наш JSON в реальный контент HTML5 с помощью руля.

function generateAllProductsHTML (data) {var list = $ ('. all-products .products-list'); var theTemplateScript = $ ("# products-template"). html (); // Скомпилируем шаблон var theTemplate = Handlebars.compile (theTemplateScript); list.append (шаблон (данные)); // Каждый продукт имеет атрибут data-index. // При нажатии изменить URL-хэш, чтобы открыть предварительный просмотр только для этого продукта. // Помните: каждый hashchange вызывает функцию рендеринга. list.find ('li'). on ('click', function (e) {e.preventDefault (); var productIndex = $ (this) .data ('index'); window.location.hash = 'product / '+ productIndex;})}

Эта функция получает объект, содержащий только те продукты, которые мы хотим показать, и отображает их.

function renderProductsPage (data) {var page = $ ('. all-products'), allProducts = $ ('. all-products .products-list> li'); // Скрыть все товары в списке товаров. allProducts.addClass ( 'скрытый'); // Перебирать все продукты. // Если их идентификатор где-то в объекте данных, удалите скрытый класс, чтобы показать их. allProducts.each (function () {var that = $ (this); data.forEach (function (item) {if (that.data ('index') == item.id) {that.removeClass ('hidden') ;}});}); // Показать саму страницу. // (функция рендеринга скрывает все страницы, поэтому нам нужно показать ту, которую мы хотим). page.addClass ( 'видимого'); }

Показывает одну страницу предварительного просмотра продукта:

function renderSingleProductPage (index, data) {var page = $ ('. single-product'), container = $ ('. preview-large'); // Найти нужный продукт путем итерации объекта данных и поиска выбранного индекса. if (data.length) {data.forEach (function (item) {if (item.id == index) {// Заполните «.preview-large» данными выбранного продукта. container.find ('h3'). text (item.name); container.find ('img'). attr ('src', item.image.large); container.find ('p'). text (item.description);}}); } // Показать страницу. page.addClass ( 'видимого'); }

Принимает все продукты, фильтрует их по нашему запросу и возвращает объект с результатами.

function renderFilterResults (filters, products) {// Этот массив содержит все возможные критерии фильтрации. критерий var = [«производитель», «хранилище», «ОС», «камера»], результаты = [], isFiltered = false; // Снимите все флажки. // Мы будем проверять их снова один за другим. checkboxes.prop ('флажок', ложь); crit.forEach (function (c) {// Проверить, присутствует ли каждый из возможных критериев фильтра в объекте фильтров. if (filters [c] && filters [c] .length) {// После того, как мы отфильтровали продукты однажды мы хотим продолжать их фильтровать. // Поэтому мы делаем объект, в котором мы ищем (products), равным результату. // Затем массив результатов очищается, поэтому он может быть заполнен вновь отфильтрованными данными. . if (isFiltered) {products = results; results = [];} // В этих вложенных циклах for мы будем перебирать фильтры и продукты // и проверять, содержат ли они одинаковые значения (те, которые мы фильтруем by). // Перебирать записи внутри filters.criteria (помните, что каждый критерий содержит массив). filters [c] .forEach (function (filter) {// Перебирать продукты. products.forEach (function (item) { // Если продукт имеет то же значение спецификации, что и значение в фильтре, // помещаем его в массив результатов и помечаем флаг isFiltered true. If (typeof item.specs [c] == 'number') {if (item.specs [c] == фильтр) {results.push (item); isFiltered = true; }} if (typeof item.specs [c] == 'string') {if (item.specs [c] .toLowerCase (). indexOf (filter)! = -1) {results.push (item); isFiltered = true; }}}); // Здесь мы можем сделать флажки, представляющие фильтры, истинными, // поддерживая приложение в актуальном состоянии. if (c && filter) {$ ('input [name =' + c + '] [value =' + filter + ']'). prop ('checked', true); }}); }}); // Вызвать renderProductsPage. // В качестве аргумента передаем объект с отфильтрованными продуктами. renderProductsPage (результаты); }

Показывает состояние ошибки:

function renderErrorPage () {var page = $ ('. error'); page.addClass ( 'видимого'); }

Стригирует объект фильтра и записывает его в хеш.

function createQueryHash (filters) {// Здесь мы проверяем, не являются ли фильтры пустыми. if (! $. isEmptyObject (filters)) {// Stringify объект через JSON.stringify и запишите его после ключевого слова '#filter'. window.location.hash = '# filter /' + JSON.stringify (filters); } else {// Если оно пустое, измените хеш на '#' (домашняя страница). window.location.hash = '#'; }}

Заключение

Одностраничные приложения идеальны, когда вы хотите придать своему проекту более динамичный и плавный вид, а с помощью некоторых умных дизайнерских решений вы можете предложить своим посетителям приятный и приятный опыт.

Bootstrap Studio

Революционный инструмент веб-дизайна для создания адаптивных веб-сайтов и приложений.

Учить больше

Похожие

Удалить тату больше не навязчивая идея
Удаление татуировок является проблемой, учитывая метод удаления без рубцов или осложнений; а также цена, которая подходит для каждого человека. Причиной удаления татуировки, в дополнение к рабочей среде, жизни, может также быть связано с татуировкой, цвет татуировки, когда татуировка не соответствует требованиям клиента, или клиент не удовлетворен, хотят изменить. Кроме того, для тех, кто хочет экспортировать рабочую силу, удаление татуировок без рубцов уже не просто необходимость, но и требование.
▷ Visual SEO Studio Полное руководство
... HTML-код ресурса; DOM: возвращает DOM ресурса; Миниатюра: позволяет сделать миниатюру отсканированной страницы. Приведенный ниже экран позволяет легко находить ошибки: Http-аномалии: указывает на количество аномалий и показывает ошибки и / или предупреждения; Элементы не посещены: указывает на то, что страницы не отсканированы; Результаты поиска: отобразить результаты функции «Поиск страниц» Ссылка на страницу: внутренние и внешние
SEO для Angular JS: ключи для индексации // Smartbrand
... script, который фокусируется на том, что мы сказали, чтобы получить лучший пользовательский опыт, особенно для мобильных устройств. Однако, хотя он частично поддерживается Google, очень легко допустить ошибки при разработке веб-сайтов Angular, и не все содержимое вашего сайта проиндексировано. Причина, по которой это происходит, именно из-за самой природы этих событий. Javascript полезен для динамического контента, но какой из них будет индексировать поисковую систему, а какой нет?
HTML & CSS: что нужно знать SEO?
... кода им действительно нужно знать, чтобы стать SEO-аналитиком. И угадай что? Вам действительно не нужно знать много кода, чтобы быть SEO-аналитиком. НО, вы станете в миллиард раз лучше в своей работе, приложив усилия, чтобы понять, что такое HTML, CSS и JavaScript и как каждый из них интерпретируется поисковыми системами. Вам не нужно быть веб-разработчиком или даже свободно говорить на каком-либо языке программирования, чтобы быть хорошим SEO-аналитиком;
Октябрь CMS против Wordpress
... JavaScript можно комбинировать и минимизировать с помощью всего одного тега в шаблонах CMS. Механизм заманчивости Twig генерирует статические html-страницы на внешнем интерфейсе, и нет ничего быстрее плоского html, поэтому время отклика мгновенно. Можно сравнительно легко набрать более 90 баллов Google PageSpeed. Wordpress руководство говорится, что: «Первый и самый простой способ
Друпал против WordPress
Каждая CMS имеет уникальные черты, которые подходят вашей компании Если вы не знакомы с система управления контентом это веб-приложение, которое помогает создавать и редактировать контент на веб-сайтах. Двумя основными игроками в индустрии CMS являются WordPress и Drupal
Как создать список ключевых слов электронной коммерции
Ключевые слова являются важным строительным блоком для маркетинга электронной коммерции. Разработка и ведение списка ключевых слов может помочь бизнесу электронной коммерции понять покупателей и лучше их продвигать. В контексте поисковой оптимизации, слова или фразы искателей обобщать намерение - мысли, вопросы или потребности искателей. Эти ключевые слова представляют язык, на
WP SEO HTML Карта сайта - WordPress плагін
Если вы используете WordPress SEO by Yoast Plugin в качестве основного SEO-плагина, вы, возможно, заметили, что у них нет функции HTML-карты сайта. Этот плагин является ответом на эту проблему. Особенности включают Автоматически использует все настройки XML Sitemap из популярного SEO WordPress от Yoast Plugin Выберите, сколько столбцов вы хотите отобразить Столбцы имеют кладочный эффект и совместимы со всеми современными браузерами.
SEO Company - Агентство Северной Каролины
Северная Каролина - государство, которое приветствовало много новых предприятий за последние несколько лет. Экономика сильна, и жители воспользовались возможностью, чтобы воплотить в жизнь свою мечту о владении бизнесом. Первый шаг в ведении успешного бизнеса в Северной Каролине - это исчерпать все усилия по маркетингу в местном сообществе. Это означает, что у компании есть реклама в печатных материалах,
Создание SEO дружественных партнерских ссылок в три этапа
Партнерские ссылки - полезный инструмент для онлайн-рекламодателей, желающих получить немного дополнительного трафика. По сути, вы будете ставить ссылка на ваш сайт или целевую страницу на веб-сайте или домене партнера. Вы получите дополнительный трафик в обмен на небольшую плату, обычно фиксированную сумму за клик. Если вы знакомы с рекламой Google с платой за клик (PPC), вы уже знаете, что такое партнерский маркетинг - традиционные
кредиты
Студия Cappello: стратегии успеха с 2001 года Studio Cappello - одно из самых известных агентств веб-маркетинга в Италии, которое с 2001 года специализируется на создании веб-сайтов, оптимизированных для поисковых систем и призванных предложить вашим пользователям лучший опыт просмотра. В студии Cappello мы тесно сотрудничаем с клиентом, чтобы понять и определить его бизнес-цели и дизайн интерфейсов и контента с высокой степенью конверсии. 360 ° продвижение для вашего

Комментарии

Или разработка мобильного приложения?
... код, обновление плагинов в WordPress или установка новых, просто. Однако, когда вы работаете дома, вам часто приходится полагаться на другие отделы, чтобы выполнять работу, и это может быть не так просто, как кажется. Даже самые незначительные изменения могут занять несколько дней, вам нужно получить поддержку от других отделов и сотрудников и подождать, пока они не назначат вас в свою работу. Годовая SEO стратегия?
Com/products/women?
com/products/women?category=dresses&color=green http://yoursite.com/shop/index. PHP? product_id = 32 & изюминка = зеленый + платье & cat_id = 1 & SessionID = 123 & affid = 431 Поисковые системы решают, какой из этих URL-адресов отображать в результатах поиска. Они могут выбрать третий URL, который не является чистым, и если такой URL отображается в результатах поиска, он может получить не столько кликов, сколько чистый URL. Чтобы избежать этого, вы можете сделать один
Visibility_index?
visibility_index?api_key=XXX&url="; A2; "" ";" // @ value "") ")] Конечно БЕЗ квадратных скобок. Значение «A2» является ссылкой на ячейку в первом столбце и второй строке и дополняет URL-адрес в запросе. Итак, мы во второй строке. Вместо «XXX» вы создаете свой ключ API от Sistrix. И не удивляйтесь двойным кавычкам - для этого нужен Excel ... Двойной щелчок на маленьком плюсе в левом нижнем углу отмеченной ячейки «B2» завершает все ячейки, рядом с которыми есть URL
Является ли ваш сайт местом, где можно «открывать для себя новые игрушки и игры» или находить продукты с «передовыми технологиями»?
Является ли ваш сайт местом, где можно «открывать для себя новые игрушки и игры» или находить продукты с «передовыми технологиями»? Вы можете попросить друзей или деловых партнеров помочь вам придумать лучшие фразы, чтобы описать, что ваш бизнес электронной коммерции. Вы также можете провести фокус-группу с представителями ваших основных групп клиентов. Соберите эти ключевые фразы в первоначальный список. Продукты и Категории Далее добавьте в свой список
Кто знает ваши продукты и рынок лучше, чем вы?
Кто знает ваши продукты и рынок лучше, чем вы? «Поверь себе. Ты знаешь больше, чем думаешь». - Бенджамин Спок «Вас окружают простые, очевидные решения, которые могут значительно увеличить ваш доход, власть, влияние и успех. Проблема в том, ВЫ просто их не видите . "- Джей Абрахам Поверьте, вы можете продвигать свои сайты намного лучше, чем любой специалист по SEO и интернет-маркетингу. Единственное, чего вам не хватает - это знания о том,
Вы блокируете сканирование файлов CSS и JS своего сайта?
Вы блокируете сканирование файлов CSS и JS своего сайта? Если так, вот почему ты не должен , Вы можете увидеть это в Google Search Console. Нерабочие ссылки или ошибки сканирования веб-страниц в ключевых точках доступа. Есть ли у вашего сайта неработающие ссылки в ключевых точках доступа, таких как основная или дополнительная навигация? Вы можете проверить это в Screaming Frog, Deep Crawl или в консоли поиска Google.
Насколько дорогой будет настройка генерации трафика через каждую маркетинговую среду?
Насколько дорогой будет настройка генерации трафика через каждую маркетинговую среду? После того, как конкретный консультант по цифровому маркетингу определил, какие каналы лучше всего использовать, он должен рассмотреть его с точки зрения бюджета. Например, если целевой аудиторией в основном являются профессионалы B2B, они, вероятно, будут рассматривать LinkedIn в качестве подходящего канала. Тем не мение,
Аутсорсинг или заключение договоров?
Аутсорсинг или заключение договоров? Многие компании сталкиваются с вопросом о том, могут ли они лучше привлекать сторонних специалистов к поисковой оптимизации или выполнять их лучше со стороны внутреннего специалиста. На практике это в основном зависит от размера компании и степени, в которой внимание уделяется SEO. В настоящее время вы можете сделать это по очень привлекательной цене аутсорсинг социальных сетей
JA и JP: какой код следует использовать для обозначения Японии как страны, а какой для японского как языка?
JA и JP: какой код следует использовать для обозначения Японии как страны, а какой для японского как языка? Значения Hreflang требуют постоянной повторной проверки, чтобы избежать ошибок, и вот здесь пригодится отчет International SEO. Мы найдем и покажем вам все ошибки, связанные с язык а также страна коды и подчеркивания используются вместо
Что такое HTML?
Что такое HTML? HTML, или язык разметки гипертекста , можно рассматривать как каркас веб-сайта. Это код, который содержит контент и метаинформацию, которую поисковые системы используют, чтобы понять, о чем сайт. Веб-сайт, написанный на чистом HTML, не будет выглядеть так здорово, но он будет молниеносным, вероятно, оптимизированным для обычного поиска и адаптивным (оптимизированным для мобильных устройств). Например, музыкант Vulfpeck-х Сайт
Html?
html?category=2 og: site_name Название вашего сайта. Это не означает, что ваше доменное имя, хотя оба могут быть одинаковыми. Как пример, Facebook, а не facebook.com. Ниже приведены подробные инструкции по их добавлению на ваш сайт, а также пример для подражания. Карты Твиттера Карты Твиттера означают, что когда кто-то пишет в Твиттере ссылку на ваш

Javascript полезен для динамического контента, но какой из них будет индексировать поисковую систему, а какой нет?
HTML & CSS: что нужно знать SEO?
И угадай что?
Годовая SEO стратегия?
Com/products/women?
Com/products/women?
PHP?
Visibility_index?
Является ли ваш сайт местом, где можно «открывать для себя новые игрушки и игры» или находить продукты с «передовыми технологиями»?
Кто знает ваши продукты и рынок лучше, чем вы?

ГОРЯЧАЯ ЛИНИЯ

(062) 348 60 00
(095) 210 57 42

Дед Мороз в офис Донецк

Дед Мороз на детском утреннике Донецк

Дед Мороз на дом Донецк

Новости

Телеканал Юнион в гостях у Морозко

Последние записи