preg_match_all('/\b[а-яё]+\b/ui', $str, $cyrillic);
preg_match_all('/\b[a-z]+\b/i', $str, $latin);
const getNested = (obj, keys) => keys.reduce((p, c) => p?.hasOwnProperty(c) ? p[c] : null, obj);
Object.keys(obj).forEach(n => n !== key && delete obj[n]);
obj = { [key]: obj[key] };
const deleteKeys = (obj, except) =>
Object.keys(obj).forEach(n => except.includes(n) || delete obj[n]);
const obj = { a: 1, b: 2, c: 3, d: 4 };
deleteKeys(obj, [ 'a' ]);
console.log(obj); // {a: 1}
const pick = (obj, keys) =>
Object.fromEntries(keys.map(n => [ n, obj[n] ]));
const obj = { a: 1, b: 2, c: 3, d: 4 };
console.log(pick(obj, [ 'a', 'd' ])); // {a: 1, d: 4}
const className = 'select';
const sumEl = document.querySelector('.sum');
const sum = elements =>
Array.prototype.reduce.call(
elements,
(acc, n) => acc + (+n.value || 0),
0
);
const updateSum = () => sumEl.textContent = sum(document.getElementsByClassName(className));
document.addEventListener('change', e => e.target.classList.contains(className) && updateSum());
updateSum();
const selects = document.querySelectorAll(`.${className}`);
const updateSum = () => sumEl.innerText = sum(selects);
selects.forEach(n => n.addEventListener('change', updateSum));
updateSum();
.test('fileSizes', 'Resolution at least 120x120px', value => {
return new Promise(resolve => {
const img = new Image();
img.onload = () => resolve(img.width >= 120 && img.height >= 120);
img.src = window.URL.createObjectURL(value);
});
})
.submenu
, он должен находится внутри того же li
, что и соответствующий ему .profile-menu-trigger
.$('.profile-menu')
.on('mouseenter', '.profile-menu-trigger', function() {
$(this).next('.submenu').fadeIn(500);
})
.on('mouseleave', 'li', function() {
$(this).find('.submenu').fadeOut(500);
});
$('селектор контейнеров пар слайдеров').each(function() {
$('.slider-for', this).slick({
...
asNavFor: $('.slider-nav', this),
});
$('.slider-nav', this).slick({
...
asNavFor: $('.slider-for', this),
});
});
console.log(Object.entries(obj).reduce((max, n) => n[1] > max[1] ? n : max).join(': '))
v-for
, которому будет передаваться массив с данными. Блок базовой комплектации примет примерно такой вид:baseOptions: [
{ name: 'Свойство 1', price: 10000 },
{ name: 'Свойство 2', price: 11000 },
...
<ul>
<li v-for="n in baseOptions">{{ n.name }} ({{ n.price }})</li>
</ul>
v-model
):extraOptions: [
{ name: 'Пакет 1', price: 16000, checked: false },
{ name: 'Пакет 2', price: 17000, checked: false },
...
<div v-for="n in extraOptions">
<input type="checkbox" v-model="n.checked">
<label>{{ n.name }}</label>
</div>
methods: {
sum: arr => arr.reduce((acc, n) => acc + n.price, 0),
computed: {
baseSum() {
return this.sum(this.baseOptions);
},
extraSum() {
return this.sum(this.extraOptions.filter(n => n.checked));
},
filters: {
price: val => `${val.toLocaleString()} р.`,
<span>{{ baseSum | price }}</span>
<span>{{ extraSum | price }}</span>
<gmap-info-window
:options="infoOptions"
:position="infoWindowPos"
:opened="infoWinOpen"
@closeclick="infoWinOpen = false"
>
{{ infoContent }}
</gmap-info-window>
onMarkerClick(e) {
this.infoWindowPos = e.latLng; // задаём положение окна, над кликнутым маркером
this.infoContent = JSON.stringify(e.latLng); // задаём контент окна, передаётся в слот
this.infoWinOpen = true; // открываем окно
},
if (counting >= 10) { level++; counting = 0;
function getScore(arr) {
const points = [ 0, 40, 100, 300, 1200 ];
let score = 0;
let lines = 0;
for (const n of arr) {
score += points[n] * (1 + (lines / 10 | 0));
lines += n;
}
return score;
}
$('.away-players').text(function(i, text) {
return $('.subs-players td:even')
.get()
.map(n => $(n).text().split(', '))
.reduce((text, n) => text.replace(n[1], `(${n.join(' ')})`), text);
});