Всем привет! Написал тут решение данной задачи, но мне кажется что это какой-то костыль. Если есть идеи, накидайте, пожалуйста. Дайте аргументы если где-то что-то коряво и или даже если нормально :). Вот сама задача и мое решение:
Дан абзац. Даны чекбоксы 'перечеркнуть', 'сделать жирным', 'сделать красным'. Если соответствующий чекбокс отмечен - заданное действие происходит с абзацем (становится красным, например). Если чекбоксу снять отметку - действие отменяется.
let p = document.querySelector('p');
let checkbox = document.querySelectorAll('input');
for (let i = 0; i < checkbox.length; i++) {
if (i === 0) {
checkbox[i].addEventListener('click', changeTextDecoration);
}
if (i === 1) {
checkbox[i].addEventListener('click', changeFontWeight);
}
if (i === 2) {
checkbox[i].addEventListener('click', changeColor);
}
}
function changeTextDecoration() {
if (this.checked) {
p.style.textDecoration = 'line-through';
} else {
p.style.textDecoration = 'none';
}
}
function changeFontWeight() {
if (this.checked) {
p.style.fontWeight = 'bold';
} else {
p.style.fontWeight = 'normal';
}
}
function changeColor() {
if (this.checked) {
p.style.color = 'red';
} else {
p.style.color = 'black';
}
}
<p> Paragraph </p>
<input type="checkbox"> Перечеркнуть
<input type="checkbox"> Сделать полужирным
<input type="checkbox"> Сделать красным
Как-нибудь так, например.
let p = document.querySelector('p');
let checkbox = document.querySelectorAll('input');
for ( let i = 0; i < checkbox.length; i++ ){
checkbox[i].addEventListener('click', cbClick);
}
function cbClick(){
const cfg = {
strike: { p: 'textDecoration', v: 'line-through', d: 'none' },
bold: { p: 'fontWeight', v: 'bold', d: 'normal'},
red: { p: 'color', v: 'red', d: 'black'}
};
const x = cfg[this.dataset.type];
p.style[x.p] = this.checked ? x.v : x.d;
};
<p> Paragraph </p>
<input type="checkbox" data-type="strike"> Перечеркнуть
<input type="checkbox" data-type="bold"> Сделать полужирным
<input type="checkbox" data-type="red"> Сделать красным
let p = document.querySelector('p');
let checkbox = document.querySelectorAll('input');
checkbox[0].addEventListener('click', changeTextDecoration);
checkbox[1].addEventListener('click', changeFontWeight);
checkbox[2].addEventListener('click', changeColor);
function changeTextDecoration() {
p.style.textDecoration = this.checked ? 'line-through' : 'none';
}
function changeFontWeight() {
p.style.fontWeight = this.checked ? 'bold' : 'normal';
}
function changeColor() {
p.style.color = this.checked ? 'red' : 'black';
}
<p> Paragraph </p>
<input type="checkbox"> Перечеркнуть
<input type="checkbox"> Сделать полужирным
<input type="checkbox"> Сделать красным
P.S.Пока писал увидел сообщение от Андрей NOP, это сообщение является его реализацией
или так, например
const p = document.querySelector('p'),
checkbox = document.querySelectorAll('input'),
changeTextDecoration = e => p.style.textDecoration = e.target.checked ? 'line-through' : 'none',
changeFontWeight = e => p.style.fontWeight = e.target.checked ? 'bold' : 'normal',
changeColor = e => p.style.color = e.target.checked ? 'red' : 'black'
checkbox[0].addEventListener('click', changeTextDecoration)
checkbox[1].addEventListener('click', changeFontWeight)
checkbox[2].addEventListener('click', changeColor)
<p>AHAHAHA</p>
<input type="checkbox" />
<input type="checkbox" />
<input type="checkbox" />
Это ваш базовый вариант
let p = document.querySelector('p');
let checkbox = document.querySelectorAll('input');
const listeners = [
changeTextDecoration,
changeFontWeight,
changeColor
];
for (let i = 0; i < checkbox.length; i++) {
checkbox[i].addEventListener('click', listeners[i]);
}
function changeTextDecoration() {
p.style.textDecoration = (this.checked) ? 'line-through' : 'none';
}
function changeFontWeight() {
p.style.fontWeight = (this.checked) ? 'bold' : 'normal';
}
function changeColor() {
p.style.color = (this.checked) ? 'red' : 'black';
}
<p> Paragraph </p>
<input type="checkbox"> Перечеркнуть
<input type="checkbox"> Сделать полужирным
<input type="checkbox"> Сделать красным
Но идея тупо перебирать в цикле элементы и назначать по порядку обработчики опасна. В середине добавится еще один инпут и все пропало.
Лучше их как-то проидентифицировать
let p = document.querySelector('p');
let checkbox = document.querySelectorAll('input');
const listeners = {
decor: changeTextDecoration,
weight: changeFontWeight,
color: changeColor
};
for (let i = 0; i < checkbox.length; i++) {
const input = checkbox[i];
input.addEventListener('click', listeners[input.getAttribute('data-id')]);
}
function changeTextDecoration() {
p.style.textDecoration = (this.checked) ? 'line-through' : 'none';
}
function changeFontWeight() {
p.style.fontWeight = (this.checked) ? 'bold' : 'normal';
}
function changeColor() {
p.style.color = (this.checked) ? 'red' : 'black';
}
<p> Paragraph </p>
<input type="checkbox" data-id="decor"> Перечеркнуть
<input type="checkbox" data-id="weight"> Сделать полужирным
<input type="checkbox" data-id="color"> Сделать красным
Или, учитывая тот факт, что каждый чекбокс включает или выключает какой-то элемент стиля, то можно обойтись одним обработчиком
let p = document.querySelector('p');
let checkbox = document.querySelectorAll('input');
for (let i = 0; i < checkbox.length; i++) {
const input = checkbox[i];
input.addEventListener('click', change);
}
function change() {
const attr = (this.checked) ? 'data-checked' : 'data-unchecked';
p.style[this.getAttribute('data-style')] = this.getAttribute(attr)
}
<p> Paragraph </p>
<input type="checkbox" data-style="textDecoration" data-checked="line-through" data-unchecked="none"> Перечеркнуть
<input type="checkbox" data-style="fontWeight" data-checked="bold" data-unchecked="normal"> Сделать полужирным
<input type="checkbox" data-style="color" data-checked="red" data-unchecked="black"> Сделать красным
Или вынести изменения в отдельные CSS классы и управлять самими классами
let p = document.querySelector('p');
let checkbox = document.querySelectorAll('input');
for (let i = 0; i < checkbox.length; i++) {
const input = checkbox[i];
input.addEventListener('click', change);
}
function change() {
const className = this.getAttribute('data-class');
if (this.checked)
p.classList.add(className);
else
p.classList.remove(className);
}
.decor {
text-decoration: line-through;
}
.weight {
font-weight: bold;
}
.color {
color: red;
}
<p> Paragraph </p>
<input type="checkbox" data-class="decor"> Перечеркнуть
<input type="checkbox" data-class="weight"> Сделать полужирным
<input type="checkbox" data-class="color"> Сделать красным
custom elements
custom elements
расширение базовых html
элементов, например:
class XDiv extends HTMLElement {}
customElements.define('x-div', XDiv)
ShadowRoot
грубо говоря - упрощённая версия iframe
, например: можно не париться с id
// @ts-check
class XDiv extends HTMLElement {
connectedCallback() {
/** @type {ShadowRoot} */
let shadowRoot;
try { shadowRoot = this.attachShadow({ mode: 'closed' }) } catch (e) { return; }
shadowRoot.appendChild(document.createRange().createContextualFragment(`
<slot></slot>
<p id="p">Paragraph</p>
`))
shadowRoot.addEventListener('change', e => {
const { dataset, checked } = e.target;
if (!dataset.class) return;
const p = shadowRoot.getElementById('p')
if (checked) p.classList.add(dataset.class)
else p.classList.remove(dataset.class)
})
Array.from(this.getElementsByTagName('style'), el => {
shadowRoot.appendChild(el)
})
}
}
customElements.define('x-div', XDiv)
<x-div>
<style>
.strike {
text-decoration: line-through;
}
.bold {
font-weight: bold;
}
.red {
color: red;
}
</style>
<label><input type="checkbox" data-class="strike" />Перечеркнуть</label>
<label><input type="checkbox" data-class="bold" />Сделать полужирным</label>
<label><input type="checkbox" data-class="red" />Сделать красным</label>
</x-div>
<p id="p"> Paragraph </p>
<input type="checkbox" s="text-decoration=line-through"> Перечеркнуть
<input type="checkbox" s="font-weight=bold"> Сделать полужирным
<input type="checkbox" s="color=red"> Сделать красным
<script>
Array.prototype.forEach.call(
document.querySelectorAll('input'),
(i) => i.addEventListener('change', (e) => {
let s = e.currentTarget.getAttribute('s').split('=')
p.style[s[0]] = e.currentTarget.checked ? s[1] : ''
})
)
</script>
Айфон мало держит заряд, разбираемся с проблемой вместе с AppLab
У меня есть файл с авторизацией пользователя, при логине я получаю токен в localStorageС этим все в порядке
Есть функция, которая записывает полученные с формы html документа значения в переменные а и b, в ней на 47й строке консоль выдает ошибку "Uncaught...
Решил отказаться от Ajax и все взаимодействие с сервером провожу через вебсокеты