Подсказки и приемы по программированию на jQuery
Это статья-шпаргалка по программированию на jQuery. Здесь для удобства собраны приемы и часто используемые функции при программировании. Статья будет пополняться по мере необходимости.
Для удобства пользования этой шпаргалкой к ней прилагается функционал. В необходимом месте этой страницы можно сделать клик мышью с зажатой клавишей Alt и тем самым установить метку. Установив несколько таких меток между ними можно быстро переключаться нажимая зеленые кнопки Вверх и Вниз в правом верхнем углу. Удалить ненужную метку можно кликнув по ней.
Если на странице сделать клик средней клавишей мыши (та что под колесом) с зажатой клавишей Ctrl, то появится поле поиска. При поиске выводятся блоки, содержащие все слова введенные в поле поиска через пробел.
Для отладки кода на Javascript/jQuery, HTML и CSS есть сервис: jsfiddle.net
Для отладки кода на PHP есть сервис: code.sololearn.com
Для отладки кода HTML и CSS есть сервис: edithtm.html5css.ru
Для проверки поддержки той или иной технологии в разных браузерах есть сервис: caniuse.com
Справка по диаграммам: Google Charts
Справка по формату SVG для рисования векторной графики в HTML: svg-art.ru
Предопределенные имена цветов в HTML и CSS: ссылка
Справка по технологии контейнеров: Flexbox
Иконки FontAwesome
Коды клавиш в Javascript
Типы данных MySQL
Строковые функции в MySQL
Специальные символы HTML
Оглавление
Поиск элементов DOM
hbnn = $('*'); // выбрать все элементы на любом уровне вложенности на странице (включая <html>, <head> и <body>)
hbnn = $('#rzd *'); // выбрать всех детей на любом уровне вложенности принадлежащих #rzd
st = $('[class~=hello]'); // выберет все элементы содержащие в названии класса слово hello
st = $('[class^=hello]'); // выберет все элементы, название класса которых начинается со слова hello
q = $('li label > input:checkbox');
$('input:checkbox:checked');
$('[data-k=король]'); // когда значение атрибута задано в одно слово
$('[data-k="король голый"]'); // когда значение атрибута задано несколькими словами
$('input[name="txt1"]'); // выбрать элемент по имени
$('div[data-k1=король][data-k2=королева]'); // выбрать элементы по нескольким атрибутам
$(this).parent("li"); // выбрать непосредственно родительский с тегом li элемент указанного элемента
$(this).parents("li"); // выбрать на любом уровне родительский с тегом li элемент указанного элемента (вернёт все li элементы вверх по иерархии от this)
$(this).closest("li"); // выбрать на любом уровне родительский с тегом li элемент указанного элемента (вернёт первый li элемент вверх по иерархии от this)
$(this).children("li"); // выбрать всех детей с тегом li указанного элемента
let k = $(this).find('[data-pp]').length; // выведет количество элементов с атрибутом data-pp находящихся на любой глубине внутри родителя
// имеем HTML
<div class="text">начало<p>параграф</p>конец</div>
// с методом contents выведет 3 сообщения: "начало", "параграф", "конец"
$(".text").contents().each(function(){alert($(this).text());});
// с методом children выведет 1 сообщение: "параграф"
$(".text").children().each(function(){alert($(this).text());});
// вернуть всех детей .glav на любом уровне вложенности, исключая любых детей #ogl, при этом, у которых в текстовом узле элемента встречаются одновременно слова: 'выбрать' и 'начал' без учета регистра символов
let mspo = ['выбрать', 'начал'];
let a = $('.glav *').contents().filter(function() {
// если функция возвратит false для элемента, то он будет отфильтрован, если true - то элемент будет возвращен
if (!$(this).parents('#ogl').length) { // исключить элементы родитель которых #ogl на любом уровне
if (this.nodeType == 3) { // выполнять только для текстовых узлов
let fl = true;
for (i = 0; i < mspol; i++) {if (this.textContent.toLowerCase().indexOf(mspo[i]) == -1) {fl = false; break;}}
return fl;
} else {return false;}
} else {return false;}
}).parent(); // возвращать родителя текстового узла
slo = $(this).prev("a").html(); // предыдущий элемент с тегом a
slo = $(this).next("a").html(); // следующий элемент с тегом a
// если предыдущий/следующий элемент не существует, то все равно возвращается объект, но с тегом undefined
let li = $(this).next("li");
let tn = li.prop('tagName'); // определить тип тега у элемента
if (!!tn) { // проверка, если следующий элемент существует
// какой-то код
}
let q = $(this).siblings(); // выберет все смежные (сестринские) элементы для элемента this
let q2 = $(this).siblings('.ttt'); // выберет смежные (сестринские) элементы с классом ttt для элемента this
res1 = $(".disl:first");
res2 = $(".disl:last");
res1 = $(".disl").children("label").first();
// выберет первый дочерний элемент с тегом label
res2 = $(".disl").children("label").last(); // выберет последний дочерний элемент с тегом label
el1 = $(this).parents('td').children('input:first-child'); // выберет первый дочерний элемент с тегом input
el2 = $(this).parents('td').children('input:last-child'); // выберет последний дочерний элемент с тегом input
$('div:not(#foo)'); // выберет все div, у которых id не foo
$('div:not(.foo)'); // выберет все div, у которых класс не foo
$('div:not(:first)'); // выберет все div кроме первого по счёту
$('div:not(:eq(-1), :eq(-2))'); // выберет все div кроме последнего и предпоследнего по счёту
$('div:has(a)'); // выберет все div, внутри которых содержится тег a
$('div:not(:has(a))'); // выберет все div, внутри которых не содержится тег a
str = $('span:contains("город")'); // выберет все span, в которых встречается "город", во всех словоформах в т. ч. "городок", "городской" и т. д.
$.expr[":"].exact = $.expr.createPseudo(function(arg) {return function(element) {return $(element).text() === arg.trim();};});
str = $("span:exact('город')"); // выберет span, в котором содержится слово "город" и ничего больше
q = $('p.box'); // выбрать элемент с тегом p и классом box
$('div:eq(0)'); // вернет первый div на странице
$('div:eq(1)'); // вернет второй div на странице
$('div:eq(-1)'); // вернет последний div на странице
$("div:even"); // выберет каждый нечётный элемент (т. к. индексы элементов начинаются с 0, то будут выбраны элементы с индексами: 0, 2, 4, 6 и т. д.)
$("div:odd"); // выберет каждый чётный элемент (т. к. индексы элементов начинаются с 0, то будут выбраны элементы с индексами: 1, 3, 5, 7 и т. д.)
let fc = $(":focus");
if ($('#banner').length) { // проверка на существование
alert('элемент banner существует');
}
if (!$('#banner').length) { // проверка на не существование
alert('элемент banner не существует');
}
if (!$('.mtk').length) { // проверка на не существование набора элементов
alert('элементов с классом mtk не существует');
}
let f = $(this).attr('style');
if (typeof f === "undefined" && f === false) {console.log('Атрибут отсутствует');}
a = document.getElementById("sum"); // по id
b = document.getElementsByName("sum"); // по name
c = document.getElementsByTagName("div"); // по тегу
d = document.getElementsByClassName("pole"); // по class
e = document.querySelector("ol > li"); // по css-селектору (первый элемент)
f = document.querySelectorAll("ol > li"); // по css-селектору (все элементы)
g = f[0]; // первый элемент в наборе f
let k = $('#ifr1').contents().find('#el1').attr('data-k'); // получить атрибут элемента в iframe
$('#ifr1').contents().find('select[name="sel1"]').val(id); // установить значение элемента в iframe
let fr1 = $('#ifr1').get(0).contentWindow; fr1.myfunc(); // выполнить функцию принадлежащую документу в iframe
$('#ok', window.parent.document).val(id); // установить значение элемента в родительском окне
$('#frm1', window.parent.document).submit(); // отправить форму в родительском окне
$('#vs', window.parent.document).hide(); // скрыть элемент в родительском окне
$('#ok', window.parent.document).append($('<span>', {id:'el1', text: 'дочь1'})); // создать дочерний элемент в конце заданного элемента в родительском окне
window.parent.myfunc(); // выполнить функцию принадлежащую родительскому окну
Свойства элементов DOM
let a = this.nodeType; // 1 - элемент, 3 - текстовый узел элемента, 9 - объект документа
let tn = $(this).prop('tagName'); // определить тип тега у элемента, вернет DIV, P, SPAN и т. п.
let q = $('#elem')[0].outerHTML;
$("#town option:selected").text();
rz = $('#lab_razmer_pe').val();
// вернёт true - если элемент видим и false - если не видим; при этом учитывается, когда родитель элемента невидим, тогда и искомый элемент будет невидим
rz = $('#cls').is(":visible");
$("#foo").height(); // реальная высота элемента
$("#foo").innerHeight(); // реальная высота элемента с учётом padding
$("#foo").outerHeight(); // реальная высота элемента с учётом padding и border-width
$("#foo").outerHeight(true); // реальная высота элемента с учётом padding, border-width и margin
$("#foo").width(); // реальная ширина элемента
$("#foo").innerWidth(); // реальная ширина элемента с учётом padding
$("#foo").outerWidth(); // реальная ширина элемента с учётом padding и border-width
$("#foo").outerWidth(true); // реальная ширина элемента с учётом padding, border-width и margin
h = document.documentElement.clientHeight; // высота окна браузера исключая полосу прокрутки
w = document.documentElement.clientWidth; // ширина окна браузера исключая полосу прокрутки
h2 = window.innerHeight; // высота окна браузера включая полосу прокрутки, если она есть (обычно = h + 17px)
w2 = window.innerWidth; // ширина окна браузера включая полосу прокрутки, если она есть (обычно = w + 17px)
lf = screen.width; // ширина монитора в пикселях (1920)
tp = screen.height; // высота монитора в пикселях (1080)
h1 = document.body.clientHeight; // высота body, включая высоту всех данных не входящих в видимую область окна браузера
w1 = document.body.clientWidth; // ширина body, включая ширину всех данных не входящих в видимую область окна браузера
let el = document.querySelector('#el');
el.clientHeight; // высота элемента на странице исключая высоту данных не входящих в видимую область элемента (с padding, без border, без scrollbar если он есть)
el.clientWidth; // ширина элемента на странице исключая ширину данных не входящих в видимую область элемента (с padding, без border, без scrollbar если он есть)
// бывает нужно, чтобы выяснить полную высоту элемента, который имеет полосу прокрутки, если у элемента нет вертикальной полосы прокрутки, то значение scrollHeight равно clientHeight
var elem = document.querySelector('#elem');
alert(elem.scrollHeight);
var elem = document.querySelector('#elem');
let v = elem.getBoundingClientRect();
let le = v.left; // расстояние до левой границы элемента
let to = v.top; // расстояние до верхней границы элемента
let ri = v.right; // расстояние до правой границы элемента
let bo = v.bottom; // расстояние до нижней границы элемента
let wi = v.width; // ширина элемента
let he = v.height; // высота элемента
// если элемент находится выше видимой области окна браузера, то расстояния до верхней и нижней границ элемента будут иметь отрицательные значения
le = $(this).offset().left; // расстояние слева
to = $(this).offset().top; // расстояние сверху
$("#foo").position().left; // расстояние слева
$("#foo").position().top; // расстояние сверху
z = $(this).val(); // получить значение атрибута value тега input
z = $("div").html(); // получить данные, содержащиеся между открывающим и закрывающим тегом div
z = $("label").text(); // получить текст внутри тега label исключая содержащиеся в нем другие теги
a = $('.ool label > [type="checkbox"]').prop('checked'); // возвращает true, если checkbox отмечен и false - если нет
// на чистом Javascript
b = document.querySelector('#dd').checked; // возвращает true, если checkbox отмечен и false - если нет
el = $('[name="vop"]:checked').val(); // покажет выбранное значение среди радио-кнопок с name="vop"
$(".zn").css("left","245px"); // если свойство одно
$(".zn").css({"left":"100px", "top":"150px"}); // если свойств несколько
$(".elm").css("height", ""); // удалит из атрибута style элемента elm свойство height
$(".elm").attr("style", ""); // удалит все css-свойства, содержащиеся в атрибуте style у элемента elm
$(".zn").attr("class", "spp"); // если атрибут один
$(".zn").attr({"class":"spp", "title":"Заголовок"}); // если атрибутов несколько
$('#elm').removeAttr("style"); // удалит атрибут style у элемента elm, со всеми css-свойствами в нём
$('#elm').removeAttr("data-d alt"); // удалить несколько атрибутов у элемента
$("div").html("мороз<br> и солнце"); // заменить содержимое тега div (теги будут восприняты в структуру DOM)
$("label").text("мороз<br> и солнце"); // заменить текст тега label (теги НЕ будут восприняты в структуру DOM)
$(this).val("король"); // заменить значение атрибута value тега input
$('textarea[name="tx"]').val("король\nголый"); // заменить содержимое многострочного текстового поля textarea
$('.ool label > [type="checkbox"]').prop('checked', true); // установить птичку в checkbox
$('input[name=group1][value=2]').prop("checked", true); // выбрать радио-кнопку с value = 2
// сделать неактивным элемент input (кнопка перестанет отзываться на действия пользователя, в текстовое поле нельзя будет написать)
$('#bt').prop("disabled", true);
$(this).hide(); // скрыть элемент (место занимаемое элементом остается за ним)
$(this).show(); // показать элемент
e = document.querySelector("#sum"); // выбрать элемент по id = sum
e2 = document.querySelectorAll("input")[0]; // выбрать элемент по тегу input
s = e.innerHTML; // получить html элемента в переменную s
s2 = e2.value; // получить value элемента в переменную s2
s3 = e.textContent; // получить текст элемента в переменную s3 (все теги будут вырезаны)
document.querySelector("#sum").style.border = '1px solid red';
e = document.querySelector("#sum").parentNode; // вернет родителя #sum
e = document.querySelector("#sum").children[1]; // вернет второго ребенка #sum
e = document.querySelector("#sum").firstElementChild; // вернет первого ребенка #sum
e = document.querySelector("#sum").lastElementChild; // вернет последнего ребенка #sum
e = document.querySelector("#sum").previousElementSibling; // вернет предыдущий рядом стоящий от #sum элемент
e = document.querySelector("#sum").nextElementSibling; // вернет следующий рядом стоящий от #sum элемент
e = document.querySelector("#sum");
alert(e.className); // выведет строку со всеми классами присвоенными элементу через пробел
e.className = 'hhh kkk'; // присвоить элементу классы hhh и kkk
e.classList[0]; // вернет первый класс по порядку из всех классов присвоенных элементу
e.classList.add('mmm'); // добавить элементу к списку классов класс mmm
e.classList.remove('hhh'); // удалить у элемента из списка классов класс hhh
e.classList.length; // вернет количество классов присвоенных элементу
e.classList.toggle("uuu"); // если у элемента есть класс uuu, то он будет удален и вернется значение false, если у элемента нет класса uuu, то он будет добавлен и вернется значение true
e.classList.contains("uuu"); // проверить существует ли у элемента класс uuu, если да то вернет true, если нет - то false
e.classList.replace('mmm', 'uuu'); // заменит существующий класс mmm на класс uuu
HTML-код:
<span id="elm">Скрыть</span>
JQuery-код:
$.fn.extend({toggleText: function(a, b){return this.text(this.text() == b ? a : b);}}); // расширение, чтобы кликом по элементу переключать его текст с одного варианта на другой
$("body").on("click", "#elm", function () {
$(this).toggleText('Скрыть', 'Показать');
});
$(".mydiv").click(function() {
$(this).toggleClass("mycl1").toggleClass("mycl2");
});
s = document.querySelector("#sel").selectedIndex; // получит индекс выбранного элемента в списке select (индексы начинаются от 0)
document.querySelector("#sel").selectedIndex = 1; // выбрать второй элемент списка select
var el = document.querySelector("#sel");
var so = el.options[el.selectedIndex].value;
$('.hod').addClass('redout'); // добавить класс redout элементам с классом hod
$('.hod').addClass('redout kol met'); // добавить классы redout, kol и met элементам с классом hod
$('.hod').removeClass('redout'); // удалить класс redout у элементов с классом hod
$('.hod').removeClass('redout kol met'); // удалить классы redout, kol и met у элементов с классом hod
<div id="pole" class="foo bar"></div>
<script>
a = $('#pole').hasClass('foo'); alert(a); // выведет true
b = $('#pole').hasClass('bar'); alert(b); // выведет true
c = $('#pole').hasClass('qqq'); alert(c); // выведет false
</script>
Работа с наборами элементов DOM
// свойство length работает быстрее, чем метод size(), поэтому его использование предпочтительнее
sl = $(".ol2col li").length; // вернёт количество li в списке
sl = $("select[id=town] option").size(); // вернёт количество элементов option в списке select
// счёт элементов начинается с 0
ind = $("#ull li").index( $(this) );
// или так
ind = $(this).closest('ul').children('li').index( $(this).closest('li') );
$('div').eq(0); // вернет первый div на странице
$('div').eq(1); // вернет второй div на странице
$('div').eq(-1); // вернет последний div на странице
s = $('div');
s.eq(-2); // вернет предпоследний div на странице
// в переменной A задан сам набор элементов, в переменную max попадет максимальная длина, в переменную elem - сам элемент
var A = $('.ol2col li span'), max = 0, elem;
A.each(function () {
if (this.offsetWidth > max)
max = this.offsetWidth, elem = this;
});
$('#town option:selected').each(function(){
this.selected=false;
});
$('#select option[value=5]').prop('selected', true); // пункт будет выбран визуально в элементе select
$('.zn').each(function(i){
// обратиться к текущему элементу можно через $(this)
// i - это счетчик, порядковый номер элемента в перебираемом наборе (счёт начинается с 0)
});
// переберёт элементы от последнего к первому
$($('.zn').get().reverse()).each(function(i){
});
// или так
$($('#elm').children().get().reverse()).each(function(i){
});
$('.zn').each(function(i){
if (i == 2) {return false;} // прервёт перебор элементов на 3-м шаге
});
function sorting(res, ts) {
let l = $(res), c = new Intl.Collator();
let i = l.children('li').get();
i.sort(function(a, b) {
let ca = $(a).text().toUpperCase();
let cb = $(b).text().toUpperCase();
return (ts ? 1 : -1) * c.compare(ca, cb);
});
ts = !ts; $.each(i, function(idx, itm) {l.append(itm);});
}
sorting('#myul', true); // запуск сортировки для списка myul в прямом порядке
sorting('#myul', false); // запуск сортировки для списка myul в обратном порядке
Обработка событий
let win = window.open("", "_blank", "toolbar=no,location=no,directories=no,status=no,menubar=no,scrollbars=yes,resizable=yes,width=500,height=300,top=100,left=200");
// задать заголовок и текст для нового окна
win.document.body.innerHTML = '<html><head><style></style><title>Название</title></head><body><div id="lnk">Текст</div></body></html>';
// событие - клик по элементу в попапе
$(win.document.body).on("click", "#lnk", function () {
});
// событие - перед закрытием окна попапа
$(win).on('beforeunload', function(){
});
var ow;
ow = window.open('doc1.htm');
$("#el1").click(function(){
ow.close(); // закрыть окно, открытое с помощь window.open
});
// закрыть окно, открытое пользователем, с помощью Javascript нельзя
$(window).on("beforeunload", function(){
});
var cntrlIsPressed = false; // переменная хранит состояние Ctrl
$(document).keydown(function(event){if(event.key=="Control") {cntrlIsPressed = true;}});
$(document).keyup(function(){if(event.key=="Control") {cntrlIsPressed = false;}});
$("body").on("click", function (event) {
alert(cntrlIsPressed); // выведет true, если клавиша Control зажата и false - если нет
});
$('body').on('keydown', '#myinput', function(event) {
if (event.key == 'Enter') {
event.preventDefault();
myfunc(); // функция с каким-то кодом
return false;
}
});
// по комбинации клавиш Ctrl + s в браузере запускается диалог сохранения текущей страницы, следующий код переопределит такое поведение и будет запускать мой код
$("body").on('keydown', function(e){
if(e.ctrlKey && e.which === 83){ // при этом за кодом клавиши (83) скрывается не только английская 's', но и русская 'ы'
console.log('Ctrl + s');
e.preventDefault();
return false;
}
});
$(".mr li span").click(function(){
// команды
});
$("body").on("click", "#psk", function () {
// команды
});
function selectedText() { // получить выделенный мышкой текст
if (window.getSelection) {txt = window.getSelection().toString();}
else if (document.getSelection) {txt = document.getSelection();}
else if (document.selection) {txt = document.selection.createRange().text;}
return txt;
}
$('input[name="slo"]').select(function(){
let st = selectedText();
alert(st); // выведет текст выделенный мышкой в текстовом поле с name="slo"
});
$(document).click(function(event) {
if ($(event.target).closest('#foo').length) return;
// команды
event.stopPropagation();
});
elem = document.querySelector("#abc");
// вывести тип события, элемент и координаты клика
elem.onclick = function(event) {
alert(event.type + " на " + event.currentTarget);
alert("Координаты: " + event.clientX + ":" + event.clientY);
};
var a = document.querySelectorAll('.link');
[].forEach.call(a, function(el) {
el.onclick = function(e) { // вешаем событие
// код обработки события
}
});
$("body").on("focusout", ".new", function () {
// команды
});
$('li label > input:checkbox').on("change", function() {
// команды
});
// для чекбоксов созданных динамически
$("body").on("change", ".chk", function () {
a = $(this).prop('checked'); // выдаёт снята или поставлена птичка
});
// обработчик сразу для двух событий mouseenter и mouseleave
$('#myId').hover(
function() {
alert('Навели');
},function() {
alert('Отвели');
});
// обработчик mouseover стоящий на контейнере будет инициировать срабатывание события каждый раз при наведении курсора на дочерние элементы, mouseenter - инициирует срабатывание события единожды при наведении курсора на текущий элемент
$('#foo').mouseenter(function(){
alert('Навели');
});
$('#foo').mouseover(function(){
alert('Навели');
});
// обработчик mouseout стоящий на контейнере будет инициировать срабатывание события каждый раз при выходе с дочерних элементов, mouseleave - инициирует срабатывание события единожды при выходе курсора с текущего элемента
$('#foo').mouseleave(function(){
alert('Отвели');
});
$('#foo').mouseout(function(){
alert('Отвели');
});
$(document).mousemove(function(e){
var X = e.pageX; // положения по оси X
var Y = e.pageY; // положения по оси Y
console.log("X: " + X + " Y: " + Y); // вывод результата в консоль
});
$(document).ready(function(){
$('.div_hover').mousemove(function(e){
// положение элемента
var pos = $(this).offset();
var elem_left = pos.left;
var elem_top = pos.top;
// положение курсора внутри элемента
var Xinner = e.pageX - elem_left;
var Yinner = e.pageY - elem_top;
console.log("X: " + Xinner + " Y: " + Yinner); // вывод результата в консоль
});
});
$('#myColor[type="color"]').on('input', function() {
d = 'a {color:' + $(this).val() + ';}';
alert (d);
});
$('select').on("change", function() {
// команды
});
$("input, textarea").on("change keyup input paste click", function() {
// команды
});
// у textarea нет встроенного события изменения размеров, поэтому используем события нажатия мыши и отпускания мыши - на textarea
// resize textarea
$("body").on("mousedown", ".file_edit", function () {
let hgt = $(this).height();
let id = $(this).attr('id');
$('#resz' + id).remove();
// запомним высоту при нажатии мыши
$("body").append('<input type="hidden" id="resz' + id + '" value="' + hgt + '"/>');
});
// resize textarea
$("body").on("mouseup", ".file_edit", function () {
let id = $(this).attr('id');
let hgt = $(this).height();
let bv = $('#resz' + id).val();
if (bv != hgt) { // если высота во время нажатия мыши и отпускания мыши отличается
console.log('высота textarea изменилась');
} else {$('#resz' + id).remove();}
});
$("body").on("change keyup input paste click", "#psk", function () {
// команды
});
$('#frm').submit();
<form method="POST" action="#" onsubmit="return false;">
<input type="submit" value="Вход" onclick="javascript: myfunc();">
</form>
// параметр onsubmit="return false;" у тега <form> отменит отправку формы; параметр onclick="javascript: myfunc();" выполнит функцию myfunc()
// функция срабатывает при:
// установке фокуса на эту вкладку браузера - да
// возвращении на эту вкладку браузера с другой вкладки - да
// разворачивании свёрнутого окна браузера с открытой этой вкладкой - да
// включении компьютера после гибернации с этой вкладкой бывшей в фокусе - да
// восстановление изображения после того как экран был отключен при простое с этой вкладкой бывшей в фокусе - нет
$(window).on("focus", function(){
console.log('фокус');
});
$(".new").focus();
// на jQuery
$(document).scroll(function(){
let sc = $(document).scrollTop(); // позиция вертикального скролла у документа
});
// на чистом javascript
window.addEventListener('scroll', function() {
let sc = window.pageYOffset || document.documentElement.scrollTop; // позиция вертикального скролла у документа
});
// дождётся, когда загружен DOM
$(function() {
// здесь jQuery код
});
// на чистом Javascript: дождётся, когда загружен DOM
document.addEventListener("DOMContentLoaded", function(event){
// здесь js код
});
// дождётся, когда страница загрузилась полностью (DOM, картинки, фреймы, объекты)
$(window).on("load", function(){
// здесь jQuery код
});
$(".fa-arrows-alt").click(function(event){
event.stopPropagation(); // остановит запуск обработчиков событий click у родительских элементов
// здесь свой код обработки функции
});
// HTML код
<div ondrop="drop(event, this)" ondragover="allowDrow(event)" ondragenter="dragEnter(event)" ondragleave="dragLeave(event)" class="cart">
<p id="el1" class="tch" draggable="true" ondragstart="drag(event)" ondragend="dragEnd(event)">Перетащи</p>
</div>
<div ondrop="drop(event, this)" ondragover="allowDrow(event)" ondragenter="dragEnter(event)" ondragleave="dragLeave(event)" class="cart"></div>
// CSS код
.cart {width: 300px; height: 80px; margin-bottom:20px; background: #ffff00; padding: 20px;}
.tch {background: #0084ff; border: none; border-radius: 5px; padding: 8px 14px; font-size: 15px; color: #fff;}
// JS код
function drag(ev) { // во время хватания элемента
ev.dataTransfer.setData("id", ev.target.id); // передает id перетаскиваемого элемента
// ev.dataTransfer.setData("luboy_kluch", "можно передать что угодно");
}
function drop(ev, block) { // во время бросания элемента
ev.preventDefault(); // отменить действие браузера по умолчанию
let id = ev.dataTransfer.getData("id"); // получить переданное значение по ключу
// let kluch = ev.dataTransfer.getData("luboy_kluch");
block.appendChild(document.getElementById(id)); // перенести перетаскиваемый элемент в целевой блок
block.style.border = ""; // убрать рамку у целевого блока, когда перетаскивание окончено
}
function dragEnter(ev) {
if (ev.target.className == "cart") {
ev.target.style.border = "2px dotted black"; // задать рамку целевому блоку, когда перетаскиваемый элемент находится над ним
}
}
function dragLeave(ev) {ev.target.style.border = "";} // убрать рамку у целевого блока, когда перетаскиваемый элемент покинул его
function allowDrow(ev) {ev.preventDefault();} // отменить действие браузера по умолчанию во время перетаскивания над целевым блоком
function dragEnd(ev) {ev.target.style.border = "";} // срабатывает на элементе который схватили по завершении перетаскивания - убрать рамку
// функция проверяет, чтобы объем файла не превышал 6 Мбайт и расширение файла было gif, png, jpg или jpeg
function valid_size_ext(fi) {
var fileObj;
var fts = fi.value.toLowerCase();
fts = fts.slice(fts.lastIndexOf(".") + 1);
if (fts == "gif" || fts == "png" || fts == "jpg" || fts == "jpeg"){
if (typeof ActiveXObject == "function") { // для IE
fileObj = (new ActiveXObject("Scripting.FileSystemObject")).getFile(fi.value);
} else {fileObj = fi.files[0];}
if(fileObj.size > 6 * 1024 * 1024){ // если больше 6 Мбайт
alert('Размер файла не должен превышать 6 Мбайт');
fi.parentNode.innerHTML = fi.parentNode.innerHTML; // очистить поле выбора файла
$('#fpic').on("change", function() {valid_size_ext(this);}); // заново зарегистрировать обработчик события
}
} else {
alert("Выберите фотографию в формате jpg, png, gif");
fi.parentNode.innerHTML = fi.parentNode.innerHTML; // очистить поле выбора файла
$('#fpic').on("change", function() {valid_size_ext(this);}); // заново зарегистрировать обработчик события
}
}
$('#fpic').change(function() {valid_size_ext(this);}); // запуск проверки при выборе файла картинки
var is = confirm("Подтвердить удаление?"); // выведет всплывающее окно подтверждения
if (is == true) { // если нажата кнопка ОК
// свой код
}
st = prompt('Введите название города', 'Москва'); // выведет всплывающее окно с полем ввода текста, где Москва - текст по умолчанию
if (st != '' && st != null) {
console.log(st); // выведет введённую строку
}
// удалить атрибут oncontextmenu у тега body
$("body").removeAttr("oncontextmenu");
// отменить вызов стандартного контекстного меню для элементов с классом cart
$(".cart").contextmenu(function(){return false;});
$("body").on("mousedown", function (event) {
var x = event.pageX; // координата по горизонтали (соответствует left)
var y = event.pageY; // координата по вертикали (соответствует top)
});
$("#banner").click(function(event) {
var offset = $(this).offset();
var relativeX = (event.pageX - offset.left); // относительная координата по горизонтали (соответствует left)
var relativeY = (event.pageY - offset.top); // относительная координата по вертикали (соответствует top)
});
var s = $(window).scrollTop();
function myscroll(el) {
var scrollTop = $(el).offset().top; // top элемента относительно документа
$(document).scrollTop(scrollTop); // скроллим страницу до этой позиции
}
myscroll('#banner'); // запуск скролла до элемента с id = banner
$("body,html").animate({scrollTop: 0}, 800); // крутит страницу наверх за 0.8 секунды
<div>что-то<p>клик</p>что-то</div>
$("div").click(function(event){ // при клике на p вложенный в div (c обработчиком клика установленного на div)
el = $(this); // ссылка на div
el2 = $(event.target); // ссылка на p
});
document.querySelector('#frm').submit();
window.addEventListener('resize', myfunc, false); // установить обработчик
window.removeEventListener('resize', myfunc, false); // для удаления обработчика необходимо указать ту же самую функцию
function myfunc() {
// какой-то код
}
// сработает только если DOM уже загружен
window.scrollBy(0, -80); // прокрутить страницу на 80px вверх от текущего положения скролла
window.scrollTo(0, 0); // прокрутит страницу наверх (в начало) документа
e = document.querySelector("#sum");
e.scrollIntoView(true); // прокрутит страницу так, что элемент #sum окажется вверху
e.scrollIntoView(false); // прокрутит страницу так, что элемент #sum окажется внизу
document.body.style.overflow = "hidden"; // запретить прокрутку страницы (она замрёт в текущем положении)
document.body.style.overflow = ""; // разрешить прокрутку страницы
var scrollTop = window.pageYOffset || document.documentElement.scrollTop; // кроссбраузерное положение скролла по вертикали
var scrollLeft = window.pageXOffset || document.documentElement.scrollLeft; // кроссбраузерное положение скролла по горизонтали
$("body").on("mousedown", "#psk", function (event) {
if (event.which === 1) { // нажата левая кнопка мыши
// свой код
}
if (event.which === 2) { // нажата средняя кнопка мыши
// свой код
}
if (event.which === 3) { // нажата правая кнопка мыши
// свой код
}
});
$("body").on("mouseup", "#psk", function (event) {
if (event.which === 1) { // отпущена левая кнопка мыши
// свой код
}
if (event.which === 2) { // отпущена средняя кнопка мыши
// свой код
}
if (event.which === 3) { // отпущена правая кнопка мыши
// свой код
}
});
$("a").click(function(event) {
event.preventDefault(); // при клике по ссылкам в документе переход по ним происходить не будет
alert(event.type); // вместо этого будет показан тип события
});
$("#name").on("change keyup input paste click", function() { // сработает при изменении, вставки из буфера обмена или отпускании клавиши на элементе
myfunc(); // функция которая что-то сделает в этом случае
});
// не позволяет вводить ничего кроме цифр в текстовое поле с id = dd (вырезает все символы не являющиеся цифрами)
$('#dd').on("change keyup input paste click", function() {
if (this.value.match(/[^0-9]/g)) {
this.value = this.value.replace(/[^0-9]/g, '');
}
});
// позволяет вводить всё кроме следующих букв "аиоуыэеёйюяьъАИОУЫЭЕЁЙЮЯЬЪ" в текстовое поле с id = dd2 (вырезает их)
$('#dd2').on("change keyup input paste click", function() {
if (this.value.match(/[аиоуыэеёйюяьъАИОУЫЭЕЁЙЮЯЬЪ]/g)) {
this.value = this.value.replace(/[аиоуыэеёйюяьъАИОУЫЭЕЁЙЮЯЬЪ]/g, '');
}
});
// нумерация элементов в nth-child, nth-child-last начинается от 1
$("#town option:nth-child(1)").attr("selected", "selected"); // будет выбран первый option в списке select
$("#town :nth-child(2)").attr("selected", "selected"); // будет выбран 2-й элемент с начала
$("#town :nth-child-last(2)").attr("selected", "selected"); // будет выбран 2-й элемент с конца
// вернуть позиции каретки
function getCaretPosition(ctrl) {
var start, end;
if (ctrl.setSelectionRange) {
start = ctrl.selectionStart;
end = ctrl.selectionEnd;
} else if (document.selection && document.selection.createRange) {
var range = document.selection.createRange();
start = 0 - range.duplicate().moveStart('character', -100000);
end = start + range.text.length;
}
return {start: start, end: end}
}
$("body").on("click", "#txt", function () {
caret = getCaretPosition(this);
result = /S+$/.exec(this.value.slice(0, this.value.indexOf(' ',caret.end)));
lastWord = result ? result[0] : null;
lastWord = trim_smb(lastWord, ', '); // вернёт слово без запятых и пробелов в начале и конце слова
});
Динамические манипуляции с элементами DOM
$("#town option:nth-child(3)").after($('<option value="Voronezh">Воронеж</option>'));
$("<div>", {id: "psk", text: "Привет!", css: {"left":"100px", "top":"120px"}}).appendTo("body"); // создает div с заданием id, текста, стилей
$("<div>", {id: "psk", css: {"left":"100px", "top":"120px"}, html: '<strong>Мой html</strong>'}).appendTo("body"); // создает div с заданием id, стилей, html-кода
$("<div>", {class: "psk", css: {"left":"100px", "top":"120px"}, append: $('<span>', {id: 'el1', text: 'дочерний элемент1'})}).appendTo("body"); // создает div с заданием class, стилей, дочернего элемента
$("<div>", {id: "qq", on: {click: function(e){alert('клик');}}}).appendTo("body"); // создает div c заданием id и обработчиком события click
$("<div>", {id: "qq", on: {scroll: function(e){alert('скролл');}}}).appendTo("body"); // создает div c заданием id и обработчиком события scroll - скроллинга
$("<input>", {type: "checkbox"}).prependTo("#sl ol li"); // создать чекбокс
$(this).before('<a name="k1"></a>'); // поставим метку перед указанным элементом
$(this).after('<a name="k2"></a>'); // поставим метку после указанного элемента
$('#my1').appendTo('#cont'); // запишет элемент my1 внутрь элемента cont в самом его конце
$('#my2').prependTo('#cont'); // запишет элемент my2 внутрь элемента cont в самом его начале
$('#cont').append( $('#my1').parent("li") ); // перемещаем элемент внутрь cont в самом его конце
$('#cont').prepend( $('#chbb').html() ); // перемещаем содержимое внутрь cont в самом его начале
el = $(".hello").clone(); // клонирует элемент hello со всем его содержимым в переменную el
$(".hello").clone().appendTo(".container"); // скопирует элемент hello в конец элемента container, при этом оригинальный hello также останется на своём старом месте
el3 = el2.cloneNode(true); // клонировать элемент на чистом javascript, с true - скопирует элемент вместе с вложенными в него элементами
$("#psk").remove();
$('span').wrap('<p class="red"></p>'); // обернёт каждый span на странице в тег <p> с классом red
$('span').wrap('<div><p><b><i></i></b></p></div>'); // обернёт каждый span на странице в группу тегов <div><p><b><i>
$('span').wrap(function(i){return '<p id="qq' + (i + 1) + '"></p>';}); // обернёт каждый span на странице в тег <p> с уникальным id
$('span').unwrap(); // удалит всех родителей у элементов span на странице
$('span').unwrap('.test'); // удалит всех родителей у элементов span на странице, если родитель имеет класс test
$('span').unwrap('p'); // удалит всех родителей у элементов span на странице, если родитель это тег <p>
<table id="my_tbl">
<tr><td>1</td><td>2</td><td>3</td></tr>
<tr><td>1</td><td>2</td><td>3</td></tr>
<tr><td>1</td><td>2</td><td>3</td></tr>
</table>
// вставит новый столбец перед 1-ым столбцом
$('#my_tbl').find('tr').each(function(){
$(this).find('td:eq(0)').before('<td>0</td>');
});
// вставит новый столбец после 1-го столбца
$('#my_tbl').find('tr').each(function(){
$(this).find('td:eq(0)').after('<td>1a</td>');
});
// вставит новый столбец после последнего столбца
$('#my_tbl').find('tr').each(function(){
$(this).find('td:eq(-1)').after('<td>4</td>');
});
$('#my_tbl').prepend('<tr><td>1</td><td>2</td><td>3</td></tr>'); // вставит строку в начале таблицы
$('#my_tbl').append('<tr><td>1</td><td>2</td><td>3</td></tr>'); // вставит строку в конце таблицы
$('#my_tbl').find('tr:eq(0)').after('<tr><td>1</td><td>2</td><td>3</td></tr>'); // вставит строку после первой строки в таблице
// дожидается загрузки картинки
function waitForImage(imgElem) {
return new Promise(res => {
if (imgElem.complete) {return res();}
imgElem.onload = () => res();
imgElem.onerror = () => res();
});
}
myfunc= async () => {
let img = new Image();
img.src = 'https://site.ru/pic.jpg';
await waitForImage(img); // дождёмся загрузки картинки
console.log('1'); // этот код выполнится только после того, как картинка загрузится в элемент img
}
myfunc();
Получение данных с сервера
id = 5; sl = 'тест'; // переменные для передачи в php-скрипт
$.ajax({
type: "POST",
url: "https://domain.ru/script.php",
data: {'id':id, 'sl':sl},
success: function(msg){
alert(msg); // выведем результат, пришедший от сервера
}
});
// синхронный ajax запрос будет дожидаться ответа от сервера, делая на это время страницу недоступной для пользователя
id = 5; sl = 'тест'; // переменные для передачи в php-скрипт
$.ajax({
type: 'POST',
url: "https://domain.ru/script.php",
data: {'id':id, 'sl':sl},
async: false, // будем выполнять синхронно
success: function(msg){
alert(msg); // выведем результат, пришедший от сервера
}
});
$.ajax({
url : "https://domain.ru/hello.txt",
dataType: "text",
success : function (msg) {
$("#txt").html(msg);
}
});
myfunc = async () => {
let response = await fetch('https://api.site.com/price');
if (response.ok) { // если HTTP-статус в диапазоне 200-299
let json = await response.json();
console.log(json);
} else {alert("Ошибка HTTP: " + response.status);}
}
myfunc();
st = {name: 'John', age: 30, isAdmin: false, courses: ['html', 'css', 'js'], wife: null, group: {first: 'tree', second: 'wood'}};
str = JSON.stringify(st); // закодирует массив в json
sn = JSON.parse(str); // раскодирует массив из json
a = sn['age']; // выведет 30
b = sn['group']['second']; // выведет wood
Обработка строк
str = " привет ";
pm = $.trim(str); // вернет: 'привет'
s = str.replace( /^\s+/g, '').replace( /\s+$/g, ''); // вернет: 'привет'
// удалить группу заданных символов в начале и в конце строки
function trim_smb(st, smb) {
arb = smb.split('');
ars = st.split('');
al = ars.length;
zi = -1; zi2 = -1;
for (i = 0; i < al; i++) {if (arb.indexOf(ars[i]) > -1) {zi = i;} else {break;}}
for (i = al-1; i >= 0; i--) {if (arb.indexOf(ars[i]) > -1) {zi2 = i;} else {break;}}
if (zi2 == -1) {zi2 = al;}
return st.substring(zi+1, zi2);
}
st = '% %#category/rrr/ddd/www/product1= /';
st = trim_smb(st, '% =/'); // удалит все символы % =/ в начале и в конце строки
console.log(st); // вернёт: #category/rrr/ddd/www/product1
q = " пр ив ет ";
q = q.replace(/\s/g, ''); // вернет: 'привет'
// нумерация начинается от 0. Позиция первого символа - включается, позиция последнего символа не включается
var str = "Моя строка"
str.substring(0,3) // Моя (позиция1 д.б < позиция2)
str.substring(3,0) // Моя (если позиция1 > позиция2, то это равносильно тому, что позиция1 < позиция2)
str.substring(1,2) // о
str.substring(4) // "строка" (если позиция2 не задана, то возвращает до конца строки)
// нумерация начинается от 0
var str = "abcdefghij";
str.substr(1,2); // выведет bc
str.substr(-3,2); // выведет hi (если позиция < 0, то отсчёт начинается с конца строки)
str.substr(-3); // выведет hij (если длина не задана, то возвращает до конца строки)
str.substr(1); // выведет bcdefghij
str.substr(-20,2); // выведет ab (если позиция < 0 и позиция по модулю > длины строки, то позиция = 0)
str.substr(20,2); // выведет "" (если позиция > длины строки, то возвращает пустую строку)
a = str[3]; // выведет d, строка рассматривается как массив символов, к которым можно получить доступ по их индексу в строке (не работает в IE 8.0 и ниже)
b = str.charAt(3); // выведет d
str = text.toLowerCase(); // возвратит все символы строки в нижнем регистре
str = text.toUpperCase(); // возвратит все символы строки в верхнем регистре
str = str.charAt(0).toUpperCase() + str.substr(1).toLowerCase(); // возвратит первый символ строки в верхнем регистре, остальные - в нижнем
s = "лето ах лето";
a = s.replace("лето", "зима"); alert(a); // выведет "зима ах лето"
b = s.replace(/лето/g, "зима"); alert(b); // выведет "зима ах зима"
c = s.replace(new RegExp("лето",'g'), "зима"); alert(c); // выведет "зима ах зима"
d = s.split('лето').join('зима'); alert(d); // выведет "зима ах зима"
str = str.replace(/[^0-9]/g, '');
str = '12345678123';
p1 = str.indexOf("3"); // вернет 2
p2 = str.indexOf("3", 4); // вернет 10 так как начало искать с 4 символа
p3 = str.lastIndexOf("1"); // вернет 8
p4 = str.lastIndexOf("9"); // вернет -1 так как 9 не найдено
str2 = '#comment-4345';
reg = new RegExp('#comment-','i'); // для поиска без учета регистра символов
alert(reg.test(str2)); // вернет true, так как #comment- присутствует в #comment-4345
// функция возвращает массив из найденных позиций
function str_in_str(s, sp) {
let p = -1, o = 0, m = [];
while ((p = s.indexOf(sp, o)) != -1) {
m.push(p); o = p + 1;
}
return m;
}
s = 'Лето, ах лето, лето красное будь со мной.';
m = str_in_str(s, 'лето'); alert(m); // вернет 9,15 - найденные позиции для 'лето' (первое 'Лето' не найдено, так как поиск с учетом регистра символов)
// функция возвращает позицию первого найденного в строке элемента массива, если ни один элемент массива в строке не найден, то возвращается false
function strpos_arr(st, ar) { // поиск массива подстрок в строке
lng = ar.length;
let ps = -1;
for (i = 0; i < lng; i++) {
ps = st.indexOf(ar[i]);
if(ps > -1) {break;}
}
if(ps > -1) {return ps;} else {return false;}
}
st = 'стр3ока';
ar = ['q','r','j'];
ar2 = ['q','r','3'];
strpos_arr(st, ar); // вернет false, так как ничего не найдено
strpos_arr(st, ar2); // вернет 2 - позиция символа 3-ки
st = 'Мохнатый шмель';
a1 = st.startsWith('Мохнатый'); // вернёт: true
a2 = st.startsWith('шмель'); // вернёт: false
let st = 'abcdef';
let d = st.length; // выведет 6
function sklonenie(n, s){
if (s == 1) {words = [' год',' года',' лет'];}
if (s == 2) {words = [' месяц',' месяца',' месяцев'];}
if (s == 3) {words = [' день',' дня',' дней'];}
return words[(n=(n=n%100)>19?(n%10):n)==1?0 : ((n>1&&n<=4)?1:2)];
}
p = 1; a = p + sklonenie(p, 3); // 1 день
p = 22; b = p + sklonenie(p, 2); // 22 месяца
p = 19; c = p + sklonenie(p, 1); // 19 лет
str = 'qwe$asd$zxc';
arr = str.split('$'); // разобьет строку в массив по разделителю "$"
alert(arr[1]); // выведет asd
st = 'строка';
ar = st.split(''); // создаст массив ar = ['с','т','р','о','к','а'];
let z = 'Привет\u0020медвед!'; alert(z); // выведет "Привет медвед!"
v = 'привет\nмедвед'; alert(v); // выведет
"привет
медвед" - в 2 строки
v = v.split("\n").join("+"); alert(v); // выведет "привет+медвед"
st = st.replace(/&/g, "&"); // преобразует все символы & в строке в &
st = st.replace(/</g, "<"); // преобразует все символы < в строке в <
st = st.replace(/>/g, ">"); // преобразует все символы > в строке в >
// генерирует случайный набор букв на английском
function makeid(length) {
let result = '';
const characters = 'abcdefghijklmnopqrstuvwxyz';
const charactersLength = characters.length;
let counter = 0;
while (counter < length) {
result += characters.charAt(Math.floor(Math.random() * charactersLength));
counter += 1;
}
return result;
}
q = makeid(8); // вернёт 8 маленьких английских букв в случайном порядке
Работа с массивами
var arr = []; // создать пустой массив
var arr = ["Яблоко", "Апельсин", "Слива"]; // создать массив (нумерация массива начинается с индекса 0 автоматически)
arr[9] = 5; // задать значение массива по индексу
k = arr[0]; // присвоить значение переменной по индексу массива
r = arr.length; // узнать длину массива - количество элементов массива включая пустые элементы (считает как последний индекс + 1)
var arr = ["Яблоко", "Апельсин", "Слива"];
dm = arr.push("лето"); // создает элемент массива записывая его в конец - с индексом на 1 больше, чем у последнего элемента массива (возвращает длину массива)
dm = arr.unshift("зима"); // создает элемент массива записывая его в начало (к индексам других элементов прибавляется 1) (возвращает длину массива)
dm = arr.push("лето", "осень"); // запишет в конец массива 2 новых элемента
dm = arr.unshift("зима", "весна"); // запишет в начало массива 2 новых элемента
le = arr.pop(); // удаляет последний элемент из массива (возвращает удалённый элемент)
fe = arr.shift(); // удаляет первый элемент из массива (возвращает удалённый элемент)
let a = [1, 2, 3];
let b = 1;
Array.isArray(a); // вернёт true
Array.isArray(b); // вернёт false
let arr = ['лето', 'зима', 'весна'];
let arr2 = [5, 7, 9];
// удалить из массива элемент по ключу, при этом длина массива останется прежней arr.length покажет ту же длину, что и до удаления элемента
delete arr[1]; // массив станет ["лето", undefined, "весна"]
delete arr2[1]; // массив станет [5, undefined, 9]
// но в переборе методом for элемента не будет
for(key in arr) {console.log(key + " = " + arr[key]);} // вернёт: 0 = лето, 2 = весна
for(key in arr2) {console.log(key + " = " + arr2[key]);} // вернёт: 0 = 5, 2 = 9
// начиная с индекса 1, удалить 1 элемент (удалить элемент с ключом 1)
arr.splice(1, 1); // массив станет ["лето", "весна"]
let m = [[0,0,0],[0,0,0],[0,0,0]]; // создать многомерный массив (матрицу) 3х3 заполненную нулями
d = m[1][1]; // получить центральный элемент матрицы
m[2][1] = 7; // изменить значение предпоследнего элемента матрицы
let u = [];
if (typeof u[5] === "undefined") {
alert('Элемент с ключом 5 в массиве u не существует');
}
// 1 параметр - позиция, 2 параметр - количество элементов, 3 параметр - новые элементы массива (вставляются начиная с позиции, указанной в 1 параметре)
var m = [1, 2, 3, "x", "y", "z"]; // создать массив
m.splice(3); // станет [1, 2, 3]
m.splice(-2); // станет [1, 2, 3, "x"]
m.splice(2, 2); // станет [1, 2, "y", "z"]
m.splice(-2, 1); // станет [1, 2, 3, "x", "z"]
m.splice(0, 2, "j", true); // станет ["j", true, 3, "x", "y", "z"]
m.splice(3, 0, "w", "w", "w"); // станет [1, 2, 3, "w", "w", "w", "x", "y", "z"]
m = m.filter(function(f) { return f !== 'значение' }); // удалить из массива элемент по его значению (если в массиве есть несколько таких значений, то удалит их все)
d1 = [];
d1.push(['Год', 'Количество']);
m = [['2020', 7], ['2021', 5], ['2022', 9], ['2023', 11]];
// 1-й вариант
d = [...d1, ...m];
console.log(d); // выведет: [["Год", "Количество"], ["2020", 7], ["2021", 5], ["2022", 9], ["2023", 11]]
// 2-й вариант
d2 = d1.concat(m);
console.log(d2); // выведет: [["Год", "Количество"], ["2020", 7], ["2021", 5], ["2022", 9], ["2023", 11]]
// числа, булевы и строки - хранятся и сравниваются по значению
// объекты и массивы - хранятся и сравниваются по ссылке
m = [0, 1, 2, 3];
m2 = m;
m3 = [...m]; // добавим массив к пустому массиву, тем самым скопировав его
m[0] = 7;
console.log(m2); // вернёт: [7, 1, 2, 3] - так как присвоение массива m2 = m; передаётся по ссылке, а не по значению; а по значению ожидался бы массив [0, 1, 2, 3]
console.log(m3); // вернёт: [0, 1, 2, 3] - так как мы принудительно присвоили массив по значению
// при этом надо помнить, что вложенные массивы всё равно будут передаваться по ссылке
mm = [[0, 1], [2, 3], [4, 5], [6, 7]];
mm3 = [...mm]; // добавим массив к пустому массиву, тем самым скопировав его
// присвоить все вложенные массивы по значению
mm4 = [];
for(key in mm) {
if (typeof mm4[key] === "undefined") {mm4[key] = [];}
mm4[key] = [...mm[key]];
}
mm[0][1] = 11;
console.log(mm3); // вернёт: [[0, 11], [2, 3], [4, 5], [6, 7]] - так как вложенные массивы всё равно передаются по ссылке
console.log(mm4); // вернёт: [[0, 1], [2, 3], [4, 5], [6, 7]] - так как мы принудительно присвоили все вложенные массивы по значению
// функция принимает в качестве параметра массив и возвращает новый массив с перемешанными элементами (ключи нового массива идут по порядку начиная с 0)
function shuffle(m) {
let dm = m.length;
for(var j, x, i = dm; i; j = parseInt(Math.random() * i), x = m[--i], m[i] = m[j], m[j] = x);
return m;
};
let ra = shuffle([1, 2, 3, 4, 5]); // вернёт массив с перемешанными элементами наподобие [3, 5, 1, 4, 2]
var myArray = {}; // создать пустой ассоциативный массив
var myArray2 = {'sex': 1, 'name': 'John', 'fam': 'Ivanov'};
myArray["ключ1"] = "значение1"; // задать значение ассоциативного массива по строковому ключу
k = myArray["ключ1"]; // присвоить значение переменной по ключу ассоциативного массива
r = Object.keys(myArray).length; // узнать количество элементов (длину) ассоциативного массива
alert(myArray2.name); // выведет John
let arr = {'лето': 5, 'зима': 7, 'весна': 9};
delete arr['зима'];
for(key in arr) {console.log(key + " = " + arr[key]);} // вернёт: лето = 5, весна = 9
let arr = {0: ['white', 'зима'], 50: ['green', 'весна'], 100: ['yellow', 'лето'], 200: ['orange', 'осень']};
for(key in arr) {console.log(key + " = " + arr[key][0] + ' и ' + arr[key][1]);}
// вернёт:
// 0 = white и зима
// 50 = green и весна
// 100 = yellow и лето
// 200 = orange и осень
revs = Object.keys(arr).reverse(); // создаст массив из ключей массива arr в инвертированном порядке
revs.forEach(function(item, i, revs) {console.log(item + ": " + arr[item][0] + ' и ' + arr[item][1]);});
// вернёт:
// 200: orange и осень
// 100: yellow и лето
// 50: green и весна
// 0: white и зима
let arr = {'зима': 5, 'весна': 7, 'лето': 9};
revs = Object.keys(arr).reverse(); // создаст массив из ключей массива arr в инвертированном порядке: ['лето', 'весна', 'зима']
let m = {'x': {'b': 0, 'r': 0, 's': 0}, 'y': {'b': 0, 'r': 0, 's': 0}, 'z': {'b': 0, 'r': 0, 's': 0}}; // создать 2-мерный ассоциативный массив заполненный нулями
m['y']['r'] = 5; // задать значение ассоциативного массива по двум строковым ключам
function lastElAMass(m) {
for(key in m) {f = m[key]; d = key;}
return [f, d];
}
let m = {'z': 1, 's': 2, 'r': 3, 'b': 4, 'a': 5};
q = lastElAMass(m);
console.log(q[0] + ' ' + q[1]); // вернёт: 5 a
arl = arr.length;
for (i = 0; i < arl; i++) {
alert(arr[i]);
}
// цикл for c заданием шага отличным от 1, например 7
for (i = 0; i < 100; i = i + 7) {
console.log(i); // выведет 0, 7, 14, 21, 28 и т. д.
}
mf = {'bn': 7, 'nk': 4, 'ns': 9};
nk = 0;
for(j in mf){nk = nk + (+mf[j]);}
console.log(nk); // выведет 20
for(key in myArray) {
alert(key + " = " + myArray[key]);
}
var i = 0;
while (i < 3) {
alert(i);
i++;
}
var i = 0;
do {
alert(i);
i++;
} while (i < 3);
var a = [1, 2, 3, 4, 2, 5, 6, 2, 3, 6];
var b = [2, 3];
var c = a.filter(x => !b.includes(x));
alert(c.join()); // выведет 1,4,5,6,6
mm = [1,22,-1,6,111,7,2,5,-2];
sm = mm.map(j=>x+=j, x=0).reverse()[0];
console.log(sm); // вернёт: 151
var a = [1, 2, 3, 4];
q = a.join(); // выведет 1,2,3,4
w = a.join(""); // выведет 1234
e = a.join(" : "); // выведет 1 : 2 : 3 : 4
var ms = []; // объявление массива
ms[0] = {id: "1", name: "John"};
ms[1] = {id: "2", name: "Mary"};
let m = [
[2, 4, 3, 1],
[3, 1, 4, 2],
[2, 3, 1, 4]
];
m.sort(function (a, b) {
return a[0] - b[0] || a[1] - b[1] || a[2] - b[2] || a[3] - b[3];
});
console.log(m); // возвратит массив отсортированный по 4-м полям: сперва по 1-му, потом по 2-му, потом по 3-му, потом по 4-му
[
[2, 3, 1, 4],
[2, 4, 3, 1],
[3, 1, 4, 2]
];
var ms = []; // объявление массива
ms.push({id: "15", name: "John", fam: "Петров", dat: "2001-12-30"});
ms.push({id: "2", name: "Mary", fam: "иванова", dat: "1999-07-23"});
ms.push({id: "7", name: "Opra", fam: "Ёжова", dat: "2020-04-03"});
ms.push({id: "12", name: "july", fam: "Арбузова", dat: "2019-11-17"});
ms.push({id: "5", name: "Dory", fam: "Иванова", dat: "1998-01-05"});
ms.sort(function(a,b) {return a.id - b.id;}); // сортировать по числовому ключу по возрастанию
ms.sort(function(a,b) {return b.id - a.id;}); // сортировать по числовому ключу по убыванию
var collator = new Intl.Collator('en'); // Collator для английского языка
ms.sort(function(a, b) {return collator.compare(a.name, b.name);}); // сортировать по строковому ключу на английском языке по возрастанию
ms.sort(function(a, b) {return collator.compare(a.name, b.name);}); // сортировать по строковому ключу на английском языке по убыванию
let collator2 = new Intl.Collator(); // Collator для текущего (русского) языка
ms.sort(function(a, b) {return collator2.compare(a.fam, b.fam);}); // сортировать по строковому ключу на русском языке по возрастанию
ms.sort(function(a, b) {return collator2.compare(b.fam, a.fam);}); // сортировать по строковому ключу на русском языке по убыванию
ms.sort(function(a,b) { // сортировать по ключу с датой по возрастанию
var adt = new Date(a.dat); var bdt = new Date(b.dat);
return (adt < bdt) ? -1 : (adt > bdt) ? 1 : 0;});
ms.sort(function(a,b) { // сортировать по ключу с датой по убыванию
var adt = new Date(a.dat); var bdt = new Date(b.dat);
return (bdt < adt) ? -1 : (bdt > adt) ? 1 : 0;});
ms.forEach(function(item, i, ms) { // вывод отсортированного массива в консоль
console.log(item.id + ' : ' + item.name + ' : ' + item.fam + ' : ' + item.dat);
});
// сортировка с учётом текущей языковой локали (если в обычной сортировке любая строчная буква больше любой заглавной буквы (б > Я), то здесь (я > Я), но (б < Я))
let animals = ["тигр", "ёж", "енот", "ехидна", "АИСТ", "ЯК"];
let collator = new Intl.Collator(); // использует текущую локаль, различает регистр символов, е ≠ ё, Ёж ≠ ёж
let collator2 = new Intl.Collator(undefined, {sensitivity: "accent"}); // использует текущую локаль, не различает регистр символов, е ≠ ё, Ёж = ёж
animals.sort(function(a, b) {return collator.compare(a, b);});
alert(animals); // выведет: АИСТ,ёж,енот,ехидна,тигр,ЯК
// стандартная сортировка
let animals2 = ["тигр", "ёж", "енот", "ехидна", "АИСТ", "ЯК"];
alert(animals2.sort()); // выведет: АИСТ,ЯК,енот,ехидна,тигр,ёж
function srt(p) {
let coll = new Intl.Collator(), keys = [], sobj = {};
for(k in p){keys.push(k);}
keys.sort(function(a, b) {return coll.compare(a, b);});
let kl = keys.length;
for (i = 0; i < kl; i++) {sobj[keys[i]] = p[keys[i]];}
return sobj;
}
var prod = {};
prod["Растительное масло"] = [80, 74];
prod["Сахар"] = [6.55, 5];
prod["Мука"] = [8.47, 5];
prod = srt(prod); // отсортируем продукты по алфавиту
mn2 = {};
mn2['a'] = 10;
mn2['b'] = 3;
mn2['c'] = 7;
mn2['d'] = 5;
mn2['e'] = 12;
mn3 = Object.keys(mn2).sort(function(a,b){return mn2[b]-mn2[a]});
console.log(mn3); // выведет ключи в отсортированном по убыванию порядке: e, a, c, d, b
let m = {};
for(key in mn3) {m[mn3[key]] = mn2[mn3[key]];}
mn1 = Object.keys(mn1).sort(function(a,b){return mn1[b]-mn1[a]}); // создаст массив из ключей ассоциативного массива отсортированных в порядке убывания соответствующих им значений
mn2 = Object.keys(mn2).sort(function(a,b){return mn2[a]-mn2[b]}); // создаст массив из ключей ассоциативного массива отсортированных в порядке возрастания соответствующих им значений
arr.forEach(function(item, i, arr) { // где item - элемент массива, i - его индекс, arr - сам массив
alert( i + ": " + item);
});
var arr = ["один", "два", "три", "четыре", "пять"];
$.each(arr, function(index, value) { // где value - элемент массива, index - его индекс, arr - сам массив
console.log("INDEX: " + index + " VALUE: " + value);
});
// выход из одного цикла
let i = 0; let sum = 0;
while (true) { // объявим вечный цикл
i++;
if (i > 4) {break;} // прервём цикл
sum += i;
}
alert(sum); // выведет 10 - сумма 1 + 2 + 3 + 4
// выход из foreach не предусмотрен, для этого нужно использовать цикл for
arr.forEach(function(item, i, arr) {
// переберёт все элементы массива до конца
});
// выход из нескольких циклов
let i = 0; let sum = 0;
outer: // объявим метку перед циклом, из которого нужно будет выйти в теле одного из вложенных циклов
while (true) { // объявим вечный цикл
i++;
for (let j = 1; j <= 3; j++) {
if (i == 2 && j == 2) {break outer;} // прервём несколько циклов (в данном примере 2)
sum += i * j;
}
}
alert(sum); // выведет 8 - сумма 1*1 + 1*2 + 1*3 + 2*1
// узнать входит ли, присутствует ли элемент в массиве
var an = ['dog', 'cat', 'fish'];
an[7] = 'duck'
alert(an.indexOf('duck')); // вернет 7 - индекс элемента duck
alert(an.indexOf('cow')); // вернет -1, так как элемента cow отсутствует в массиве
alert(an.indexOf('dog') != -1); // вернет true так как элемент dog присутствует в массиве под индексом 0
alert(an.indexOf('cow') != -1); // вернет false так как элемент cow отсутствует в массиве
an.includes('cat') // вернёт true
an.includes('cow') // вернёт false
// вернуть ключ первого или последнего элемента ассоциативного массива исходя из порядка, в котором элементы добавлялись в массив
function get_as_key(d, k) {
f = 0;
for (p in d) {f = f + 1; if (f == 1) {a = p;} b = p;}
if (k == 'f') {r = a;} else if (k == 'l') {r = b;}
return r;
}
v = {'лето': 5, 'весна': 5, 'осень': 5, 'зима': 5};
fk = get_as_key(v, 'f'); // получить ключ первого элемента
console.log(fk); // выведет: лето
lk = get_as_key(v, 'l'); // получить ключ последнего элемента
console.log(lk); // выведет: зима
vg = ["лето", "зима", "осень", "весна"];
var le = vg.pop(); // равен "весна"
// теперь массив выглядит так vg = ["лето", "зима", "осень"]
vg2 = ["лето", "зима", "осень", "весна"];
var my = vg2.shift(); // равен "лето"
// теперь массив выглядит так vg2 = ["зима", "осень", "весна"]
v = {'2022': 5, '2021': 5, '2023': 5, '2020': 5};
mx = Math.max.apply(null, Object.keys(v)); // вернёт: 2023
mx = Math.min.apply(null, Object.keys(v)); // вернёт: 2020
function getMinMax(ar, z) { // получить максимальное и/или минимальное значение ассоциативного массива и его ключ
let f = 0;
for(key in ar) {
f = f + 1;
if (f == 1) {max = ar[key]; max_k = key; min = ar[key]; min_k = key;}
if (max < ar[key]) {max = ar[key]; max_k = key;}
if (min > ar[key]) {min = ar[key]; min_k = key;}
}
if (z == 1) {r = [min, min_k];}
else if (z == 2) {r = [max, max_k];}
else if (z == 3) {r = [min, min_k, max, max_k];}
return r;
}
vg = ["лето": 5, "зима": 1, "осень": 3, "весна": 2];
alert(getMinMax(vg, 1)); // вернёт минимальное: 1,зима
alert(getMinMax(vg, 2)); // вернёт максимальное: 5,лето
alert(getMinMax(vg, 3)); // вернёт минимальное и максимальное: 1,зима,5,лето
vg2 = [5, 7, 6, 2, 4];
alert(getMinMax(vg2, 1)); // вернёт минимальное: 2,3
ar = [1, 5, 6, 2, 3];
m1 = Math.min(...ar);
m2 = Math.max(...ar);
console.log(m1); // вернёт: 1
console.log(m2); // вернёт: 6
m = [1, 2, 3, 4, 5];
m = m.reverse();
console.log(m); // вернёт: [5, 4, 3, 2, 1]
Работа с числами
// разделение групп разрядов целого положительного числа
function rgr_int(d) {return String(d).replace(/[^d]/g, '').replace(/B(?=(?:d{3})+(?!d))/g, ' ');}
// разделение групп разрядов положительного числа с плавающей точкой
function rgr_float(d) {
d = String(d).replace(/[^d.]/g, '');
d2 = '';
if (d.indexOf(".") != '-1') {m = d.split('.'); d = m[0]; d2 = '.' + m[1];}
d = d.replace(/B(?=(d{3})+(?!d))/g, ' ') + d2;
return d;
}
d = rgr_int(11234567); // вернёт 11 234 567
d2 = rgr_float(11234567.1542); // вернёт 11 234 567.1542
h1 = Math.ceil(5.2); // вернет 6 - округляет в большую сторону
h2 = Math.round(5.2); // вернет 5 - округляет по математическим правилам
h2 = Math.round(5.5); // вернет 6 - округляет по математическим правилам
h3 = Math.floor(5.2); // вернет 5 - округляет в меньшую сторону
// добавление функций округления до разрядов чисел
(function() {
function decimalAdjust(type, value, exp) {
// Если степень не определена, либо равна нулю...
if (typeof exp === 'undefined' || +exp === 0) {
return Math[type](value);
}
value = +value;
exp = +exp;
// Если значение не является числом, либо степень не является целым числом...
if (isNaN(value) || !(typeof exp === 'number' && exp % 1 === 0)) {
return NaN;
}
// Сдвиг разрядов
value = value.toString().split('e');
value = Math[type](+(value[0] + 'e' + (value[1] ? (+value[1] - exp) : -exp)));
// Обратный сдвиг
value = value.toString().split('e');
return +(value[0] + 'e' + (value[1] ? (+value[1] + exp) : exp));
}
if (!Math.round10) { // Десятичное округление к ближайшему
Math.round10 = function(value, exp) {
return decimalAdjust('round', value, exp);
};
}
if (!Math.floor10) { // Десятичное округление вниз
Math.floor10 = function(value, exp) {
return decimalAdjust('floor', value, exp);
};
}
if (!Math.ceil10) { // Десятичное округление вверх
Math.ceil10 = function(value, exp) {
return decimalAdjust('ceil', value, exp);
};
}
})();
h1 = Math.ceil10(5.21, -1); // вернет 5.3 - округляет в большую сторону
h2 = Math.round10(5.2, 0); // вернет 5 - округляет по математическим правилам
h2 = Math.round10(5.555, -2); // вернет 5.56 - округляет по математическим правилам
h3 = Math.floor10(555.2, 2); // вернет 500 - округляет в меньшую сторону
a = 125.1234;
b = a.toFixed(3); // вернёт 125.123 - просто обрезает лишние цифры
// получить случайное целое число от минимума (включительно) до максимума (не включительно)
function getRandomNumber(min, max) {
return Math.floor(Math.random() * (max - min) + min);
}
a = x % y // вернёт остаток о целочисленного деления
12 % 5 // 2
-1 % 2 // -1
NaN % 2 // NaN
1 % 2 // 1
2 % 3 // 2
-4 % 2 // -0
5.5 % 2 // 1.5
let i = 2;
if (i%2 == 0) {alert('четное');} // проверка на четные числа, выведет 'четное'
let j = 5;
if (j%2 == 1) {alert('нечетное');} // проверка на нечетные числа, выведет 'нечетное'
// проверка на целое число
function is_number(p) {return /^\d+$/.test(p);}
// проверка на целое число, допускается отрицательное число
function is_number2(p){return /^[-]?\d+$/.test(p);}
// проверка на целое число
function is_number3(p) {
let t = p.length; let m = [0,1,2,3,4,5,6,7,8,9]; let n = true;
for (let i = 0; i < t; i++) {if (m.indexOf(+p.charAt(i)) == -1) {n = false; break;}} return n;
}
// проверка на целое число
function is_number4(p){
let a = [NaN, undefined, null, true, false, ''];
return (a.indexOf(p) != -1) ? false : isNaN(+p) ? false : (p < 0) ? false : ((+p ^ 0) === +p) ? true : false;
}
// проверка на целое число, допускается отрицательное число
function is_number5(p){
let a = [NaN, undefined, null, true, false, ''];
return (a.indexOf(p) != -1) ? false : isNaN(+p) ? false : ((+p ^ 0) === +p) ? true : false;
}
// проверка на число, допускается число с плавающей точкой (дробное)
function is_number6(p){
let a = [NaN, undefined, null, true, false, ''];
return (a.indexOf(p) != -1) ? false : isNaN(+p) ? false : (p < 0) ? false : true;
}
// проверка на число, допускается отрицательное число и число с плавающей точкой (дробное)
function is_number7(p){
let a = [NaN, undefined, null, true, false, ''];
return (a.indexOf(p) != -1) ? false : isNaN(+p) ? false : true;
}
// вывод с разделением групп разрядов
var formatter = new Intl.NumberFormat("ru");
alert(formatter.format(1234567890.123)); // 1 234 567 890,123
// вывод с разделением групп разрядов (вариант 2)
ssm = String(ssm).replace(/(\d)(?=(\d\d\d)+([^\d]|$))/g, '$1 ') + ' руб.';
alert(ssm); // 1 234 567 890.123 руб.
// вывод с ограничением значимых цифр (важны только первые 3)
var formatter = new Intl.NumberFormat("ru", {maximumSignificantDigits: 3});
alert(formatter.format(1234567890.123)); // 1 230 000 000
// вывод валюты
var formatter = new Intl.NumberFormat("ru", {style: "currency", currency: "GBP"});
alert(formatter.format(1234.5)); // 1 234,5 £
// вывод валюты с двумя цифрами после запятой
var formatter = new Intl.NumberFormat("ru", {style: "currency", currency: "USD", minimumFractionDigits: 2});
alert(formatter.format(1234.5)); // 1 234,50 $
console.log(new Intl.NumberFormat("ru-RU",{minimumIntegerDigits: 7}).format(-123)); // -0 000 123
console.log(new Intl.NumberFormat("ru-RU",{minimumIntegerDigits: 7, minimumFractionDigits: 5, maximumFractionDigits: 7}).format(-12.345)); // -0 000 012,34500
console.log(new Intl.NumberFormat("ru-RU",{minimumIntegerDigits: 7, useGrouping: false}).format(-12.345)); // -0000012,345
Работа с математическими, геометрическими функциями
Math.PI - константа π: 3.1415
Math.E - константа е: 2.7182
// функции принимают значение угла в радианах, где 180° = π радиан
let x1 = Math.sin(Math.PI / 6); // синус угла 30°
let x2 = Math.cos(Math.PI / 2); // синус угла 90°
// на классическом графике x-ось располагается горизонтально слева-направо, y-ось располагается вертикально снизу-вверх
Работа с датой и временем
var dt = new Date(); // создать объект Date с текущей датой и временем
var dt2 = new Date('2020-03-15 03:50:00'); // создать объект Date с датой и временем заданными в виде строки
var dt3 = new Date(2020, 0, 1, 0, 0, 0, 0); // 1 января 2020, 00:00:00
var dt4 = new Date(2020, 0, 1); // то же самое, часы, минуты, секунды, миллисекунды по умолчанию равны 0
var dt5 = new Date(1000*60*60*24); // создать объект Date с датой и временем заданными количеством миллисекунд прошедших с начала 1 января 1970 года (создаст дату 2 января 1970 года)
var dt6 = Date.now(); // возвращает текущую дату сразу в виде миллисекунд прошедших с начала 1 января 1970 года
var dt = new Date();
y = dt.getFullYear(); // возвращает год в 4 цифры
y2 = dt.getFullYear().toString().substr(-2); // возвращает год в 2 цифры
m = dt.getMonth(); // возвращает месяц в виде числа, где 0 - январь, 1 - февраль и т. д.
d = dt.getDate(); // возвращает день месяца от 1 до 31
dn = dt.getDay(); // возвращает день недели, где 0 - воскресенье, 1 - понедельник, 2 - вторник, и т. д.
h = dt.getHours(); // возвращает час от 0 до 23
mi = dt.getMinutes(); // возвращает минуту от 0 до 59
se = dt.getSeconds(); // возвращает секунду от 0 до 59
tzo = dt.getTimezoneOffset(); // возвращает разницу между местным и UTC-временем, в минутах, для зоны UTC+5 вернёт 60 * 5 = 300
tm = dt.getTime(); // возвращает число миллисекунд прошедших с 1 января 1970 года GMT+0 до заданной даты
// вывести день года по счету
function day_year() {
now = new Date();
start = new Date(now.getFullYear(), 0, 0);
diff = now - start;
oneDay = 1000 * 60 * 60 * 24;
day = Math.floor(diff / oneDay);
return day;
}
console.log(day_year()); // выведет день года по счёту, например 28 июня 2023 - будет 179 днём года
dt = new Date('2024-02-05 00:00:00');
console.log(dt.toISOString()); // выведет "2024-02-04T22:00:00.000Z" - на 1 день меньше, чем заданная дата
dt = new Date('2024-02-05 00:00:00 GMT');
console.log(dt.toISOString()); // выведет "2024-02-05T00:00:00.000Z" - правильная дата
// вариант 1
n = new Date();
r = n.toISOString();
r = r.replace("T", " ");
r = r.substring(0, r.indexOf("."));
console.log(r); // выведет: 2022-09-22 17:14:06
// вариант 2
n = new Date();
d = n.getDate();
m = n.getMonth() + 1;
y = n.getFullYear();
d = d > 9 ? d : "0"+d;
m = m > 9 ? m : "0"+m;
dts = y + '-' + m + '-' + d; // выведет: 2022-09-22
// от номера месяца - к названию месяца
me1 = ["янв", "фев", "мар", "апр", "май", "июн", "июл", "авг", "сен", "окт", "ноя", "дек"]; // со строчной буквы, 3 буквы
me2 = ["январь", "февраль", "март", "апрель", "май", "июнь", "июль", "август", "сентябрь", "октябрь", "ноябрь", "декабрь"]; // со строчной буквы, без склонения
me3 = ["января", "февраля", "марта", "апреля", "мая", "июня", "июля", "августа", "сентября", "октября", "ноября", "декабря"]; // со строчной буквы, со склонением
me4 = ["Янв", "Фев", "Мар", "Апр", "Май", "Июн", "Июл", "Авг", "Сен", "Окт", "Ноя", "Дек"]; // с заглавной буквы, 3 буквы
me5 = ["Январь", "Февраль", "Март", "Апрель", "Май", "Июнь", "Июль", "Август", "Сентябрь", "Октябрь", "Ноябрь", "Декабрь"]; // с заглавной буквы, без склонения
me6 = ["Января", "Февраля", "Марта", "Апреля", "Мая", "Июня", "Июля", "Августа", "Сентября", "Октября", "Ноября", "Декабря"]; // с заглавной буквы, со склонением
// от названия месяца - к номеру месяца
me7 = {"янв":1, "фев":2, "мар":3, "апр":4, "май":5, "июн":6, "июл":7, "авг":8, "сен":9, "окт":10, "ноя":11, "дек":12}; // со строчной буквы, 3 буквы
me8 = {"январь":1, "февраль":2, "март":3, "апрель":4, "май":5, "июнь":6, "июль":7, "август":8, "сентябрь":9, "октябрь":10, "ноябрь":11, "декабрь":12}; // со строчной буквы, без склонения
me9 = {"января":1, "февраля":2, "марта":3, "апреля":4, "мая":5, "июня":6, "июля":7, "августа":8, "сентября":9, "октября":10, "ноября":11, "декабря":12}; // со строчной буквы, со склонением
me10 = {"Янв":1, "Фев":2, "Мар":3, "Апр":4, "Май":5, "Июн":6, "Июл":7, "Авг":8, "Сен":9, "Окт":10, "Ноя":11, "Дек":12}; // с заглавной буквы, 3 буквы
me11 = {"Январь":1, "Февраль":2, "Март":3, "Апрель":4, "Май":5, "Июнь":6, "Июль":7, "Август":8, "Сентябрь":9, "Октябрь":10, "Ноябрь":11, "Декабрь":12}; // с заглавной буквы, без склонения
me12 = {"Января":1, "Февраля":2, "Марта":3, "Апреля":4, "Мая":5, "Июня":6, "Июля":7, "Августа":8, "Сентября":9, "Октября":10, "Ноября":11, "Декабря":12}; // с заглавной буквы, со склонением
setFullYear(year [, month, date])
setMonth(month [, date])
setDate(date)
setHours(hour [, min, sec, ms])
setMinutes(min [, sec, ms])
setSeconds(sec [, ms])
setMilliseconds(ms)
setTime(milliseconds) (устанавливает всю дату по миллисекундам с 01.01.1970 UTC)
var dt = new Date();
dt.setHours(0); // сегодня, но час изменён на 0
dt.setHours(0, 0, 0, 0); // сегодня, но часы, минуты, секунды изменены на 00:00:00.
var dt = new Date(); // получим текущую дату
dt.setDate(dt.getDate() + 7); // прибавим 7 дней к текущей дате
dt = new Date();
dt.setMonth(dt.getMonth() + 1);
dt.setDate(1);
function add_years(dt, god) {
let d = new Date(dt);
d.setFullYear(d.getFullYear() + god);
r = d.toISOString();
w = r.split('T');
return w[0];
}
q = add_years('1981-07-06', 65); // вернёт 2046-07-06
year = 2020;
month = 1; // февраль
var maxDays = 32 - new Date(year, month, 32).getDate(); // при создании даты с избыточным количеством дней создаётся дата следующего месяца (года) с днём равным лишним дням
alert(maxDays); // вернёт 29 так как 2020 год високосный
function IsVisokYear(y) { // если год високосный вернёт true
let ly = new Date(y, 1, 29);
if (ly.getDate() == 29) {return true;} else {return false;}
}
IsVisokYear(2020); // вернёт true
IsVisokYear(2021); // вернёт false
// учитывает високосные года
function DayOfYear() {
let cd = new Date();
let y = cd.getFullYear();
let m = cd.getMonth();
let d = cd.getDate();
let ml = [31,28,31,30,31,30,31,31,30,31,30,31];
let ly = new Date(y, 1, 29);
if (ly.getDate() == 29) {ml[1] = 29;}
let dd = 0;
for (i=0; i < m; i++) {dd = dd + ml[i];}
return dd + d;
}
console.log(DayOfYear());
era: 'long'
year: 'numeric'
month: 'long'
day: 'numeric'
weekday: 'long'
timezone: 'UTC'
hour: 'numeric'
minute: 'numeric'
second: 'numeric'
var date = new Date('2020-03-15 03:50:00');
var options = {weekday: 'long'};
alert(date.toLocaleString("ru", options)); // вернёт воскресенье - день недели русскими буквами
var options = {month: 'long'};
alert(date.toLocaleString("ru", options)); // вернёт март - месяц русскими буквами
var formatter = new Intl.DateTimeFormat("ru");
alert(formatter.format(date)); // вернёт 15.03.2020 - русский формат даты
var formatter2 = new Intl.DateTimeFormat("ru", {hour: "numeric", minute: "numeric", second: "numeric"});
alert(formatter2.format(date)); // вернёт 03:50:00 - время в русском формате
let formatter3 = new Intl.DateTimeFormat("ru", {weekday: "long", year: "numeric", month: "long", day: "numeric"});
alert(formatter.format(date)); // вернёт воскресенье, 15 марта 2020 г.
function getTimeRemaining(tm){
var td = Date.parse(new Date());
var dl = Date.parse(tm);
if (dl > td) { // если заданная дата больше текущей
t = dl - td;
bm = 'ещё осталось';
} else { // если заданная дата меньше текущей
t = td - dl;
bm = 'прошло';
}
var seconds = Math.floor( (t/1000) % 60 );
var minutes = Math.floor( (t/1000/60) % 60 );
var hours = Math.floor( (t/(1000*60*60)) % 24 );
var days = Math.floor( t/(1000*60*60*24) );
var mes = Math.floor(days / 30.41);
var dni = days - Math.round(mes * 30.41);
var ddn = [' день', ' дня', ' дней'];
if (mes > 0) {mes = mes + ' мес ' + dni + ' дней';} else {mes = dni + ' дней';}
return {
'total': t,
'days': days,
'hours': hours,
'minutes': minutes,
'seconds': seconds,
'bm': bm,
'mes': mes
};
}
tmm = '2020-03-15 03:50:00';
var myt = getTimeRemaining(tmm);
var ss = '<span title="' + myt.mes + '">' + myt.days + '<sup>д</sup> ' + myt.hours + '<sup>час</sup> ' + myt.minutes + '<sup>мин</sup><br><span>' + myt.bm + '</span></span>';
$(this).html(ss);
function date_diff(dtn, dtk) {
if (dtn == 0) {b = new Date();} else {b = new Date(dtn);}
e = new Date(dtk);
ny = b.getFullYear();
ky = e.getFullYear();
nm = b.getMonth();
km = e.getMonth();
nd = b.getDate();
kd = e.getDate() + 1;
if ((km == 0)||(km == 2)||(km == 4)|| (km == 6) || (km == 7) ||(km == 9)||(km == 11)){kdays = 31;}
if ((km == 3)||(km == 5)||(km == 8)|| (km == 10)){kdays = 30;}
if (km == 1&&((ky % 4 == 0) && (ky % 100 != 0)) || (ky % 400 == 0)){kdays = 29;}
if (km == 1&&((ky % 4 != 0) || (ky % 100 == 0))){kdays = 28;}
if ((nm == 0)||(nm == 2)||(nm == 4)|| (nm == 6) || (nm == 7) ||(nm == 9)||(nm == 11)){ndays = 31;}
if ((nm == 3)||(nm == 5)||(nm == 8)|| (nm == 10)){ndays = 30;}
if (nm == 1&&((ny % 4 == 0) && (ny % 100 != 0)) || (ny % 400 == 0)){ndays = 29;}
if (nm == 1&&((ny % 4 != 0) || (ny % 100 == 0))){ndays = 28;}
FirstMonthDiff = ndays - nd + 1;
if (kd - nd < 0) {km = km - 1; kd = kd + kdays;}
daysDiff = kd - nd;
if (km - nm < 0) {ky = ky - 1; km = km + 12;}
monthDiff = km - nm;
yearDiff = ky - ny;
if (daysDiff == kdays) {
daysDiff = 0;
monthDiff = monthDiff + 1;
if (monthDiff == 12) {
monthDiff = 0;
yearDiff = yearDiff + 1;
}
}
if ((FirstMonthDiff != ndays)&&(kd - 1 == kdays)){daysDiff = FirstMonthDiff;}
if (yearDiff == 0) {a_kg = '';} else {a_kg = yearDiff + ' ' + sklonenie(yearDiff, 1);}
if (monthDiff == 0) {} else {a_kg = a_kg + ' ' + monthDiff + ' мес';}
if (daysDiff == 0) {} else {a_kg = a_kg + ' ' + daysDiff + ' ' + sklonenie(daysDiff, 3);}
rr = yearDiff + '' + sklonenie(yearDiff, 1) + " " + monthDiff + " month(s) " + daysDiff + " days(s)"
return a_kg;
}
qq = date_diff('2023-05-27', '2037-11-02'); // вернёт 14 лет 5 мес 6 дней
function set_cur_date() { // установить текущую дату в поле Дата
dt = new Date();
day = dt.getDate();
month = dt.getMonth() + 1,
year = dt.getFullYear(),
month = (month < 10 ? "0" : "") + month;
day = (day < 10 ? "0" : "") + day;
dt5 = year + '-' + month + '-' + day;
$('#clndr').val(dt5);
}
set_cur_date();
// даты лучше всего сравнивать как числа, переведя их в количество миллисекунд прошедших с 1 января 1970 года
dt1 = new Date('2022-08-30 00:00:00');
dt2 = new Date('2022-08-29 00:00:00');
tm1 = dt1.getTime(); // переведём дату в миллисекунды
tm2 = dt2.getTime(); // переведём дату в миллисекунды
if (tm1 > tm2) {
// этот код выполнится, так как дата dt1 больше даты dt2
}
Типы данных, сравнение, присваивание, условные операторы
// Преобразование в строку
var a = String(55); // "55"
var a = String(null); // "null"
var a = String(false); // "false"
var a = String(undefined); // "undefined"
var a = true + "test"; // "truetest"
var a = "123" + undefined; // "123undefined"
// Преобразование в число
var a = +"123"; // 123
var a = +"1.55"; // 1.55 (для корректного преобразования в число в строке должны быть только цифры и не более одной точки)
var a = parseInt("100px"); // 100
var a = parseInt("123ab", 10); // 123 (10 - десятичная система счисления)
var a = +" n 123 n n"; // 123 (пробелы и переносы строк предварительно обрезаются)
var a = +"123abc"; // NaN
var a = +"123.3."; // NaN
var a = +"abc"; // NaN
var a = +""; // 0
var a = +true; // 1
var a = +false; // 0
var a = +undefined; // NaN
var a = +null; // 0
// Преобразование в число с плавающей точкой
let a = parseFloat("5.351 ab"); // 5.351
// Преобразование в логический тип
var a = !!2; // true
var a = !!"тест"; // true
var a = !!$("#mel"); // true
var a = !!0; // false
var a = !!""; // false
var a = !!null; // false
var a = !!undefined; // false
var a = !!NaN; // false
> больше
>= больше или равно
< меньше
<= меньше или равно
== равно
!= не равно
=== строго равно
!== строго не равно
alert(2 > 1); // true
alert(2 < 1); // false
alert(2 == 1); // false
alert(2 != 1); // true
alert('Я' > 'А'); // true
alert('Кот' > 'Код'); // true (потому что т > д)
alert('Сонный' > 'Сон'); // true (потому что Сонный длиннее, чем Сон)
alert('а' > 'А'); // true (потому что любая строчная буква > любой заглавной буквы)
alert("9" < "a"); // true (потому что цифра в строке всегда меньше, чем буквы в любом регистре)
alert('2' > 1); // true (потому что при сравнении разных типов строка '2' становится числом 2)
alert('01' == 1); // true (потому что при сравнении разных типов строка '01' становится числом 1)
alert(true == 1); // true (потому что при сравнении разных типов true становится 1)
alert(false == 0); // true (потому что при сравнении разных типов false становится 0)
alert('' == false); // true (потому что при сравнении разных типов пустая строка становится 0 и false становится 0)
alert(false === 0); // false (потому что при "строгом равно" разные типы не преобразуются)
alert('' !== false); // true (потому что при "строгом не равно" разные типы не преобразуются)
alert(null === undefined); // false (потому что null и undefined имеют разные типы)
alert(null == undefined); // true (потому что при не строгом равенстве null равно undefined и не равно больше ничему другому)
alert(null > 0); // false (потому что при сравнении разных типов сравнение > преобразует null в 0)
alert(null == 0); // false (потому что при не строгом равенстве null равно только undefined и не равно больше ничему другому)
alert(null >= 0); // true (потому что при сравнении разных типов сравнение >= преобразует null в 0)
alert(undefined > 0); // false (потому что при сравнении разных типов undefined преобразуется в NaN, а NaN – возвращает false при любых сравнениях)
alert(undefined < 0); // false (потому что при сравнении разных типов undefined преобразуется в NaN, а NaN – возвращает false при любых сравнениях)
alert(undefined == 0); // false (потому что при не строгом равенстве undefined равно только null и не равно больше ничему другому)
alert(NaN == NaN); // false (потому что NaN – возвращает false при любых сравнениях)
alert(NaN === NaN); // false (потому что NaN – возвращает false при любых сравнениях)
alert(null == null); // true
alert(null === null); // true (потому что имеют одинаковый тип)
alert(undefined == undefined); // true
alert(undefined === undefined); // true (потому что имеют одинаковый тип)
e1 = $(this);
e2 = $('#qqq');
if (e1[0] === e2[0]) {
// этот код будет выполнен, если элементы совпадают, т. е. это один и тот же элемент DOM
}
let r = 3 > 2;
alert(r); // выведет true
i++; // аналогично записи i = i + 1;
i--; // аналогично записи i = i - 1;
s += i; // аналогично записи s = s + i;
s -= i; // аналогично записи s = s - i;
s *= i; // аналогично записи s = s * i;
s /= i; // аналогично записи s = s / i;
s %= i; // аналогично записи s = s % i;
s &= i; // аналогично записи s = s & i;
s |= i; // аналогично записи s = s | i;
k = 1;
s = (k > 10) ? 1 : 5; // в результате s будет равно 5
if (k > 10) {s = 1;} else {s = 5;} // аналогичная предыдущей запись
k = 3;
s2 = (k > 10) ? 1 : (k < 10) ? 7 : 5; // в результате s2 будет равно 7
if (k > 10) {s2 = 1;} else if (k < 10) {s2 = 7;} else {s2 = 5;} // аналогичная предыдущей запись
// проверка текстового поля на пустоту
zn = $.trim($('#pole').val());
if (!!zn == false) {alert('Значение пусто!'); return;}
// проверка полей типа date, datetime-local - дата, дата с временем - на пустоту
var dd = $('#clndr').val();
if (!dd) {alert('Некорректная дата!'); return;}
// проверка числового поля, чтобы оно было больше нуля
dg = +$('#cfr').val(); // приведем значение к числу
if (isNaN(dg) || !(dg > 0)) {alert('Некорректная длительность!'); return;}
// проверка числового поля, чтобы оно было целым числом и больше нуля
dg = +$('#cfr').val(); // приведем значение к целому числу
if (isNaN(dg) || !(dg > 0) || parseInt(dg) != dg) {alert('Некорректная длительность!'); return;}
// проверка текстового поля с вводом email
function valid_email(s) {return /^[\w-\.]+@[\w-\.]+\.[\w-]{2,20}$/i.test(s);}
q = valid_email('a.b@ma-i_l.co.photography'); // вернет true для длинного домена верхнего уровня
q = valid_email('a@xn--h1aigbl0e.xn--p1ai'); // вернет true для домена на кириллице
// html-элемент input type="email" хоть и создан для ввода и проверки email перед отправкой данных на сервер, но его встроенная в браузер проверка пока что несовершенна и считает нормальным, например, такой email адрес: 'z@ф' так что проверку на удовлетворительность введенного email лучше делать самостоятельно способами выше
// проверка на соответствие, что пароль содержит не менее 6 символов и хотя бы одну цифру и латинскую букву в нижнем и верхнем регистре.
function is_psw(p) {return (p.length < 6) ? false : /(?=(.*\d))(?=(.*[a-z]))(?=(.*[A-Z]))/.test(p);}
psw = 'dD3dd'; // вернёт false
psw = 'dDdddd'; // вернёт false
psw = 'dd3ddd'; // вернёт false
psw = 'dD3ddd'; // вернёт true
psw = 'dD!3d$dыd'; // вернёт true
if (!is_psw(psw)) {alert('Пароль должен содержать не менее 6 символов и содержать хотя бы одну цифру и латинскую букву в нижнем и верхнем регистре!'); return;}
function myf(k) {
if (!(k >= 10 && k <=20)) { // условие задано через отрицание
alert(k + ' вне диапазона 10 - 20');
} else {
alert(k + ' внутри диапазона 10 - 20');
}
}
myf(9); // выведет 9 вне диапазона 10 - 20
myf(12); // выведет 12 внутри диапазона 10 - 20
// можно использовать, например, чтобы определить, существует ли функция
try {
myfunc(par); // тут вызов возможно ещё не успевшей загрузиться функции
} catch (error) {
// тут, действия, если код выше вызвал ошибку
}
Временные функции (таймер, интервал, анимация)
var timerId = setTimeout(function(){
alert('Привет'); // этот код будет выполнен через 1000 миллисекунд или 1 секунду
}, 1000);
clearTimeout(timerId); // отменит исполнение таймера в переменной timerId, если эта команда будет выполнена раньше, чем наступит время исполнения таймера
setTimeout(function run() {
// код который выполнится через 1 сек
// здесь можно использовать переданные параметры: par1, par2, par3, par4
}, 1000, par1, par2, par3, par4);
var timerId = setInterval(function() {
alert("тик"); // этот код выполнится через 2 секунды и далее будет выполняться каждые 2 секунды
}, 2000);
clearInterval(timerId); // отменит исполнение интервальной функции в переменной timerId
setTimeout(function run() {
res = func(i); // запуск какой-то своей функции
zd = res + 1500;
setTimeout(run, zd); // запустит саму себя еще раз через 1,5 секунды, если предыдущая функция возвратила 0
}, 1000); // выполнится через 1 секунду
HTML:
<p class="sptl">спойлер1</p><div><p>Скрытый текст для<br>первого спойлера</p></div>
<p class="sptl">спойлер2</p><div><p>Скрытый текст для второго спойлера</p></div>
$(".sptl").next().hide(); // по умолчанию спойлеры скрыты
$(".sptl").click(function(){ $(this).next().slideToggle(); }); // скрыть-открыть спойлер по клику
$("#am").slideDown(600); // скрытие элемента займет 0,6 сек
$("#am").slideUp(600); // отображение элемента займет 0,6 сек
// Плавно показать сообщение
function msg_show(t) {
$('#msg').fadeIn(700, msg_hide); // анимация отображения займёт 0,7 сек и по окончании запустит функцию скрывающую элемент
}
// Плавно скрыть сообщение
function msg_hide() {
$('#msg').fadeOut(1300); // анимация скрытия займёт 1,3 сек
}
$('.foo').slideToggle(1000, sdvig); // где функция sdvig выполнится после отработки анимации
// HTML код
<p id="newimg">Hello World</p>
// CSS код
#newimg {position:absolute; left:0px; top:0px; z-index:100;}
// JS код анимации сразу нескольких свойств элемента с id = newimg от изначальных в CSS к заданным в JS
$("#newimg").animate({opacity: 0, left: "300px", top: "-200px", width: "100px", height: "100px"}, 1000); // анимация выполняется в течении 1 секунды
$("#el").animate({opacity: 0}, 1000, myfunc); // анимация
function myfunc() { // функция выполнится после завершения анимации
// какой-то код
}
setInterval(function(){
setTimeout(function(){
$("#message").hide(); // элемент не виден
setTimeout(function(){$("#message").show();},500); // элемент становится виден через 0,5 сек
},3000); // повтор итерации через 3 сек
},3500); // запускается через 3,5 сек после загрузки страницы
Использование функций, область видимости, типы переменных
function hello(a, b) {
z = a + b;
return z;
}
s = hello('frm', 3);
function myfunc(n) {
var a = 1 + n; var b = 2 + n;
return [a, b];
}
var vl = myfunc(5);
var z = vl[0];
var x = vl[1];
function hello(a, b) {
let z = a + b;
if (z == 7) {return false;}
return z; // если предыдущее условие выполнится, то этот return не сработает
}
let s = hello(4, 4); alert(s); // вернет 8
let s = hello(4, 3); alert(s); // вернет false
function myfunc(n, m = "медвед") {
alert(n + " " + m );
}
myfunc("привет"); // выведет "привет медвед"
myfunc("привет", "мир"); // выведет "привет мир"
function myfunc2(n, m = myfunc("настало")) {
alert(n + " " + m );
}
myfunc2("лето"); // выведет "лето настало медвед"
async function mfunc() {
return 'тест';
}
// использование асинхронной функции с синтаксисом then-catch
mfunc().then(res => {
console.log('тест1');
console.log(res);
console.log('тест2');
}).catch(error => {console.error(error);}); // выведет в консоль: выведет в консоль: тест1 тест тест2
// использование асинхронной функции с синтаксисом async-await
mfunc2 = async () => {
console.log('тест1');
result = await mfunc(); // await можно использовать только внутри async функции
console.log(result);
console.log('тест2');
}
mfunc2(); // выведет в консоль: тест1 тест тест2
function myfunc() {
alert(q + 5);
}
var q = 2;
myfunc(); // выведет 7
function myfunc2(q) {
alert(q + 5);
}
var q = 2;
myfunc2(7); // выведет 12 так как внутри функции использовалась локальная переменная q заданная в качестве параметра функции
function myfunc3() {
q = 3;
alert(q + 5);
}
var q = 2;
myfunc3(); // выведет 8
alert(q); // выведет 3, так как значение глобальной переменной q было изменено внутри функции
function myfunc4() {
var q = 4;
alert(q + 5);
}
var q = 2;
myfunc4(); // выведет 9, так как внутри функции использовалась объявленная локальная переменная q
alert(q); // выведет 2, так как глобальная переменная q не изменялась
function myfunc5(a) {
a.pole= 'привет';
};
var obj = {pole: 'медвед'}; // объект
myfunc5(obj);
alert(obj.pole); // выведет "привет", так как свойство объекта было изменено в функции
var a; alert(a); // вернет undefined
var a = 5; alert(a); // вернет 5
alert(b); // вернет ошибку Uncaught ReferenceError: b is not defined
alert(c); // вернет undefined несмотря на то, что переменная 'с' объявлена ниже
var c = 5;
var x = 3;
var x = 4; // даст объявить переменную повторно
console.log(x);
for(var i = 0; i<=10; i++) { /* … */ }
alert(i); // выведет 10 - последнее значение переменной i в цикле
let a = 3; // в отличие от var видна только внутри блока {} в котором она объявлена, таких как: function, if, while, for
let a = 3;
if (true) {
let a = 5; alert(a); // выведет 5 (внутри блока)
}
alert(a); // выведет 3 (снаружи блока)
alert(c); // вернет ошибку Uncaught ReferenceError: c is not defined несмотря на то, что переменная 'с' объявлена ниже
let c = 5;
let x;
let x; // вернет ошибку Uncaught SyntaxError: Identifier 'x' has already been declared, потому что переменная 'x' уже объявлена в этом блоке
for(let i = 0; i<10; i++) { /* … */ }
alert(i); // вернет ошибку Uncaught ReferenceError: i is not defined, так как i объявлена только для цикла for
const a = 5; // не подлежит изменению
a = 7; // вернет ошибку Uncaught TypeError: Assignment to constant variable, так как константы нельзя изменять
const a = 5;
const a = 7; // вернет ошибку Uncaught SyntaxError: Identifier 'a' has already been declared, так как константу нельзя объявлять повторно
function dd() {
var b = 7;
var c = b * a;
alert(c);
}
const a = 5;
dd(); // выведет 35, так как константа 'a' глобальная и видна внутри функции
var v = -1, t = 0, m = []; // все переменные v, t и массив m объявлены через var
let d = "привет", s = p = f = 5; // все переменные d, s, p, f объявлены через let
const x = y = z = 0; // объявлены переменные x, y, z, при этом через const объявлена только x; y и z объявлены через var и не являются константами
const x = 0, y = 0, z = 0; // все переменные объявлены через const
// строгий режим не поддерживает старые реализации кода, поддерживается только современный режим Javascript
(function() {
'use strict'; // включит строгий режим внутри функции
// здесь код функции в строгом режиме
})();
<script>
"use strict"; // включит строгий режим во всём скрипте, эта директива должна идти первой или после комментариев
// здесь код скрипта в строгом режиме
</script>
console.log(str);
Адрес страницы и адресная строка
// если адресная строка:
// https://site.ru/post.php?post=25&action=Привет%20медвед
// функция разбора GET-параметров нормально обрабатывает также значения с пробелами и на русском языке
function getAdrPar(name) {
return decodeURIComponent((new RegExp('[?|&]' + name + '=' + '([^&;]+?)(&|#|;|$)').exec(location.search)||[,""])[1].replace(/\+/g, '%20'))||null;
}
let post = getAdrPar('post'); alert(post); // выведет 25
let act = getAdrPar('action'); alert(act); // выведет "Привет медвед"
let aaa = getAdrPar('aaa'); alert(aaa); // выведет null
let h = location.hostname; // возвращает site.ru
document.location.href = 'https://site.ru/';
function openInNewTab(href) {Object.assign(document.createElement('a'), {target: '_blank', href}).click();}
openInNewTab('https://site.ru');
var p = document.location.href;
p = p.substring(0, p.lastIndexOf("#"));
document.location.href = p;
s = document.referrer; // возвратит ссылку вида https://site.ru/post.php?r=43&da=56 если страница была загружена не по ссылке, то вернет '' - пустую строку
document.location.reload(); // перезагрузить текущую страницу
document.location.reload(true); // перезагрузить текущую страницу, без использования кэша браузера
Хранение и передача данных между окнами
// для хранения куки браузером выделяется всего 4 Кбайта на один домен, при этом при каждом обновлении страницы домена куки отправляются на сервер и обратно
function createCookie(name,value,days) { // создать куки
if (days) {
var date = new Date();
date.setTime(date.getTime()+(days*24*60*60*1000));
var expires = "; expires="+date.toUTCString();
} else {var expires = "";}
document.cookie = name+"="+value+expires+"; path=/";
}
createCookie('imya','Лена',100); // создать куки на 100 дней с именем imya = 'Лена'
function getCookie(name) { // получить значение куки по его имени
var matches = document.cookie.match(new RegExp("(?:^|; )" + name.replace(/([\.$?*|{}\(\)\[\]\\\/\+^])/g, '\\$1') + "=([^;]*)"));
return matches ? decodeURIComponent(matches[1]) : undefined;
}
nm = getCookie('imya'); // получить значение куки с названием 'imya'
function eraseCookie(name) {createCookie(name,"",-1);}
eraseCookie('imya'); // удалить куки с названием 'imya'
// для localStorage браузером выделяется 5 Мбайт на домен в Firefox, Google Chrome, и Opera, и 10 Мбайт в Internet Explorer (данные хранятся только в браузере пользователя, на сервер автоматически не отправляются)
// проверить включен ли localStorage в браузере
if (window.localStorage) {
// какой-то код с использованием localStorage
}
localStorage['pole'] = 'тест'; // записать в localStorage атрибут pole со значением 'тест'
let n = localStorage['pole']; // получить значение ранее установленного атрибута pole в переменную, если атрибут не существует, то вернет undefined
delete localStorage['pole']; // удалить атрибут pole из localStorage
if (localStorage['pole'] == null) {} // проверить, что ключ не существует в localStorage
Разные функции и возможности
// HTML код кнопки
<a class="back_to_top" title="Наверх">↑</a>
// JS код обработчик логики (чистый Javascript)
<script type="text/javascript">
(function() {
'use strict';
function trackScroll() {
var scrolled = window.pageYOffset;
var coords = document.documentElement.clientHeight;
if (scrolled > coords) {
goTopBtn.classList.add('back_to_top-show');
}
if (scrolled < coords) {
goTopBtn.classList.remove('back_to_top-show');
}
}
function backToTop() {
if (window.pageYOffset > 0) {
window.scrollBy(0, -80);
setTimeout(backToTop, 0);
}
}
var goTopBtn = document.querySelector('.back_to_top');
window.addEventListener('scroll', trackScroll);
goTopBtn.addEventListener('click', backToTop);
})();
</script>
// CSS код кнопки
.back_to_top {background: #a2a2a2; color:#000000; padding: 7px 15px; font-size: 20pt; cursor: pointer; bottom: 20px; right: 15px; display: none; position: fixed; z-index: 999; border-radius: 4px; opacity: 0.4;}
.back_to_top :hover {background: #777777;}
.back_to_top-show {display: block;}
// HTML код
<p onclick="sound()">Проиграть звук</p>
// JS функция
function sound() {
audio = new Audio(); // создать новый элемент audio
audio.src = 'https://site.ru/1.mp3'; // путь к звуковому файлу
audio.autoplay = true; // автоматически запустить проигрывание
}
// HTML код
<p><span onclick="sound_stop()">Stop</span> <span onclick="sound_pause()">Pause</span> <span onclick="sound_play()">Play</span></p>
// JS код
var audio;
audio = new Audio(); // создать новый элемент audio
audio.src = 'https://site.ru/2.mp3'; // путь к звуковому файлу
function sound_stop() {
audio.pause(); // пауза
audio.currentTime = 0; // текущее время на 0
}
function sound_pause() {
audio.pause(); // пауза
}
function sound_play() {
audio.play(); // плей
}
// на jQuery: при клике на тег var его текст копируется в буфер обмена
$("var").click(function(){
let t = $(this).text();
$("<input>", {id: "tmpel", value: t}).appendTo("body");
$("#tmpel").select();
document.execCommand("copy");
$("#tmpel").remove();
});
// на Javascript: при клике на тег var его текст копируется в буфер обмена
var vars = document.querySelectorAll("var");
[].forEach.call(vars, function(el) { // перебираем все найденные элементы
el.onclick = function(e) { // вешаем событие
let inp = document.createElement("input");
inp.id = "tmpel";
inp.value = e.currentTarget.textContent;
document.body.append(inp);
let fu = document.querySelector("#tmpel");
fu.select();
document.execCommand("copy");
fu.remove();
}
});
// HTMl-код (номер сноски заключен в тег верхнего индекса sup, текст сноски идет сразу за ним в теге span, в нем же можно задать высоту и ширину окна сноски, если атрибуты data-h и data-w убрать, то будут использоваться одни на всех размеры из css)
<p>Мороз и солнце<sup>1</sup><span data-h="50" data-w="200" class="invis">Солнце - звезда класса G2V желтый карлик.</span> день чудесный! Еще ты дремлешь, друг<sup>2</sup><span data-h="50" data-w="150" class="invis">Друг - товарищ, названный брат, побратим, но не родственник.</span> прелестный.</p>
// CSS-код
#pskaz {background:#dbdbdb; position: absolute; width:300px; height:150px; border-radius: 5px; padding:5px 10px 5px 6px; overflow:auto; font-size: 15px;}
#pskazx {position:absolute; cursor:pointer; color:red; right:2px; top:1px;}
sup {cursor:pointer;}
.invis {display: none;}
// JS-код (положение окна сноски зависит от положения номера сноски в тексте и подстраивается под размеры видимой области окна браузера; окно сноски открывается по клику на номер сноски и закрывается по клику на крестик)
$("body").on("click", "sup", function () {
$("#pskaz").remove();
let opis = $(this).next().html();
let he = $(this).next().attr('data-h');
let wi = $(this).next().attr('data-w');
$("<div>", {id: "pskaz", html: opis, on: {scroll: function(event){$("#pskazx").css({"top":$(this).scrollTop()+1});}}, css: {height: he, width: wi}, append: $("<div>", {id: "pskazx", title: "Закрыть", html: "⊗", on: {click: function(event){$("#pskaz").remove();}}})}).appendTo("body");
let tw = $(this).width(); let th = $(this).height();
let h1 = window.innerHeight; let w1 = window.innerWidth;
let le2 = $(this).offset().left; let to2 = $(this).offset().top;
let elh = $('#pskaz').outerHeight(); let elw = $('#pskaz').outerWidth();
let c = this.getBoundingClientRect(); let to = c.top; let le = c.left;
if (le + elw + tw + 5 < w1) {lz = le2 + tw + 5;} // справа
else if (le - elw - 5 > 0) {lz = le2 - elw - 5;} // слева
else {lz = Math.round((w1 - elw)/2);} // посредине
if (to - elh > 0) {tz = to2 - elh;} // сверху
else if (to + th + elh < h1) {tz = to2 + th;} // снизу
else {tz = Math.round((h1 - elh)/2) + $(window).scrollTop();} // посредине
$('#pskaz').css({"left":lz, "top":tz});
});
// Это достигается с помощью элемента textarea и запретом нажатия клавиши Enter в нём
<textarea id="my_textarea"></textarea>
$("body").on("keydown", "#my_textarea", function(e) {
if (e.key == 'Enter') {
e.preventDefault();
return false;
}
});
// HTML-код:
<div id="menu">
<a class="mact" href="page1.php">Страница 1</a>
<span class="mnct">Страница 2<span class="mm_vm"><a href="2a.php">Страница 2а</a><a href="2b.php">Страница 2б</a></span></span>
<a class="mnct" href="page3.php">Страница 3</a>
<span class="mnct">Страница 4<span class="mm_vm"><a href="4a.php">Страница 4а</a><a href="4b.php">Страница 4б</a><a href="4c.php">Страница 4в</a></span></span>
</div>
// CSS-код:
#menu {background: #464a62;}
#menu a, #menu > span {position: relative; display: inline-block; cursor: pointer; color:#fff;}
.mm_vm {display: none; width: 150px; z-index: 1000; background: #464a62; border: 2px solid #343749;}
.mm_vm a {width: calc(100% - 20px);}
.mm_vm a:hover {background-color:#343749;}
.mact {background:#55a654 !important;}
.mnct:hover {background-color:#343749;}
// JQuery-код:
// выпадающее меню - показать
$('#menu > span').mouseover(function(ev){
$(this).children('.mm_vm').css({'display':'block', 'position':'absolute', 'top':'37px', 'left':'0px'});
});
// выпадающее меню - скрыть
$('#menu > span').mouseout(function(ev){
$(this).children('.mm_vm').hide();
});
// HTML-код:
<script type="text/javascript" src="https://www.gstatic.com/charts/loader.js"></script>
<span class="language-xml"><span class="language-xml"><span class="language-xml"><span class="language-xml"><div id="chart_div" style="width: 100%; height: 500px;"></div></span></span></span></span>
// JS-код:
// эти 2 строчки можно запускать при клике на какую-нибудь вкладку или кнопку, чтобы диаграмма отрисовывалась только по требованию
google.charts.load('current', {'packages':['corechart']});
google.charts.setOnLoadCallback(drawChart); // запуск функции диаграммы
// функция диаграммы
function drawChart() {
// данные для диаграммы
var data = google.visualization.arrayToDataTable([
['Год', 'Продажи', 'Затраты'],
['2013', 1000, 400],
['2014', 1170, 460],
['2015', 660, 1120],
['2016', 1030, 540]
]);
// опции отображения диаграммы
var options = {
title: 'Производительность компании',
hAxis: {title: 'Год', titleTextStyle: {color: '#333'}},
vAxis: {minValue: 0}
};
// тип диаграммы (AreaChart - в данном примере) и id элемента в котором она будет отображена
// могут быть также: BarChart, PieChart, BubbleChart, CandlestickChart, ColumnChart, ComboChart, Gantt, OrgChart, GeoChart, Map, Histogram, LineChart, Sankey, Table, WordTree и др.
var chart = new google.visualization.AreaChart(document.getElementById('chart_div'));
chart.draw(data, options); // отрисовать диаграмму
}
// дополнения:
Чтобы отобразить значения данных на графике (аннотацию), нужно исправить данные для диаграммы таким образом
['Год', 'Продажи', {role:'annotation'}, 'Затраты', {role:'annotation'}],
['2013', 1000, 1000, 400, 400],
// показывать легенду сверху одной строкой
legend: {position: 'top', maxLines: 1},
// задать положение и размеры графика на выделенной ему области
chartArea:{left:80, top:80, width:'88%', height:'85%'},
// задать цвет и толщину 3, 4 и 5-й линий графика
series: [{}, {}, {color: 'green', visibleInLegend: true}, {type: 'line', color: 'lime', lineWidth: 2}, {type: 'line', color: 'Aquamarine', lineWidth: 2}],
// задать размер шрифта аннотаций
annotations: {textStyle: {fontSize: 11}}
// задать подписи горизонтальной оси с данными типа дата в 2 строки (где n - разделитель на 2 строки)
hAxis: {format: 'EEEnd'} // 1 строка: день недели, 2 строка: день месяца
hAxis: {format: 'dnMMM'} // 1 строка: день месяца, 2 строка: сокращённое название месяца
hAxis: {format: 'MMMnyyyy'} // 1 строка: сокращённое название месяца, 2 строка: год
google.charts.load("current", {packages:["timeline"], "language": "ru"});
// запустит функцию после отрисовки диаграммы
google.visualization.events.addListener(chart, 'ready', afterDraw); // добавить после строки var chart = new google.visualization.Timeline(container);
// функция перенесёт подписи наверх
function afterDraw() {
var g = document.getElementsByTagName("svg")[0].getElementsByTagName("g")[1];
document.getElementsByTagName("svg")[0].parentNode.style.top = '45px';
document.getElementsByTagName("svg")[0].style.overflow = 'visible';
var height = Number(g.getElementsByTagName("text")[0].getAttribute('y')) + 20;
g.setAttribute('transform','translate(0,-'+height+')');
// если нужно удалить последний элемент подписи
//var lastDateElement = g.querySelector("text:last-child");
//if (lastDateElement) {
// lastDateElement.remove();
//}
g = null;
}
CSS стили:
.ggl-tooltip {border: 1px solid #E0E0E0; font-family: Arial, Helvetica; font-size: 10pt; padding: 12px 12px 12px 12px;}
.ggl-tooltip div {padding: 6px 6px 6px 6px;}
.ggl-tooltip span {font-weight: bold;}
JS скрипт:
google.charts.load("current", {packages:["timeline"], "language": "ru"});
google.charts.setOnLoadCallback(drawTimeLine);
function drawTimeLine() {
var container = document.getElementById('sid_timeline');
var chart = new google.visualization.Timeline(container);
var dataTable = new google.visualization.DataTable();
dataTable.addColumn({ type: 'string', id: 'Position' });
dataTable.addColumn({ type: 'string', id: 'Name' });
dataTable.addColumn({ type: 'date', id: 'Start' });
dataTable.addColumn({ type: 'date', id: 'End' });
dataTable.addRows([
['165414 fine-turboers', 'Cpus 24 - 0.543h', new Date(2016,07,20, 13,37,32), new Date(2016,07,20, 15,43,19)],
['165418 fine-turboers', 'Cpus 24 - 0.534h', new Date(2016,07,20, 14,47,12), new Date(2016,07,20, 16,40,09)],
['165427 fine-turboers', 'Cpus 24 - 0.265h', new Date(2016,07,20, 18,01,23), new Date(2016,07,21, 00,02,53)],
]);
dataTable.insertColumn(2, {type: 'string', role: 'tooltip', p: {html: true}});
var dateFormat = new google.visualization.DateFormat({
pattern: 'd MMM yyyy' // ' hh:mm:ss'
});
let me1 = ["янв", "фев", "мар", "апр", "май", "июн", "июл", "авг", "сен", "окт", "ноя", "дек"];
for (var i = 0; i < dataTable.getNumberOfRows(); i++) {
var duration = (dataTable.getValue(i, 4).getTime() - dataTable.getValue(i, 3).getTime());
var days = parseInt( duration / (1000*60*60*24) ) + 1;
//var hours = parseInt( duration / 3600 ) % 24;
//var minutes = parseInt( duration / 60 ) % 60;
//var seconds = duration % 60;
var ddn = [' день', ' дня', ' дней'];
var tooltip = '<div class="ggl-tooltip"><span>' +
dataTable.getValue(i, 1) + '</span></div><div class="ggl-tooltip"><span>' +
dataTable.getValue(i, 0) + '</span>:<br>' +
dateFormat.formatValue(dataTable.getValue(i, 3)) + ' - ' +
dateFormat.formatValue(dataTable.getValue(i, 4)) + '</div>' +
'<div class="ggl-tooltip"><span>Длительность: </span>' +
days + sklonenie(days, ddn);
// hours + 'ч ' + minutes + 'м ' + seconds + 'с ';
dataTable.setValue(i, 2, tooltip);
}
var options = {
// timeline: { showRowLabels: false },
tooltip: {isHtml: true},
avoidOverlappingGridLines: false
};
chart.draw(dataTable, options);
}
// формат данных узлов и связующих линий содержащихся в html-элементе с id = cyj:
{"data":{"id":"n1", "foo": "текст узла 1"},"position":{"x":40,"y":50},"group":"nodes","removed":false,"selected":false,"selectable":true,"locked":false,"grabbable":true,"classes":"myst1"},
{"data":{"id":"n2", "foo": "текст узла 2"},"position":{"x":40,"y":50},"group":"nodes","removed":false,"selected":false,"selectable":true,"locked":false,"grabbable":true,"classes":"myst1"},
{"data":{"id":"e1","source":"n1","target":"n2"},"position":{},"group":"edges","removed":false,"selected":false,"selectable":true,"locked":false,"grabbable":true,"classes":""}
<style>
#cy {position: absolute; left: 0; top: 30; bottom: 0; right: 0; z-index: 999;}
#cyj {display: none;}
</style>
<script src="cytoscape.min.js"></script>
<script src="cytoscape-euler.js"></script>
<script>
var cy;
function graf() { // функция для отрисовки графа
$('#cy').html(''); // очистить контейнер графа
cd = $('#cyj').html(); // достать данные для элементов в json формате
sn = JSON.parse(cd); // парсим json-данные в массив элементов
cy = window.cy = cytoscape({
container: document.getElementById('cy'), // элемент-контейнер, куда отрисовать граф
layout: { // настройки для всего графа
name: 'euler', // тип графа euler (подключается отдельным js-файлом)
randomize: true, // формировать граф случайным образом при каждой отрисовке
//fit: false, // подгонять ли граф к области просмотра (меняет масштаб графа под размеры области просмотра, чтобы он вошел в неё целиком и ставит его посредине)
spacingFactor: 1.6, // задать расстояния между узлами
nodeDimensionsIncludeLabels: true, // определяет, включаются ли размеры метки при вычислении размеров узла
//pan: { x: 100, y: 100 }, // переместить график в указанное положение
animate: false // анимировать ли отрисовку графа
},
wheelSensitivity: 0.1, // чувствительность колеса мыши для изменения масштаба графа
style: [ // все стили
{
selector: 'node', // стиль для узлов
style: {
'shape': 'round-rectangle', // форма узла: прямоугольник с закруглёнными узлами
'width': '120', // шириной 120 пикселей
'font-size': '12', // шрифт внутри узла
'background-color': '#ffffff', // цвет фона узла
'border-width': '2', // граница вокруг узла 2 пиксела
'border-color': '#bbbbbb', // цвет границы вокруг узла
//'label': 'data(id)', // подпись над узлом
'content': 'data(foo)', // текст внутри узла
'text-max-width': '116', // максимальная ширина текста узла
'text-wrap': 'wrap', // переносить текст узла на новую строку при достижении предела ширины
'line-height': '1', // расстояние между строками у текста узла
'text-valign': 'center', // вертикальное выравнивание для текста узла: по центру
'text-halign': 'center' // горизонтальное выравнивание для текста узла: по центру
}
},
{selector: 'edge', style: {'line-color': '#126814', 'opacity': 0.5}}, // стиль для связующих линий
{selector: ':selected', style: {}}, // стиль для выделенных
{selector: '.myst1', style: {'background-color': '#d9ffde'}}, // мой стиль 1
{selector: '.myst2', style: {'background-color': '#ffdddd'}}, // мой стиль 2
{selector: '.myst3', style: {'background-color': '#deefff'}} // мой стиль 3
],
elements: sn // задаёт элементы
});
}
graf(); // отрисовать граф
// клик по элементу графа
cy.nodes().on('click', function(e){
var ele = e.target;
id = ele.data('id'); // получить id узла
cl = ele.classes(); // получить классы узла
//console.log(cl);
ele.toggleClass('myst1'); // добавить/удалить узлу класс myst1
ele.toggleClass('myst2'); // добавить/удалить узлу класс myst2
ele.data('foo', 'ку-ку'); // заменить текст узла
});
// поиск по графу
$("body").on("click", "#poisk_button", function () {
let p = $.trim($('#poisk_text').val());
cy.nodes().forEach(function(ele){
foo = ele.data('foo'); // получить текст узла
if (foo.lastIndexOf(p) != -1) {
console.log(foo);
}
});
});
</script>
// родителя нельзя сделать ребёнком своему ребёнку
// с помощью drag&drop любой элемент можно подчинить или переподчинить другому элементу, поменять порядок отображения
// с помощью drag&drop родителя можно перенести в любое место скопом вместе с деревом его детей
// поля в базе данных
id INT primary key AUTO_INCREMENT, // id сущности (файла)
name VARCHAR(32) NOT NULL, // название сущности (файла)
rod INT DEFAULT 0, // id родителя
npp SMALLINT DEFAULT NULL // номер по порядку
// CSS
.sidebar > ul > li > span > span {display: inline-block;}
// структура хранения дерева элементов (последний вложенный span нужен для задания отступа, отображающего уровень подчинения, внутри предпоследнего span хранится название элемента)
.sidebar > ul > li > span > span
drev = [[4, 'Лето', 0, 4],[3, 'Зима', 0, 3],[2, 'Осень', 0, 2],[1, 'Весна', 0, 1],[6, 'Июнь', 1, 2],[5, 'Август', 1, 1],[7, 'Ильин день', 5, 1]]; // данные с сервера получаемые при загрузке страницы (формат: [id, name, rod, npp], сортировка: ORDER BY rod, npp DESC)
ris_drev(); // отрисовать дерево при загрузке
// отрисовать дерево проектов при загрузке
function ris_drev() {
let drev2 = [...drev];
let m = [];
while (drev2.length > 0) { // пока в массиве есть элементы
fl = 0;
if (drev2[0][2] == 0) {
if (typeof m[0] === "undefined") {m[0] = [];}
m[0].push(drev2[0][0]); // родители 0 уровня
drev2.splice(0, 1);
fl = 1;
}
if (fl == 0) {
ml = m.length;
for (let j = 0; j < ml; j++) {
if (m[j].includes(drev2[0][2])) {
if (typeof m[j+1] === "undefined") {m[j+1] = [];}
m[j+1].push(drev2[0][0]); // родители 1 уровня
drev2.splice(0, 1);
}
if (drev2.length == 0) {break;}
}
}
if (drev2.length == 0) {break;}
}
m.forEach(function(itm, i, m) {
itm.forEach(function(it, j, itm) {
dd = el_drev_po_id(it);
if (i > 0) {pch = ' style="width:' + i + '0px;"';} else {pch = '';}
li = '<li data-id="' + it + '" data-rod="' + dd[2] + '" data-npp="' + dd[3] + '"><span id="link' + it + '"><span' + pch + '></span><i title="' + dd[1] + '" class="fas fa-folder"></i><samp class="svm">' + dd[1] + '</samp></span></li>';
if (i == 0) {$('.sidebar > ul:eq(0) > li:nth-child(1)').after(li);}
else {$('.sidebar > ul:eq(0) > li[data-id=' + dd[2] + ']').after(li);}
});
});
}
// функция добавляет прокладки между элементами, чтобы перетаскиванием на них элементов менять их порядок
function tx_rzd() {
let rzd = '<li ondrop="drop(event, this)" ondragover="allowDrow(event)" ondragenter="dragEnter(event)" ondragleave="dragLeave(event)" class="tx_rzd"></li>';
$('.tx_rzd').remove(); // удалить все разделители
$('.sidebar > ul:eq(0) > li:not(.tx_rzd)').each(function(i){
$(this).after(rzd);
});
}
// узнать есть ли подчинённые у id элемента
function pchin_est(id) {
return !!$(".sidebar > ul:eq(0) > li[data-rod=" + id + "]").length;
}
function drag(ev) { // во время хватания элемента
let ind = $(".sidebar > ul:eq(0) > li").index( $(ev.target) );
let id = $(ev.target).attr('data-id');
ev.dataTransfer.setData("ind", ind); // передает индекс перетаскиваемого элемента
ev.dataTransfer.setData("id", id); // передает id перетаскиваемого элемента
}
function drop(ev, block) { // во время бросания элемента
ev.preventDefault(); // отменить действие браузера по умолчанию
let ind = ev.dataTransfer.getData("ind"); // индекс схваченного элемента
let ide = ev.dataTransfer.getData("id"); // id схваченного элемента
phe = pchin_est(ide); // есть ли подчинённые у перетаскиваемого проекта
ind_b = +$(".sidebar > ul:eq(0) > li[class=tx_rzd]").index( $(block) );
kb = $(".sidebar > ul:eq(0) > li[class=tx_rzd]").length;
if ($(block).hasClass('tx_rzd')) { // менять порядок с учётом подчинения
rd = +$(".sidebar > ul:eq(0) > li:eq(" + ind + ")").attr('data-rod');
let pr = $(block).prev('li').find('span > span').css('width');
let pr_id = +$(block).prev('li').attr('data-id');
let pr_rod = +$(block).prev('li').attr('data-rod');
if (pr == undefined) {pr = 0;} else {pr = +pr.replace(/[^0-9]/g, '') / 10;}
let nx = $(block).next('li').find('span > span').css('width');
let nx_rod = +$(block).next('li').attr('data-rod');
if (nx == undefined) {nx = 0;} else {nx = +nx.replace(/[^0-9]/g, '') / 10;}
if ((pr == 0 && nx == 0) || (pr == 1 && nx == 0) || ind_b == 0 || ind_b == kb - 1) {
nrd = 0; // новый data-rod
prvr = 0; // проверить является ли перетаскиваемый элемент ребёнком самому себе
if (rd == 0 && phe == true) {
nph = -1; // новый pchin
rek = 0; // переписать pchin рекурсивно для подчинённого дерева
task = 1; // перетащить подчинённое дерево визуально вслед за элементом
} else if (rd == 0 && phe == false) {
nph = -1; // новый pchin
rek = 0; // переписать pchin рекурсивно для подчинённого дерева
task = 0; // перетащить подчинённое дерево визуально вслед за элементом
} else if (rd > 0 && phe == true) {
nph = 0; // новый pchin
rek = 1; // переписать pchin рекурсивно для подчинённого дерева
task = 1; // перетащить подчинённое дерево визуально вслед за элементом
} else if (rd > 0 && phe == false) {
nph = 0; // новый pchin
rek = 0; // переписать pchin рекурсивно для подчинённого дерева
task = 0; // перетащить подчинённое дерево визуально вслед за элементом
}
} else {
if ((pr == 0 && nx == 1) || (pr < nx && pr > 0)) {
nrd = pr_id; // новый data-rod
} else if (pr == nx && nx > 0) {
nrd = pr_rod; // новый data-rod
} else if (pr > nx && nx > 0) {
nrd = nx_rod; // новый data-rod
}
if (rd >= 0 && phe == true) {
nph = nx; // новый pchin
rek = 1; // переписать pchin рекурсивно для подчинённого дерева
task = 1; // перетащить подчинённое дерево визуально вслед за элементом
prvr = 1; // проверить является ли перетаскиваемый элемент ребёнком самому себе
} else if (rd >= 0 && phe == false) {
nph = nx; // новый pchin
rek = 0; // переписать pchin рекурсивно для подчинённого дерева
task = 0; // перетащить подчинённое дерево визуально вслед за элементом
prvr = 0; // проверить является ли перетаскиваемый элемент ребёнком самому себе
}
}
drop_do(nrd, nph, rek, task, prvr, ide, block); // произвести перенос при drop
} else { // подчинить
let did = $(block).attr('data-id');
if (ide == did) {return false;} // при кидании на самого себя ничего не делать
let pp = $(block).find('span > span').attr('style');
if (pp == undefined) {pp = 0;} else {
pp2 = $(block).find('span > span').css('width');
pp = +pp2.replace(/[^0-9]/g, '') / 10;
}
nrd = did; // новый data-rod
nph = pp + 1; // новый pchin
if (phe == true) { // подчинённые есть
rek = 1; // переписать pchin рекурсивно для подчинённого дерева
task = 1; // перетащить подчинённое дерево визуально вслед за элементом
prvr = 1; // проверить является ли перетаскиваемый элемент ребёнком самому себе
} else if (phe == false) { // подчинённых нет
rek = 0; // переписать pchin рекурсивно для подчинённого дерева
task = 0; // перетащить подчинённое дерево визуально вслед за элементом
prvr = 0; // проверить является ли перетаскиваемый элемент ребёнком самому себе
}
drop_do(nrd, nph, rek, task, prvr, ide, block); // произвести перенос при drop
}
block.style.outline = ""; // убрать рамку у целевого блока, когда перетаскивание окончено
}
function dragEnter(ev) {
if (ev.target.className == "cart") {
ev.target.style.outline = "2px solid red !important"; // задать рамку целевому блоку, когда перетаскиваемый элемент находится над ним
}
}
function dragLeave(ev) {ev.target.style.outline = "";} // убрать рамку у целевого блока, когда перетаскиваемый элемент покинул его
function allowDrow(ev) {ev.preventDefault();} // отменить действие браузера по умолчанию во время перетаскивания над целевым блоком
function dragEnd(ev) {ev.target.style.outline = "";} // срабатывает на элементе который схватили по завершении перетаскивания - убрать рамку
// произвести перенос при drop
function drop_do(nrd, nph, rek, task, prvr, ide, block) {
if (prvr == 1) {
aa = prver_rod(nrd, ide);
if (aa) {alert('Родитель не может стать своим ребёнком'); return false;}
}
$(".sidebar > ul:eq(0) > li[data-id=" + ide + "] > span > span").removeAttr('style');
if (nph != -1) {
if (nph > 0) {
$(".sidebar > ul:eq(0) > li[data-id=" + ide + "] > span > span").css('width', nph + '0px');
}
}
$(".sidebar > ul:eq(0) > li[data-id=" + ide + "]").attr('data-rod', nrd);
$(block).after($(".sidebar > ul:eq(0) > li[data-id=" + ide + "]"));
if (task == 1) { // перетащить подчинённое дерево визуально вслед за элементом
kro = 1;
idro = [ide];
nph2 = nph;
while (idro.length > 0) {
idro.forEach(function(itm, i, idro) {
nph2 = nph2 + 1
kro = $(".sidebar > ul:eq(0) > li[data-rod=" + itm + "]").length;
idro2 = [];
if (kro > 0) {
$($(".sidebar > ul:eq(0) > li[data-rod=" + itm + "]").get().reverse()).each(function(i){
idf = $(this).attr('data-id');
idro2.push(idf);
if (rek == 1) { // переписать pchin рекурсивно для подчинённого дерева
$(this).find('span > span').removeAttr('style');
$(this).find('span > span').css('width', nph2 + '0px');
}
$(".sidebar > ul:eq(0) > li[data-id=" + itm + "]").after($(this));
});
}
});
idro = [...idro2];
}
}
tx_rzd(); // добавить/обновить прокладки
$('.tx_rzd').addClass('tx_rzd_upd');
ndr = sobr_drev(); // собрать дерево в массив
server({'r':2, 'drev':ndr}); // отправить на сервер
}
// собрать дерево в массив для его отправки в БД и переотрисовки
function sobr_drev() {
let ndr = [];
r0l = $('.sidebar > ul:eq(0) > li[data-rod=0]').length;
$($('.sidebar > ul:eq(0) > li[data-rod=0]').get().reverse()).each(function(i){
id = +$(this).attr('data-id');
rd = +$(this).attr('data-rod');
ndr.push([id, rd, r0l]);
r0l--;
});
let ln = [];
let nb = [];
$($('.sidebar > ul:eq(0) > li[data-id] > span > span[style]').get().reverse()).each(function(i){
pp = $(this).css('width');
pp = +pp.replace(/[^0-9]/g, '') / 10; // уровень дерева
id = +$(this).closest('li').attr('data-id');
rd = +$(this).closest('li').attr('data-rod');
if (typeof ln[rd] === "undefined") { // номер по порядку (в обратном порядке)
rpl = $('.sidebar > ul:eq(0) > li[data-id][data-rod=' + rd + ']').length;
ln[rd] = rpl;
} else {ln[rd] = ln[rd] - 1;}
if (typeof nb[pp] === "undefined") {nb[pp] = [];}
nb[pp].push([id, rd, ln[rd]]); // запоминаем по уровням
});
nb.forEach(function(itm, i, nb) {
itm.forEach(function(it, i, itm) {
ndr.push(it); // пишем по уровням в основной массив
});
});
ndr = JSON.stringify(ndr);
return ndr;
}
// по id контейнера узнать количество колонок CSS columns, которые браузер создал автоматически
function columns_count(id) {
let ch = $('#' + id).height(); // высота контейнера
let cc = 1, nk = 0;
$('#' + id + ' .dch').each(function(i){
let he = $(this).outerHeight(true); // высота дочернего блока
nk = nk + he;
if (nk > ch) {nk = he; cc = cc + 1;}
});
return cc;
}
// в обычном режиме javascript видит только монитор, на котором открыто основное окно, если попытаться открыть новое окно (попап) на площади другого монитора, то оно всё равно откроется на текущем мониторе, чтобы это исправить, нужно запросить у пользователя разрешение на использование всех мониторов зарегистрированных в системе
// работа с несколькими мониторами в системе
let cachedScreens = null;
const isSupported = "getScreens" in window || "getScreenDetails";
const getScreensInfo = async () => {
if (isSupported) {
if (cachedScreens) {
return cachedScreens.screens;
} else {
cachedScreens = "getScreens" in window ? await window.getScreens() : await window.getScreenDetails();
return cachedScreens.screens;
}
}
return [window.screen];
};
// асинхронная функция, чтобы открыть попап
async function win_new() {
await getScreensInfo(); // ждём получения информации о мониторах в системе (также запрашивает разрешение на использование нескольких мониторов - делает это 1 раз для домена)
console.log(cachedScreens); // покажет массив данных обо всех мониторах в системе, где left и top для каждого монитора укажут в какой конфигурации мониторы находятся относительно друг друга
tp = -500; lf = 2500; // координаты положения нового окна (попапа)
win = window.open("", "_blank", "toolbar=no,location=no,directories=no,status=no,menubar=no,scrollbars=yes,resizable=yes,width=500,height=300,top=" + tp + ",left=" + lf);
}
Поделиться статьей: