class App extends React.Component {
state = {
selected: {},
groups: [
[
[ 'value_a1', 'value_a2', 'value_a3' ],
[ 'value_b1', 'value_b2', 'value_b3' ],
[ 'value_c1', 'value_c2', 'value_c3' ],
],
[
[ 'value_a1', 'value_b1', 'value_c1' ],
[ 'value_a2', 'value_b2', 'value_c2' ],
[ 'value_a3', 'value_b3', 'value_c3' ],
],
],
}
onChange = (e, groupIndex, itemIndex) => {
const selectedGroup = this.state.groups[groupIndex][itemIndex];
const selectedInfo = this.state.selected[groupIndex] || [];
this.setState({
selected: {
...this.state.selected,
[groupIndex]: e.target.checked
? selectedInfo.concat(selectedGroup)
: selectedInfo.filter(n => !selectedGroup.includes(n))
},
});
}
render() {
const { selected, groups } = this.state;
const matched = (selected[0] || []).filter(n => {
return groups.every((group, i) => (selected[i] || []).includes(n));
});
return (
<div>
{groups.map((group, groupIndex) => (
<ul>
{group.map((item, itemIndex) => (
<li>
<input
type="checkbox"
onChange={(e) => this.onChange(e, groupIndex, itemIndex)}
/>
{item.map(val => <span>{val}</span>)}
</li>
))}
</ul>
))}
<div>
{matched.map(val => <span>{val}</span>)}
</div>
</div>
);
}
}
computed: {
routeAnimation() {
return что-то, зависящее от this.$route;
},
},
<transition :name="routeAnimation">
<div :key="routeAnimation"></div>
</transition>
this.renderer.createElement('svg');
this.renderer.createElement('svg', 'svg');
this.renderer.createElement('circle');
this.renderer.createElement('circle', 'svg');
Мне этот механизм не понятен.
Как это можно понять, это документированная возможность?
Comment
- судя по имени и по коду, он должен рендерить один комментарий, а у вас массив. Наверное, тут нужен ещё один компонент - список комментариев.const Comment = ({ general, job, address }) => (
<li>
<div>first name: {general.firstName}</div>
<div>last name: {general.lastName}</div>
<div>company: {job.company}</div>
<div>address: {address.country}, {address.city}, {address.street}</div>
</li>
);
const CommentList = ({ comments }) => (
<ul>
{comments.map(n => <Comment {...n} />)}
</ul>
);
ReactDOM.render(
<CommentList comments={comments} />,
document.getElementById('root')
);
$('.button').click(function() {
const $this = $(this);
const $content = $this.closest('.item').find('.block');
if ($this.hasClass('closed')) {
$this.removeClass('closed').html('Скрыть ↑');
$content.slideDown();
} else {
$this.addClass('closed').html('Показать ↓');
$content.slideUp();
}
}).click();
Приходит массив объектов, и в объекте надо менять свойствоenabled: true
соответственно в другом объекте это свойство нужно заменить наfalse
.
.highlighted {
color: red;
font-weight: bold;
font-size: 1.5em;
}
class App extends React.Component {
state = {
items: [ 'aaa', 'aa1', 'ab1', 'zzz', '00!', 'lorem ipsum dolor...' ],
search: '',
}
render() {
const { items, search } = this.state;
const regex = RegExp(search, 'g');
const replacement = '<span class="highlighted">$&</span>';
return (
<div>
<input value={search} onChange={e => this.setState({ search: e.target.value })} />
{search &&
<ul>
{items.filter(n => n.includes(search)).map(n =>
<li dangerouslySetInnerHTML={{ __html: n.replace(regex, replacement) }} />
)}
</ul>}
</div>
);
}
}
const Input = ({ label, ...props }) => (
<div>
<label>
{label}
<input {...props} />
</label>
</div>
);
class App extends React.Component {
state = {
from: 'Москва',
to: 'Питер',
}
onChange = ({ target: { value, name } }) => {
this.setState(() => ({
[name]: value,
}));
}
swap = () => {
this.setState(({ from, to }) => ({
from: to,
to: from,
}));
}
render() {
return (
<div>
<button onClick={this.swap}>swap</button>
<Input label="откуда" value={this.state.from} name="from" onChange={this.onChange} />
<Input label="куда" value={this.state.to} name="to" onChange={this.onChange} />
</div>
);
}
}
const container = document.querySelector('ul');
const itemSelector = 'li';
const randomStyles = () => ({
'background-color': `#${(Math.random() * 0xFFFFFF | 0).toString(16).padStart(6, 0)}`,
'padding-left': `${Math.random() * 100 | 0}px`,
});
.active {
border: 3px dashed blue;
}
const update = (el, styles) => (
Object.assign(el.style, styles),
el.classList.toggle('active')
);
container.querySelectorAll(itemSelector).forEach(function(n) {
n.addEventListener('click', this);
}, function() {
document.querySelectorAll(`.${this.id}`).forEach(function(n) {
update(n, this);
}, randomStyles());
});
container.addEventListener('click', ({ target: t }) => {
if ((t = t.closest(itemSelector)) && container.contains(t)) {
const styles = randomStyles();
for (const n of document.getElementsByClassName(t.getAttribute('id'))) {
update(n, styles);
}
}
});
const audio = new Audio();
const queue = [];
audio.onended = function() {
if (queue.length) {
audio.src = queue.shift();
audio.play();
}
};
function play(srcArray) {
queue.push(...srcArray);
if (audio.paused) {
audio.onended();
}
}
play([ '1.mp3', '2.mp3', '3.mp3' ]);
{ 'символ': 'на что его надо заменить' }
:const combine = (keys, values) =>
keys.reduce((acc, n, i) => (acc[n] = values[i], acc), {});
const enToRu = combine(trans[0], trans[1]);
const ruToEn = combine(trans[1], trans[0]);
const translate = (str, charset) => Array
.from(str, n => charset[n] || n)
.join('');
translate(';jgf', enToRu) // 'жопа'
translate('руддщб цщкдв!!', ruToEn) // 'hello, world!!'
Вешаю на него сеттер...
function test(m) {
let money = m;
Object.defineProperty(this, 'money', {
get() {
return money;
},
set(val) {
alert(`Значение свойства money меняется с ${money} на ${val}`);
money = val;
},
});
}
function test(m) {
this.money = m;
return new Proxy(this, {
set(target, prop, val) {
alert(`Значение свойства ${prop} меняется с ${target[prop]} на ${val}`);
target[prop] = val;
return true;
},
});
}
Есть ли причины так не делать?
@click="pushNumbars() reader.push(*)"
img
класс лучше переключать у article
- максимально дальних не общих предков картинок. Если вдруг захотите при кликах на кнопки стилизовать ещё что-то помимо картинок, или измените взаимное расположение элементов, то не придётся переписывать js-код. Стили, конечно, придётся немного поправить, вместо .active
будет .active img
.const container = document.querySelector('.container');
const itemSelector = 'article';
const buttonSelector = `${itemSelector} .btn`;
const activeClass = 'active';
container.addEventListener('click', e => {
const button = e.target.closest(buttonSelector);
if (button) {
button.closest(itemSelector).classList.toggle(activeClass);
}
});
container.querySelectorAll(buttonSelector).forEach(function(n) {
n.addEventListener('click', this);
}, e => e.currentTarget.closest(itemSelector).classList.toggle(activeClass));
:hover
и самой кнопке тоже:.btn:hover {
display: block;
}
<div id="container"></div>
.#container span {
display: inline-block;
white-space: pre;
font-size: 40px;
animation: span .2s ease-out;
}
@keyframes span {
from {
transform: translateX(500px);
opacity: 0;
}
to {
transform: translateX(0);
opacity: 1;
}
}
const forEachWithDelay = (arr, delay, callback) =>
(function next(i) {
if (i < arr.length) {
setTimeout(() => (callback(arr[i]), next(-~i)), delay);
}
})(0);
// или
async function forEachWithDelay(arr, delay, callback) {
for (let i = 0; i < arr.length; i++) {
await new Promise(r => setTimeout(r, delay));
callback(arr[i]);
}
}
forEachWithDelay(
'hello, world!!',
69,
n => document
.querySelector('#container')
.insertAdjacentHTML('beforeend', `<span>${n}</span>`)
);
// или
forEachWithDelay(
'fuck the world',
187,
function(n) {
this.appendChild(document.createElement('span'));
this.lastChild.textContent = n;
}.bind(document.getElementById('container'))
);