rocket-lazy-load
можно деактивировать для определённых картинок, data-no-lazy="1"
<img src="logo.png" data-no-lazy="1" title="Лого от Артемия за килобакс" alt="">
var divContent
у вас строка текста (пусть и HTML).appendChild()
ожидает не строку текста, а HTML узел (Node) – его можно создать как у вас выше document.createElement()
.element.innerHTML = myHTML;
appendChild()
Но у вас требуется два инпута вставить, с множеством атрибутов. На чистом JS это займет несколько строк:var input = document.createElement('input');
input.type = "text";
input.placeholder = "Наименование";
input.className = "expenses-item";
newDiv.appendChild(input);
input = document.createElement('input');
input.type = "text";
input.placeholder = "Цена";
input.className = "expenses-item";
newDiv.appendChild(input);
const everyNth = (arr, n) => arr.filter((e, i) => i % n === 0);
// применение
everyNth([0, 11, 22, 33, 44, 55, 66, 77], 7) // [0, 77]
for()
:function everyNth(arr, n) {
const result = [];
for (let i=0; i<arr.length; i+=n) result.push(arr[n]);
return result;
}
for()
быстрее в 7 раз!Content-type
: вы передрали код из примера с application/x-www-form-urlencoded
, который предполагает отправку данных как в GET-параметрах: a=1&b=2&c=3
request.setRequestHeader("Content-Type", "application/json;charset=UTF-8");
php://input
$data = json_decode(file_get_contents("php://input"));
forEach()
вызывает функцию по очереди с каждым из элементов массива. В данном примере вызовется function(1), function(3), function(4), ... function(5)result
это объект, где свойствами будут встреченные цифры (как строки).result
нет, и, например, result[1]
будет поначалу undefined
. И в таком случае создаётся это свойство со значением 1
.undefined
, и оно будет увеличено на 1.Math.round()
для определения попадания в интервал:var priceProduct = 2000;
var monthlyPayment = 230;
var precision = 1e-6; // точность одна миллионная
var months = priceProduct / monthlyPayment;
var nearest = Math.round(months);
var diff = months - nearest;
if (diff > precision) months = nearest + 1; // == Math.ceil()
indexOf()
const text2 = 'You know nothing Jon Snow';
function countUniqChars(str) {
return new Set(str.split('')).size;
}
countUniqChars(text2) // 13
позиция-из-которой
, сколько-выдрать
, вставить-этого
, вставить-ещё
, ...function swap(arr, from, to) {
// выдёргиваем:
const A = arr.splice(from, 1)[0];
const B = arr.splice(to-1, 1)[0];
// -1 т.к. массив стал короче после первой операции
// вставляем
arr.splice(from, 0, B); // 0 - ничего не вырезаем, только вставляем
arr.splice(to, 0, A);
}
splice()
function swap(arr, from, to) {
// выдёргиваем-копируем:
const A = arr[from];
const B = arr[to];
// вставляем-заменяем
arr[from] = B;
arr[to] = A;
}
const zip = arr => arr
.reduce((agg, c) => {
const iR = agg.indexOf(c + 1);
const iL = agg.lastIndexOf(c - 1);
if (!!~iR && !!~iL) agg.splice(iL, 2); // закрыли дырку
else if (!!~iR) agg[iR] = c; // сдвинули границу
else if (!!~iL) agg[iL] = c; // то же
else { // вставляем сироту - найти позицию сразу после меньшего
let pos = 0;
while (pos < agg.length && agg[pos] < c) pos++;
agg.splice(pos, 0, c, c); // вставляем дважды
}
return agg;
}, [])
.reduce((agg, c, i, arr) => {
if (!(i&1)) agg.push(arr[i+1] === c ? c : [c, arr[i+1]].join('-'));
return agg;
}, [])
.join(', ')
;
[ 0, 5, 8, 9, 11, 11 ]
indexOf()
и lastIndexOf()
на самописный поиск, останавливающийся на элементе, бОльшем или меньшем искомого.console.log(this); // window
this
не принимает значение кнопки, а наследует его из внешнего кода. В данном случае, глобального, поэтому this === window
this
будет нажатой кнопкой. Так бы работало без стрелочной функции, если по-старинке передавали function(evt) {}
0. Получение ключа доступа
Для работы с виджетами в сообществе необходимо получить токен сообщества с правом доступаapp_widget
при помощи события VK Connect: VKWebAppGetCommunityAuthToken в приложении с типом VK Mini Apps.
npm install @vkontakte/vk-connect
index.js
:import connect from '@vkontakte/vk-connect';
// Sending event to client
connect
.sendPromise('VKWebAppGetCommunityAuthToken', {
"app_id": 6909581, // id вашего свежесозданного mini App
"group_id": 1, // id группы, где вы админ, куда виджет
"scope": "app_widget"
})
.then(data => {
// Обработка события в случае успеха
console.log(data);
})
.catch(error => {
//Обработка событияв случае ошибки
});
Затем, наверное, webpack'ом билдится готовый скрипт, который подгружается в браузер.// Set the name of the hidden property and the change event for visibility
var hidden, visibilityChange;
if (typeof document.hidden !== "undefined") { // Opera 12.10 and Firefox 18 and later support
hidden = "hidden";
visibilityChange = "visibilitychange";
} else if (typeof document.msHidden !== "undefined") {
hidden = "msHidden";
visibilityChange = "msvisibilitychange";
} else if (typeof document.webkitHidden !== "undefined") {
hidden = "webkitHidden";
visibilityChange = "webkitvisibilitychange";
}
var videoElement = document.getElementById("videoElement");
// If the page is hidden, pause the video;
// if the page is shown, play the video
function handleVisibilityChange() {
if (document[hidden]) {
videoElement.pause();
} else {
videoElement.play();
}
}
// Warn if the browser doesn't support addEventListener or the Page Visibility API
if (typeof document.addEventListener === "undefined" || hidden === undefined) {
console.log("This demo requires a browser, such as Google Chrome or Firefox, that supports the Page Visibility API.");
} else {
// Handle page visibility change
document.addEventListener(visibilityChange, handleVisibilityChange, false);
// When the video pauses, set the title.
// This shows the paused
videoElement.addEventListener("pause", function(){
document.title = 'Paused';
}, false);
// When the video plays, set the title.
videoElement.addEventListener("play", function(){
document.title = 'Playing';
}, false);
}
[10, 20, 30, 50, 235, 3000].filter(n => !!~[1,2,5].indexOf(+n.toString()[0]))
// результат [ 10, 20, 50, 235 ]
Вывод на экран пилите самостоятельно.filter()
оставит только те элементы, для которых функция внутри вернёт true
. Функция аргумент (в скобках) применяется по очереди к каждому элементу массива (числу).+
).indexOf()
ищет полученную первую цифру в массиве допустимых: 1, 2, 5 и возврашает его индекс (0, 1 или 2) или -1, если не найдено.~
из -1 сделает 0. А из любого другого числа (из 0, 1 или 2) – сделает ненулевое число. Два !!
это два булевых оператора отрицания. Из аргумента делают true
или false
. Из 0 получится false
, из любого другого true
. Таким образом связка !!~
и indexOf()
даёт ответ на вопрос найден или не найден? getRangeAt(0)
Range
есть свойства startOffset
и endOffset
– то, про что спрашиваете.value=""
function reset() {
[...document.querySelectorAll('section.main input[type="text"]')]
.forEach( el => el.value='' )
;
}
document.getElementsByClassName('budget_day-value')[0]
document.querySelector('.budget_day-value')
<label>
, и либо указывать id
инпута в атрибуте for=""
, либо включать инпут внутрь этого лейбла. Так клик по названию поля сделает фокус внутри этого поля.
Замыкания
В программировании есть общий термин: «замыкание», – которое должен знать каждый разработчик.
Замыкание – это функция, которая запоминает свои внешние переменные и может получить к ним доступ. В некоторых языках это невозможно, или функция должна быть написана специальным образом, чтобы получилось замыкание. Но, как было описано выше, в JavaScript, все функции изначально являются замыканиями (есть только одно исключение, про которое будет рассказано в Синтаксис "new Function
").
То есть, они автоматически запоминают, где были созданы, с помощью скрытого свойства[[Environment]]
и все они могут получить доступ к внешним переменным.
Когда на собеседовании фронтенд-разработчик получает вопрос: «что такое замыкание?», – правильным ответом будет определение замыкания и объяснения того факта, что все функции в JavaScript являются замыканиями, и, может быть, несколько слов о технических деталях: свойстве[[Environment]]
и о том, как работает лексическое окружение.