JavaScript

Listen element content changes

December 30, 2022
var someElement = document.querySelector('.some-class');
if(window.addEventListener) {
  // Normal browsers
  someElement.addEventListener('DOMSubtreeModified', someFunction, false);
} else if(window.attachEvent) {
  // IE
  someElement.attachEvent('DOMSubtreeModified', someFunction);
}
async function someFunction() {
  // Do something if someElement content change
}

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

Cookies functions

August 18, 2022

Функции для записи/удаления/получения значений cookie по имени:

function set_cookie(name, value) {
    document.cookie = name +'='+ value +'; Path=/;';
}

function delete_cookie(name) {
    document.cookie = name +'=; Path=/; Expires=Thu, 01 Jan 1970 00:00:01 GMT;';
}

function get_cookie(name) {
    let cookie = {};
    document.cookie.split(';').forEach(function(el) {
        let [key,value] = el.split('=');
        cookie[key.trim()] = value;
    });
    return cookie[name];
}

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

replaceAll vs replace

July 11, 2022

Функция replaceAll не работает в старых версиях Safari, вместо неё можно использовать replace с регулярным выражением. Пример:

var string = 'some text for test';
if (string.indexOf('te') != -1) { // если подстрока 'te' есть в строке string
    /* string = string.replaceAll('te', ' '); */
    string = string.replace(/te/g, ' '); // /substring/g
    console.log(string);
}
// Выведет 'some xt for st' в консоль.

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

Detect mobile iOS

March 19, 2022

Меняем событие ‘click’ на ‘touchstart’ для мобильных на iOS, т.к. последний не реагирует на событие ‘click’:

function iOS() {
	return [
		'iPad Simulator',
		'iPhone Simulator',
		'iPod Simulator',
		'iPad',
		'iPhone',
		'iPod'
	].includes(navigator.platform)
	// iPad on iOS 13 detection
	|| (navigator.userAgent.includes("Mac") && "ontouchend" in document)
}

var click = 'click';
if (iOS()) {
	click = 'touchstart';
}

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

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

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
}

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

jQuery to JS – Переход к нативному JavaScript

June 15, 2021

Полезная статья о переходе с jQuery на js:
jQuery to JS – Переход к нативному JavaScript


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

.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
});

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

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

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 непосредственно в момент вызова функции, а дефолтное значение удалить.


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

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

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 Таки пригодилось, подглядел, внёс изменения для уменьшения объёма кода


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