return [...el].map((n) => new Select(n));
Select
на this.constructor
. const checkedTexts = (el, selector) =>
Array.from(el.querySelectorAll(`${selector}:checked`), n => n.parentNode.innerText);
const propertyText = (el, selector) =>
el.querySelector(selector).innerText.split(': ')[1];
document.querySelector('.container-filter').addEventListener('input', function() {
const maxPrice = parseInt(this.querySelector('.range').value);
const brands = checkedTexts(this, '.input');
const years = checkedTexts(this, '.input-date');
document.querySelectorAll('.device .laptop').forEach(n => {
const price = parseInt(propertyText(n, '.laptop-price'));
const brand = propertyText(n, '.laptop-name');
const year = propertyText(n, '.laptop-year');
n.style.display = (
(maxPrice >= price) &&
(!brands.length || brands.includes(brand)) &&
(!years.length || years.includes(year))
)
? 'block'
: 'none';
});
});
const newStr = str
.split(' ')
.map(function([...word]) {
const sorted = word.filter(this).sort((a, b) => b.localeCompare(a));
return word.map(n => this(n) ? sorted.pop() : n).join('');
}, RegExp.prototype.test.bind(/[a-z]/i))
.join(' ');
str.replace(/(\d{2})(\d{2})/, '$1.$2.')
// или
str.replace(/(?=\d{4}$|\d{6}$)/g, '.')
// или
str.match(/(..)(..)(.+)/).slice(1).join('.')
// или
[ 0, 2, 4 ].map((n, i, a) => str.slice(n, a[i + 1])).join`.`
// или
[...str].reduce((acc, n, i) => acc + n + ([ ,'.',,'.' ][i] || ''))
// или
''.concat(...Array.from(str, (n, i) => '24'.includes(i) ? `.${n}` : n))
on: {
breakpoint() {
this.el.classList.toggle('класс', this.slides.length < this.params.slidesPerView);
},
},
ref={ref}
элементу, который собираетесь скрывать.Не могу закрыть поп-ап
dialog: [],
dialog[index]= false
При нажатии на кнопку, при выборе 3 изображения на превью открывается всегда первое.
data: () => ({
slide: null,
dialog: false,
...
}),
methods: {
openDialog(slideIndex) {
this.slide = slideIndex;
this.dialog = true;
},
...
},
v-row
v-col(v-for="(n, i) in pictures")
v-item
v-img(height="100", width="100", :src="n", @click="openDialog(i)")
v-col(hidden="")
v-dialog(v-model="dialog")
v-carousel(v-model="slide")
v-carousel-item(v-for="n in pictures")
v-img(:src="n")
v-btn(@click="dialog = false") close dialog
<div className="mainWindow">
{this.props.children}
</div>
<posts :posts="$store.state.posts" />
<router-link :to="{ name: 'home', params: { posts } }">home</router-link>
this.$router.push({
name: 'home',
params: {
posts: this.posts,
},
});
router-link
или вызова $router.push
. При этом, если переход осуществляется не из корневого компонента, то, чтобы дотянуться до posts, придётся ещё и $root
использовать. В случае же, когда пользователь решит осуществить переход посредством адресной строки браузера, то ничего передать не получится.router-view
, тогда они будут переданы как параметры в компонент текущего маршрута: <router-view :posts="post" />
.$attrs
). Чтобы передавать что надо только куда надо, можно оформить параметры, передаваемые в router-view
, как вычисляемое свойство, значение которого будет зависеть от текущего маршрута:computed: {
routeParams() {
return что-то, в зависимости от this.$route;
},
},
<router-view v-bind="routeParams" />
function Modal(props) {
const root = useRef();
useEffect(() => {
const onClick = e => root.current.contains(e.target) || закрытьОкно();
document.addEventListener('click', onClick);
return () => document.removeEventListener('click', onClick);
}, []);
return (
<div ref={root}>
...
</div>
);
}
function Modal(props) {
return (
<div
className="modal-overlay"
onClick={e => (e.currentTarget === e.target) && закрытьОкно()}
>
...
</div>
);
}
.modal-overlay {
position: absolute;
left: 0;
top: 0;
width: 100vw;
height: 100vh;
background: rgba(0, 0, 0, 0.5);
}
document.querySelector('table').addEventListener('click', ({ target: t }) => {
if (t.classList.contains('save_order')) {
const tr = t.closest('tr'); // всё, идентифицировали
}
});
arr.pop();
// или
arr.length -= !!arr.length;
// или
arr.splice(-1);
const count = сколько надо удалить;
):for (let i = count; --i >= 0 && arr.length; arr.pop()) ;
// или
arr.length -= Math.max(0, Math.min(arr.length, count));
// или
count > 0 && arr.splice(-count);
echo implode('', array_map(function($author, $book) {
return '<p>Книга '.$book['nameBook'].', ее написал '.$author['fio'].', '.$author['email'].'</p>';
}, $arr['authors'], $arr['books']));
document.addEventListener('input', ({ target: t }) => {
if (t.classList.contains('rating__value')) {
const value = +t.value;
t.closest('.item-rating').querySelector('.rating__dynamic').innerHTML = Array
.from({ length: 5 }, (n, i) => `<span class="char">${'☆★'[+(value > i)]}</span>`)
.join('');
}
});
document.querySelectorAll('.rating__value').forEach(n => {
n.dispatchEvent(new Event('input', { bubbles: true }));
});
for (const n of document.getElementsByClassName('rating__value')) {
n.previousElementSibling.innerHTML = '<span class="char"></span>'.repeat(5);
n.addEventListener('input', onRatingInput);
onRatingInput.call(n);
}
function onRatingInput() {
const value = this.value | 0;
const stars = this.previousElementSibling.children;
for (let i = 0; i < stars.length; i++) {
stars[i].innerText = value > i ? '★' : '☆';
}
}