Как можно добавлять сложнейшие анимации, которые на CSS+JS не написать?
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()
на самописный поиск, останавливающийся на элементе, бОльшем или меньшем искомого.const routes = [
{ path: '/foo', component: Foo },
{ path: '/bar', component: Bar, isDevOnly: true },
{ path: '*', component: Baz },
]
const router = new VueRouter({
routes: routes.filter(r => DEVELOPMENT || !r.isDevOnly)
})
DEVELOPMENT
из переменной окружения с помощью DefinePluginconst webpack = require('webpack');
module.exports = {
// ...
plugins: [
new webpack.DefinePlugin({
DEVELOPMENT: JSON.stringify(process.env.mode === 'development'),
}
]
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);
}
function myFunction() {
var sourceSheet = SpreadsheetApp.getActiveSpreadsheet(); //лист откуда берем данные
var activeRow = list1.getActiveSheet().getActiveCell().getRow(); //номер активной ячейки
var destSheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("Журнал ввода данных");
var lastRow = destSheet.getLastRow();
destSheet.insertRowAfter(lastRow);
var destRow = lastRow + 1;
function copyCell(colFrom, colTo) {
sourceSheet.getRange(activeRow, colFrom).copyTo(destSheet.getRange(destRow, colTo));
}
copyCell(1, 1); // номер участка
copyCell(2, 2); // имя человека
copyCell(4, 3); // дата начала работ
copyCell(6, 4); // дата завершения работ
}
function onOpen(e) {
SpreadsheetApp.getUi()
.createMenu('Работа с Журналом')
.addItem('Копировать в журнал', 'myFunction')
.addToUi();
}
6/6
5/6
4/6
6/6 * 5/6 * 4/6 = 120/216 = 5/9
docker build
(док) создаёт новый image
(образ) В вашем примере с тегом python-barcode
docker run
запускает из образа контейнер. Можно и не один, а несколько, даже параллельно. В вашем примере имя для него сгенерится автоматом, какая-нибудь смешная комбинация двух слов. Контейнер может работать, останавливаться, перезапускаться. Можно удалить контейнер. Контейнер не изменяет образ, из которого создан – он «накатывает» свою деятельность поверх, в новых слоях.базовый FROM образ -- образ с доп. слоями = ваш новый образ -- контейнер и изменения -- образ с изменениями
Host: ...
перенаправлять/проксировать запрос на соотв. виртуальный сервер.server {
server_name site.ru;
location / {
proxy_pass http://127.0.0.1:8000; # допустим, тут слушает основной
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
# ... ещё инструкции - передача заголовков, кэширование..
}
}
server {
server_name name1.site.ru;
location / {
proxy_pass http://127.0.0.1:8001; # вирт-1
# ...
}
}
server {
server_name name2.site.ru;
location / {
proxy_pass http://127.0.0.1:8002; # вирт-2
# ...
}
}