Узнать ОС пользователя

January 31, 2022
var OS = "Not known";
if (navigator.appVersion.indexOf("Win") != -1) {
	OS = "Windows OS";
} else if (navigator.appVersion.indexOf("Mac") != -1) {
	OS = "MacOS";
} else if (navigator.appVersion.indexOf("X11") != -1) {
	OS = "UNIX OS";
} else if (navigator.appVersion.indexOf("Linux") != -1) {
	OS = "Linux OS";
}
if (OS == "MacOS") {
	// do something for Mac
} else if (OS == "Windows OS" || OS == "UNIX OS" || OS == "Linux OS") {
	// do something for others
}

Тут могла быть ваша реклама.

.forEach для списка элементов DOM

June 15, 2021
var allElems = document.querySelectorAll('.some-class');
var allElemsArr = Array.prototype.slice.call(allElems);
allElemsArr.forEach(function(el, index){
    // code here
});

Следующая конструкция не используется по причине того, что не поддерживается в некоторых старых браузерах:

document.querySelectorAll('.some-class').forEach(function(el, index){
    // code here
});

Тут могла быть ваша реклама.

JotForm. Динамичные значения полей формы

March 12, 2021

Есть такой сервис для создания форм обратных связей и интеграции их на сайт – JotForm. Прикол в том, что одну и ту же форму можно добавить на разные страницы, но добавляется она через iframe. Потому, если есть необходимость добавить в форму поле, которое должно содержать, например, название страницы (динамическое значение), то для этого есть способ, но в документации и на форумах он описан криво и в предложенном виде работать не будет. Мне пришлось найти его методом тыка и сейчас я опишу, как же всё-таки это делается правильно.
Для начала нужно в редакторе формы создать поле, в которое будет подставляться нужное значение.

Например:

1. Добавляем текстовое поле:

2. Идём в настройки этого поля:

3. Задаём для поля уникальное имя:

4. Идём во вкладку PUBLISH (в верхней части страницы на оранжевой полосе) и открываем форму для просмотра, нажав на кнопку “Open in new tab”:

5. Тут нам нужно открыть консоль браузера (в chrome  – F12) и посмотреть, какое имя присвоил jotForm нашему полю (в моём случае q23_jobTitle):

Нам нужна та его часть, что идёт после “_”, т.е. в моём случае jobTitle.

6. Затем возвращаемся во вкладку PUBLISH -> EMBED -> IFRAME и копируем оттуда код.

 

7. Добавляем его в нужное место на странице нашего сайта, но с одним изменением: в атрибут src добавляем get-параметры с именами наших полей, а в качестве их значений уже пишем то, что ним нужно:

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


Тут могла быть ваша реклама.

Адаптивный popup на все случаи жизни

March 7, 2021

Данный попап открывается при добавлении к элементу #popup класса .open. Непосредственно сам попап – это элемент с классом .popup_block, а обёртка нужна, чтобы затемнять страницу при его открытии и для выравнивания попапа по центру страницы, а если он не будет помещаться в окно (например на мобильных устройствах) то будет появляться вертикальный скролл.

HTML

<div id="popup" class="popup-bg">
    <div class="popup__container">
        <div class="popup__block">
            <div class="popup__close"></div>
        </div>
    </div>
</div>

CSS

.popup__close {
    position: absolute;
    top: 10px;
    right: 10px;
    display: block;
    width: 25px;
    height: 25px;
    cursor: pointer;
    z-index: 10;
}

.popup__close::before,
.popup__close::after {
    content: '';
    position: absolute;
    top: 50%;
    left: -3px;
    display: block;
    width: 27px;
    height: 2px;
    background-color: #9ea1a7;
}

.popup__close::before {
    transform: translate(0,-2px) rotate(45deg);
}

.popup__close::after {
    transform: translate(0,-2px) rotate(-45deg);
}

.popup-bg {
    opacity: 0;
    pointer-events: none;
    position: fixed;
    top: 0;
    left: 0;
    width: 100vw;
    height: 100vh;
    background-color: rgba(0,0,0,.8);
    z-index: 99;
    transition: .3s all;
}

.popup-bg.open {
    opacity: 1;
    pointer-events: auto;
}

.popup__container {
    width: 100%;
    max-height: 100%;
    overflow-y: auto;
    margin: 0 auto;
    position: absolute;
    top: 50%;
    left: 50%;
    transform: translate(-50%,-50%);
}

.popup__block {
    position: relative;
    margin: 0 auto;
    width: 100%;
    max-width: 500px;
    padding: 40px 15px 20px;
}

Script

document.querySelector('.open-popup-button').addEventListener('click',function(){
    document.querySelector('#popup').classList.add('open');
});
document.querySelector('.popup__close').addEventListener('click',function(){
    document.querySelector('#popup').classList.remove('open');
});

Тут могла быть ваша реклама.

Плавное появление элементов страницы при скролле

February 4, 2021
// Smooth appearance of sections
function smoothApp( section, elemArr, styleArr, transArr, timeoutArr, num ) {
    if (document.querySelector(section) && window.innerWidth >= 992) {
        var windowPos = Math.abs(Math.round(document.querySelector('html').getBoundingClientRect().top));
        var startPos = document.querySelector(section).getBoundingClientRect().top + window.pageYOffset - (window.innerHeight * num);
        elemArr.forEach(function(el, index){
            if (document.querySelector(el)) {
                if (document.querySelector(el) && windowPos < startPos) {
                    document.querySelector(el).style.transform = 'translate(' + styleArr[index] + ')';
                    document.querySelector(el).style.opacity = '0';
                    document.querySelector(el).style.transition = 'none';
                }
            }
        });
        window.addEventListener('scroll', function(event){
            var windowPos = Math.abs(Math.round(document.querySelector('html').getBoundingClientRect().top));
            var startPos = document.querySelector(section).getBoundingClientRect().top + window.pageYOffset - (window.innerHeight * num);
            if (windowPos > startPos){
                elemArr.forEach(function(el, index){
                    if (document.querySelector(el)) {
                        document.querySelector(el).style.transition = transArr[index] + 's all';
                        setTimeout( function(){
                            document.querySelector(el).style.transform = 'translate(0,0)';
                            document.querySelector(el).style.opacity = '1';
                        }, timeoutArr[index]);
                    }
                });
            }
        });
    }
}

section – селектор элемента, при прокрутке до которого начинается анимация

elemArr – массив со списком селекторов тех элементов, которые должны анимироваться

styleArr – массив со значениями x и y для каждого элемента из предыдущего массива, на которые будет сдвинут элемент относительно текущего положения (смещение на стартовую позицию для анимации)

transArr – массив с временем анимации в секундах для каждого элемента массива elemArr

timeoutArr – массив с временем задержки анимации в секундах для каждого элемента массива elemArr

num – значение отвечает за место срабатывания анимации относительно окна, где 1 – нижняя часть окна (т.е. анимация сработает, когда анимируемый элемент окажется в самой нижней области окна), а 0 – верхняя часть окна (т.е. анимация сработает тогда, когда элемент окажется в самом верху окна). Указывается без кавычек.
ПРИМЕЧАНИЕ: некоторые старые браузеры не умеют читать дефолтные значения аргументов функции, поэтому желательно указывать значение аргумента num непосредственно в момент вызова функции, а дефолтное значение удалить.


Тут могла быть ваша реклама.

Добавляем атрибут defer к скриптам для повышения скорости загрузки страниц

February 4, 2021
function defer_parsing_of_js( $url ) {
    if ( is_user_logged_in() ) return $url; //don't break WP Admin
    if ( FALSE === strpos( $url, '.js' ) ) return $url;
    if ( strpos( $url, 'jquery.js' ) ) return $url;
    return str_replace( ' src', ' defer src', $url );
}
add_filter( 'script_loader_tag', 'defer_parsing_of_js', 10 );

Тут могла быть ваша реклама.

Скрипт для вывода времени, привязанного к конкретному часовому поясу

June 7, 2020

Я потратил почти сутки, чтобы разобраться в этом, но у меня-таки получилось…
В js есть объект Date(), который возвращает время пользователя, при помощи которого можно реализовать, например, динамические часы или таймер обратного отсчёта на странице сайта. Моей же задачей было получить и вывести на страницу время конкретной временной зоны, вне зависимости от временной зоны пользователя.

Внутри объекта Date() есть параметр, который показывает часовой пояс пользователя. Всё что нужно сделать, чтобы получить, например, московское время – вычесть из текущего времени пользователя смещение по времени, получив тем самым время по Гринвичу, и применить к получившемуся результату нужное смещение (в случае с Москвой – прибавить три часа).

Делается это довольно просто:
Для получения смещения относительно Гринвича к объекту Date() применяется метод getTimezoneOffset().
В двух словах: данный метод возвращает смещение времени пользователя относительно Гринвича в минутах со знаком “минус”. Т.е. пользователь с UTC+5 в результате работы данного метода получит -300 ( 5 * 60 ). О том откуда берётся знак “минус” можно почитать в статьях об этом методе.

Вот такой код получился в итоге:

function moveTimeZone( timezone_offset ){
    var current_timezone_offset = new Date().getTimezoneOffset();
    var now_in_selected_timezone = new Date( new Date().getTime() + timezone_offset * 3600 * 1000 + current_timezone_offset * 60 * 1000);
    return now_in_selected_timezone;
}
var userTime = Math.round(new Date().getTime()/1000);
var timeInMoscow = moveTimeZone($userTime, 3);

А теперь подробнее:
Функция:
В переменную current_timezone_offset записываем значение смещения времени во временной зоне пользователя (в минутах).
В переменную now_in_selected_timezone записываем время нужной нам временной зоны, которое получаем при помощи следующей формулы:

текущее время пользователя ( new Date().getTime() )
+
смещение времени для временной зоны, время которой мы хотим получить (в часах, по этому умножаем timezone_offset на 3600, чтобы получить значение в секундах и на 1000, для получения его же в миллисекундах)
+
смещение времени во временной зоне пользователя (так как значение для current_timezone_offset было получено в минутах, то для получения его в секундах умножаем его на 60, а следом на 1000, для получения значения в миллисекундах).

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

Конечно есть один нюанс: время на устройстве пользователя может быть неправильным, из-за чего и финальное значение не будет соответствовать действительности. Чтобы избежать подобного следует использовать время сервера, которое в PHP можно получить при помощи функции time().

p.s. Статья создана ещё в феврале 2018, а дописана только сейчас – в июне 2020. А всё дело в том, что я буквально на той неделе столкнулся с необходимостью написания таймера обратного отсчёта и долго вспоминал, как же я это делал два года назад. Решил таки задокументировать, чтобы было куда подглянуть через два года, когда я снова забуду как это делается.

p.s.s 18.11.2024 Таки пригодилось, подглядел, внёс изменения для уменьшения объёма кода


Тут могла быть ваша реклама.

Первая тестовая запись

June 14, 2019

Первая тестовая запись

Первая проблема, с которой я столкнулся при работе с этим сайтом — некорректное отображение оного в стандартном браузере Android. Дело в том, что шаблон, вроде как, адаптивный, т.е. должен адекватно отображаться на любом устройстве, аккуратно масштабируясь под соответствующий размер. Но, увы, при входе на сайт с планшетника, я не увидел ни заголовков, ни виджетов, хотя в полноразмерной версии они есть. Точно такой же шаблон стоит у меня на первом сайте и проблем с ним в этом плане не возникало. Ну, раз проблема есть, то её надо решать. Лезть в код не было никакого желания, т.к. я пока ещё толком не разобрался в архитектуре WordPress’а и знания языков пока не достаточно хорошие, так что решение проблемы правкой кода заняло бы кучу времени и потратило бы кучу нервов. Решить проблему я хотел как можно быстрее, потому пошёл более лёгким путём.

Сначала я грешил на шрифты, потому полез в настройки шаблона, в надежде на то, что если я поставлю шрифт попроще, то Android с ним справится. Но я не смог этого сделать. Причина была проста — раздел «Шрифты» попросту отсутствовал, что вызвало у меня удивление и возмущение.

Тогда я решил сделать ход конём — поискать плагины, которые поправили бы код за меня или, по крайней мере, добавили бы новых функций в редактор. И такие, к моей великой радости, нашлись.

Первый из них — Easy Google Fonts — плагин добавляет в редактор пункт Typography, через который можно достаточно гибко отформатировать весь текст сайта. Задать нужный шрифт, его размер, цвет и т.д. + к стандартным шрифтам он подключает гугловские (большая часть не поддерживает кириллицу). Он очень облегчил мне жизнь.

Второй — Jetpack от WordPress.com — плагин с огромным количеством функций, от защиты от спама, до… а впрочем вот тут всё подробно описано. Меня интересовала одна конкретная функция — адаптация сайта для мобильных устройств. А включается она довольно просто — установкой галочки в соответствующей строке.

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


Данный текст выводится при помощи плагина Advanced Custom Fields. Изображение ниже – также выводится при помощи данного плагина.


Прячем сайт от индексации поисковыми системами

June 14, 2019

Иногда бывает необходимо закрыть сайт от индексации. Как например в моём случае, когда я создаю сайт для клиента на своём хостинге, а позже перекидываю его на хостинг клиента. Чтобы в последствии у клиента не возникло проблем с индексацией и производится манипуляция, описанная ниже.
Всё довольно просто. Нам понадобится всего-то 2 файла: .htpasswd и .htaccess, которые содержат несколько строк кода на двоих.

Эти файлы, пока ещё девственно чистые, мы создаём на нашем хостинге в том разделе, где у нас лежит сайт ( в случае с WordPress — в разделе, в котором лежит сам WorgPress ). Я создавал их, подключившись к хостингу по FTP через FileZilla. Теперь нам нужно заполнить их содержимым, которое мы будем генерировать при помощи замечательного ресурса www.htaccesstools.com.

Создание .htpasswd

Придумываем логин и пароль для доступа к нашему сайту (! запоминаем или записываем !), переходим по ссылке и вводим их в соответствующие поля. После нажимаем кнопку «Create .htpasswd file» и получаем строку кода, который нам нужно скопировать в файл .htpasswd. Копируем, сохраняем файл.

Создание .htaccess

Теперь переходим по этой ссылке и в поле .htpasswd File Location вводим путь к файлу .htpasswd, который мы только что отредактировали. Выглядеть он должен примерно так: /home/username/domain.com/.htpasswd. В контексте данного поста поле Auth Name нас не особо интересует, можно оставить как есть. Затем нажимаем на кнопку «Create .htaccess file» и получаем код, который нам нужно скопировать в файл .htaccess. Копируем, сохраняем.

Всё!

Теперь, когда мы зайдём на сайт, то увидим следующую картину:

Теперь, чтобы попасть на сайт, нам нужно ввести логин и пароль, которые мы ! запомнили или записали !

Вот и всё. Всем ништяков.