Выпадающее меню в WordPress

В мобильной версии темы WordPress Twenty Fifteen сайдбар используется в виде выпадающего меню, которое отображается при нажатии на кнопку. Чтобы показать или скрыть меню используется JavaScript, который в свою очередь использует библиотеку jQuery.

Как я уже писал раньше, я поставил себе цель полностью выпилить jQuery из стандартной темы оформления Twenty Fifteen. Сначала перенес на CSS спойлер, который ранее работал на JavaScript и jQuery. И вот сейчас руки дошли до выпадающего меню в WordPress.

Для начала нужно полностью отключить загрузку jQuery, добавьте в файл в functions.php:

function wpdocs_dequeue_script() {
    wp_dequeue_style('jquery');
    wp_deregister_script('jquery');
}
add_action( 'wp_print_scripts', 'wpdocs_dequeue_script' );

Чтобы показать или скрыть выпадающее меню при нажатии на кнопку, добавьте JavaScript ниже в файл footer.php:

<script type="text/javascript">
    var dropdownButton = document.getElementById("dropdown"),
    dropdownDiv = document.getElementById("secondary");

    dropdownButton.addEventListener("click", function () {
        dropdownButton.classList.toggle("toggled-on");
        dropdownDiv.classList.toggle("toggled-on");

    if (dropdownButton.getAttribute("aria-expanded") == 'false') {
        dropdownButton.setAttribute("aria-expanded", "true");
        dropdownDiv.setAttribute("aria-expanded", "true");
    }
    else {
        dropdownButton.setAttribute("aria-expanded", "false");
        dropdownDiv.setAttribute("aria-expanded", "false");
    }
});
</script>

Преимущества данного скрипта — нет необходимости подгружать jQuery. К недостаткам можно отнести то, что данный скрипт не работает в Opera Mini по причине отсутствия поддержки classList. Возможно, в будущем перепишу выпадающее меню на CSS, но сейчас не хочу заморачиваться.

JavaScript класс элемента

В этой записи я расскажу как с помощью JavaScript добавить или изменить атрибут class для элементов страницы. Часто этот метод используют для создания динамических элементов страницы. Чтобы в JavaScrip добавить, удалить, переключить или проверить класс элемента используют методы, которые содержит свойство classList:

  • classList.add
  • classList.remove
  • classList.toggle
  • classList.contains
  • classList.length
  • classList.item

Добавить класс

classList.add — добавить класс элемента.

Синтаксис:

element.classList.add(name);
  • name — имя класса.

В примере я использую метод classList.add чтобы добавить класс style для для элемента <div>:

<div id="div1">Hello World</div>

<script>
var div1 = document.getElementById("div1");
div1.classList.add("style");
</script>

Удалить класс

classList.remove — удалить класс элемента.

Синтаксис:

element.classList.remove(name);
  • name — имя класса.

В примере я использую метод classList.remove чтобы удалить класс style для для элемента <div>:

<div id="div1" class="style">Hello World</div>

<script>
var div1 = document.getElementById("div1");
div1.classList.remove("style");
</script>

Переключить класс

classList.toggle — добавить имя класса, если его нет, или удалить, если он есть.

Синтаксис:

element.classList.toggle(name);
  • name — имя класса.

В примере я использую метод classList.toggle чтобы добавить класс style для для элемента <div>:

<div id="div1">Hello World</div>

<script>
var div1 = document.getElementById("div1");
div1.classList.toggle("style");
</script>

Или удалить класс style, если он есть:

<div id="div1" class="style">Hello World</div>

<script>
var div1 = document.getElementById("div1");
div1.classList.toggle("style");
</script>

Проверить наличие класса

classList.contains — возвращает логическое значение, указывающее, имеет ли элемент указанный класс или нет.

Синтаксис:

element.classList.contains(name);
  • name — имя класса.

В примере я использую метод classList.contains чтобы добавить класс style для для элемента <div>:

<div id="div1" class="style">Hello World</div>

<script>
var div1 = document.getElementById("div1");
alert(div1.classList.contains("style"));
</script>

Количество классов

classList.length — возвращает количество классов в элементе.

Синтаксис:

element.classList.length;

В примере я использую метод classList.length чтобы получить количество классов для для элемента <div>:

<div id="div1" class="style1 style2">Hello World</div>

<script>
var div1 = document.getElementById("div1");
alert(div1.classList.length);
</script>

Узнать имя класса

classList.item — возвращает имя класса по его порядковому номеру.

Синтаксис:

element.classList.item(number);
  • number — порядковый номер класса.

В примере я использую метод classList.item чтобы получить имя класса по его порядковому:

<div id="div1" class="style1 style2">Hello World</div>

<script>
var div1 = document.getElementById("div1");
alert(div1.classList.item(0));
</script>

JavaScript атрибут элемента

В данной записи я расскажу как с помощью JavaScript добавить, удалить, изменить и получить значение атрибута элемента. В JavaScript для работы с атрибутами существуют следующие функции:

  • setAttribute
  • getAttribute
  • hasAttribute
  • removeAttribute

Добавить или изменить атрибут

setAttribute — функция добавляет новый атрибут или изменяет значение существующего атрибута по указанному элементу.

Синтаксис функции:

element.setAttribute(name, value);
  • name — задает имя атрибута.
  • value — указывает новое значение атрибута.

В примере я использую функцию setAttribute чтобы добавить атрибут disabled для элемента <button>:

<button id="btn">Hello World</button>

<script>
var b = document.querySelector("#btn");
b.setAttribute("disabled", "disabled");
</script>

Получить значение атрибута

getAttribute — функция вернет значение указанного атрибута элемента.

Синтаксис функции:

var attribute = element.getAttribute(attributeName);
  • attribute — строка содержащая значение атрибута.
  • attributeName — имя атрибута, значение которого вы хотите получить.

В примере я использую функцию getAttribute чтобы получить значение атрибута элемента <div>:

<div id="div1" align="center">Hello World</div>

<script>
var div1 = document.getElementById("div1");
var align = div1.getAttribute("align");

alert(align);
</script>

Проверить наличие атрибута

hasAttribute — метод возвращает логическое значение, указывающее, имеет ли элемент указанный атрибут или нет.

Синтаксис функции:

var result = element.hasAttribute(attName);
  • result — значение true или false.
  • AttName — задает имя атрибута.

В примере я использую функцию hasAttribute чтобы проверить наличие атрибута align="center" для элемента <div>:

<div id="div1" align="center">Hello World</div>

<script>
var d = document.getElementById("div1");

if (d.hasAttribute("align")) {
    alert("align center");
}
</script>

Удалить атрибут

removeAttribute — удаляет атрибут из указанного элемента.

Синтаксис функции:

element.removeAttribute(attrName);
  • attrName — строка с именем атрибута, который нужно удалить.

В примере я использую функцию removeAttribute чтобы удалить атрибут align="center" для элемента <div>:

<div id="div1" align="center">Hello World</div>

<script>
document.getElementById("div1").removeAttribute("align");
</script>

Удалите код препятствующий отображению

Если вам когда-либо приходилось анализировать свои сайты с помощью сервиса Google PageSpeed Tools, то вы наверняка уже сталкивались с данной рекомендацией: «Удалите код JavaScript, препятствующий отображению».

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

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

Из всего этого можно сделать вывод, что качество технической составляющей сайта, стало одним из факторов ранжирования сайта в поисковой системе Google.

Как удалить код, препятствующий отображению страницы

Перейдем к технической стороне решения вопроса. Чтобы убрать данное предупреждение: «Удалите код JavaScript, препятствующий отображению», нужно убрать подключение скриптов внутри тега <head>, а затем подключить их в низу страницы. Но не спешите слепо выполнять данную рекомендацию.

В зависимости от размера скрипта и его функций, существует следующие рекомендации по размещению JavaScript:

  • скрипты участвующие в процессе отображении страницы необходимо подключать внутри тега <head>;
  • если скрипт не участвует в процессе отображения страницы, необходимо его перенести в страницы;
  • скрипты небольшого размера лучше добавить в содержимое HTML-документа;
  • используйте атрибут async для  асинхронного вызова JavaScript.

Пример асинхронного вызова скрипта:

<script async src="code.js">

Как перенести скрипты в подвал WordPress

У WordPress есть встроенная функция wp_register_script, которая добавляет скрипты в очередь и загружает их при необходимости. Для вывода скрипта в подвале WordPress, необходимо изменить один из параметров вызова данной функции.

Для скриптов, которые необходимо выводить в подвале WordPress, необходимо в файле functions.php добавь параметр true в конец вызова функции wp_register_script.

Формат вызова функции wp_register_script():

wp_register_script( $handle, $src, $deps, $ver, $in_footer );

Для вывода скрипта в подвале WordPress, необходимо установить true в значении параметра $in_footer, как это сделано в примере ниже:

function wpb_adding_scripts() {
    wp_register_script('my-script', get_template_directory_uri() . '/js/my-script.js','','1.0', true);
    wp_enqueue_script('my-script');
}
add_action( 'wp_enqueue_scripts', 'wpb_adding_scripts' );

Как вариант, чтобы разместить скрипт в подвале WordPress, можно выполнить повторную регистрацию JavaScript:

function wpb_adding_scripts() {
    wp_deregister_script('my-script');
    wp_register_script('my-script', get_template_directory_uri() . '/js/my-script.js','','1.0', true);
    wp_enqueue_script('my-script');
}
add_action( 'wp_print_scripts', 'wpb_adding_scripts' );

Если ваши скрипты не участвуют в отображении страницы, можно переместить загрузку всех внешних скриптов в подвал WordPress. Для этого используем функцию ниже:

function footer_enqueue_scripts() {
    # Удаляем JavaScript из заголовка
    remove_action('wp_head', 'wp_print_scripts');
    remove_action('wp_head', 'wp_print_head_scripts', 9);
    remove_action('wp_head', 'wp_enqueue_scripts', 1);
    # Выводим в footer
    add_action('wp_footer', 'wp_print_scripts', 5);
    add_action('wp_footer', 'wp_enqueue_scripts', 5);
    add_action('wp_footer', 'wp_print_head_scripts', 5);
}
add_action('after_setup_theme', 'footer_enqueue_scripts');

JQuery: Открыть ссылку в новом окне

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

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

Чтобы браузер самостоятельно открывал ссылки в новом окне, необходимо использовать специальный атрибут target="_blank". Как быть, если по какой-либо причине, ранее вы не использовали данный атрибут. В данной ситуации будет полезен небольшой JavaScript, который навсегда избавит вас от данной проблемы.

В шаблоне вашего сайта, перед закрытием тега </body> необходимо добавить код из примера ниже. Теперь, вне зависимости от наличия атрибута target="_blank", скрипт автоматически будет открывать исходящие ссылки в новой вкладке браузера. При этом, навигация по внутренним ссылкам сайта останется без изменений.

<script type= "text/javascript">
$('a').each(function() {
    var a = new RegExp('/' + window.location.host + '/');
    if(!a.test(this.href)) {
         $(this).click(function(event) {
         event.preventDefault();
         event.stopPropagation();
         window.open(this.href, '_blank');
         });
    }
})
</script>;

Закрыть ссылку от индексации

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

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

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

Для того чтобы закрыть ссылку от индексирования, мы будем записывать ее в виде текста размещенного внутри HTML-тега <span>. Самостоятельно <span> не имеет логического значения и выполняет функцию тэга-контейнера, который используют для форматирования или назначения уникального идентификатора выделенному фрагменту текста.

Чтобы сделать закрытую ссылку в браузере посетителя активной и ничем не отличающейся от других ссылок, мы будем использовать внутри HTML-документа специальный JavaScript код. Дополнительно назначим для тэга <span> стили оформления, которые уже используют ссылки на нашем сайте.

Закрыть ссылку от индексации в WordPress

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

Открываем панель управления WordPress и переходим в меню «Внешний вид» — «Редактор». Необходимо добавить в файл footer.php перед закрытием тега </body> следующий скрипт:

<script type= "text/javascript">function GoTo(link){window.open(link.replace("url:","http://"));}</script>

Для тега <span> необходимо указать стили таким образом, чтобы формат текста своим внешним видом ничем не отличался от обычной ссылки на нашем сайте. Открываем файл style.css, копируем код из примера ниже и устанавливаем значение селекторов CSS под внешний стиль ссылок.

.spanurl {
  color: #333;
  border-bottom: 1px solid #333;
  cursor:pointer;
}
.spanurl:hover {
  color: #707070;
  border-bottom: none;
}

Теперь, чтобы закрыть ссылку от индексации, вместо обычной ссылки <a href="url"></a> необходимо использовать следующий код:

<span class="spanurl" onclick="GoTo('url:example.com/')">Example Domain</span>

Каждый раз копировать данный код не очень удобно, чтобы легко закрыть ссылку от индексации я предлагаю использовать специально предназначенный для этого шорткод. Для этого необходимо добавить в файл functions.php код из примера ниже:

function shortcode_spanurl($content) {
 
    $pattern = '/[spanurl](.*?)<a (.*?)href=["']([a-zA-Z]+://)?(.*?)["'](.*?)>(.*?)</a>(.*?)[/spanurl]/i';
    $spanurl = preg_replace($pattern, "$1<span class='spanurl' onclick="GoTo('url:$4')">$6</span>$7", $content);
 
return $spanurl;
}
add_filter('the_content', 'shortcode_spanurl');

Используем Lazy Load для загрузки Disqus

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

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

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

Используем Lazy Load для загрузки Disqus

На данный момент существует множество готовых Lazy Load скриптов для разных популярных фреймворков. Чтобы избежать подключения дополнительных JavaScript-библиотек, для загрузки комментариев Disqus с помощью функции Lazy Load, я буду использовать библиотеку jQuery.

Если вы ранее не использовали jQuery, необходимо подключить библиотеку в шаблоне вашего сайта:

<script type='text/javascript' src='//ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js?ver=1.11.1'></script>

Для WordPress будет правильнее выполнить подключение скрипта через файл шаблона functions.php, для этого необходимо добавить в содержимое файла следующую функцию:

function wpdocs_dequeue_script() {
    wp_deregister_script('jquery');
    wp_register_script('jquery', ("//ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"), false, '1.11.3');
    wp_enqueue_script('jquery');
}
add_action( 'wp_print_scripts', 'wpdocs_dequeue_script', 100 );

Непосредственно сам скрипт, отвечающий за загрузку комментариев Disqus при при скроллинге страницы браузера:

<script type="text/javascript">
var disqus_identifier = window.location.url;
var ds_loaded = false;

function loadDisqus()
{
    var disqus_div = $("#disqus_thread");
    var top = disqus_div.offset().top;
    var disqus_data = disqus_div.data();
    if ( !ds_loaded && $(window).scrollTop() + $(window).height() > top ) 
    {
        ds_loaded = true;
        for (var key in disqus_data) 
        {
            if (key.substr(0,6) == 'disqus') 
            {
                window['disqus_' + key.replace('disqus','').toLowerCase()] = disqus_data[key];
            }
        }
        var dsq = document.createElement('script');
        dsq.type = 'text/javascript';
        dsq.async = true;
        dsq.src = 'http://' + window.disqus_shortname + '.disqus.com/embed.js';
        (document.getElementsByTagName('head')[0] || document.getElementsByTagName('body')[0]).appendChild(dsq);
    }  
}

$(function () 
{
    var disqus_div = $("#disqus_thread");
    if (disqus_div.size() > 0) 
    {
        $(window).scroll(loadDisqus);      
    }  
}
);
</script>

Скрипт лучше вынести в отдельный файл, а затем подключить его в functions.php:

function disqus_lazyload_script() {
    wp_enqueue_script('disqus', get_stylesheet_directory_uri() . '/disqusLazyLoad.js', array('jquery'), false, true); 
}
add_action( 'wp_enqueue_scripts', 'disqus_lazyload_script', 30 );

В месте отображения блока комментариев Disqus необходимо добавить строку ниже, в которой необходимо заменить значение параметра data-disqus-shortname на ваш идентификатор.

<div id="disqus_thread" data-disqus-shortname="DISQUS_SHORTNAME"></div>

Загрузка jQuery с Google CDN

Многие шаблоны, плагины и компоненты сайта используют для своей работы библиотеку скриптов jQuery. По умолчанию в WordPress скрипты загружаются из папки wp-includes. Первоначальный размер библиотеки jQuery составляет порядка 300KB, после минимизации его можно уменьшить до 90KB. Дополнительно количество передаваемых данных можно снизить за счет использования сжатия GZIP.

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

Ситуация кардинально меняется если посетители запросят миллион страниц с пустым кэшем браузера, в этом случае используя CDN вы экономите до 76GB трафика. А при использовании популярного Google CDN, есть большая вероятность, что необходимая библиотека jQuery уже лежит внутри кэша браузера. В добавок, если сравнить скорости загрузки с CDN и обычного хостинга, то разница во времени может отличаться в несколько раз в пользу CDN.

Таким образом, используя CDN для загрузки jQuery, мы без труда убираем один лишний запрос к серверу и немного уменьшаем время загрузки страниц сайта. Так зачем игнорировать такую возможность?

Вместо того чтобы использовать платные CDN-сервисы, мы можем свободно загружать jQuery с серверов крупных компаний. Для jQuery есть несколько популярных общедоступных CDN:

  • jQuery CDN
  • Google CDN
  • Microsoft CDN
  • CDNJS CDN
  • Яндекс CDN

Подробней о использовании указанных CDN-сервисов вы можете прочитать на официальном сайте jQuery. Что касается меня, для своих нужд я предпочитаю использовать Google CDN — наиболее популярный среди всех бесплатных CDN-сервисов, 89% от загрузок которого приходится на библиотеку jQuery. Поэтому, далее речь пойдет о использовании именного этого сервиса.

Особенности использования Google CDN

При использовании Google CDN, вы можете прямо указать версию (1.11.1) загружаемой библиотеки или с помощью модификации фрагмента ссылки, указать необходимые параметры для загрузки jQuery.

Пример подключения jQuery с использованием точной версии библиотеки:

<script src="//ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>

Для загрузки последней актуальной версии jQuery используем код:

<script src="http://ajax.googleapis.com/ajax/libs/jquery/1/jquery.min.js"></script>

Следует отметить, что время жизни файла в кэше браузера, напрямую зависит от ссылки, которую мы будем использовать для подключения библиотеки. При использовании ссылки содержащей точную версию библиотеки, время хранение файла в кэше будет ограничено сроком равным одному году max-age=31536000. Если вы используете ссылку для последней актуальной версии jQuery, файл будет храниться в кэше в течении часа max-age=3600.

Используем Google CDN для загрузки jQuery в WordPress

Для загрузки jQuery с Google CDN на сайте использующем WordPress, для начала необходимо выяснить необходимую версию библиотеки. Для этого достаточно заглянуть в содержимое HTML-документа вашего сайта. Для правильного подключения jQuery в WordPress необходимо добавить код функции ниже в содержимое файла functions.php вашей темы:

function wpdocs_dequeue_script() {
    wp_deregister_script('jquery');
    wp_register_script('jquery', ("//ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"), false, '1.11.1');
    wp_enqueue_script('jquery');
}
add_action( 'wp_print_scripts', 'wpdocs_dequeue_script', 100 );

Данная функция удалит из очереди на подключение библиотеку из каталога wp-includes и заменяет ее на jQuery с сайта Google CDN.