Подсказки и приемы по программированию на 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: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 на странице
if ($('#banner').length) { // проверка на существование
alert('элемент banner существует');
}
if (!$('#banner').length) { // проверка на не существование
alert('элемент banner не существует');
}
if (!$('.mtk').length) { // проверка на не существование набора элементов
alert('элементов с классом mtk не существует');
}
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();
$("#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)
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 type="button" с id = bt (кнопка перестанет отзываться на действия пользователя)
$('#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('Скрыть', 'Показать');
});
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 в обратном порядке
Обработка событий
var ow;
ow = window.open('doc1.htm');
$("#el1").click(function(){
ow.close(); // закрыть окно, открытое с помощь window.open
});
// закрыть окно, открытое пользователем, с помощью Javascript нельзя
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;
}
});
$(".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('Отвели');
});
$('#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() {
// команды
});
$("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()
$(".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 также останется на своём старом месте
$("#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>'); // вставит строку после первой строки в таблице
Получение данных с сервера
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);
}
});
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; // задать значение массива по индексу
dm = arr.push("лето"); // создает элемент массива записывая его в конец - с индексом на 1 больше, чем у последнего элемента массива (возвращает длину массива)
dm = arr.unshift("зима"); // создает элемент массива записывая его в начало (к индексам других элементов прибавляется 1) (возвращает длину массива)
k = arr[0]; // присвоить значение переменной по индексу массива
r = arr.length; // узнать длину массива - количество элементов массива включая пустые элементы (считает как последний индекс + 1)
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"};
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 - просто обрезает лишние цифры
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 днём года
// вариант 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;
}
echo 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("лето"); // выведет "лето настало медвед"
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
Разные функции и возможности
// 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"><div id="chart_div" style="width: 100%; height: 500px;"></div></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}}
// формат данных узлов и связующих линий содержащихся в 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;
}
Поделиться статьей: