Почему установка свойства display элемента для flex в CSS меняет поведение события onclick JS с помощью 'event.target'? - PullRequest
7 голосов
/ 12 марта 2020

У меня есть список основных c, со структурой HTML, подобной этой:

<ul class="list">
{...}
  <li class="item">Ellipse</li>
{...}

Затем я использую некоторые JS, чтобы добавить button s для удаления элементов, поэтому конечная структура выглядит следующим образом:

<ul class="list">
{...}
  <li class="item">Ellipse <button>Delete item</button></li>
{...}

У меня также есть функция, позволяющая пролистывать элементы списка по клику путем переключения класса CSS:

let ul = document.querySelector('.list');
{...}

function markAsDone (event) {  
  let target = event.target;
  target.classList.toggle('done');
}
{...}

ul.addEventListener('click', markAsDone);

. Это работает, как и ожидалось. (например, элемент списка вычеркнут). Однако, если я изменю свойство отображения элементов списка на flex в CSS:

.item {
  display: flex;
  justify-content: space-between;
  max-width: 300px ;
}

И затем щелкну по элементу, текст кнопки также будет зачеркнут, в отличие от ранее! С тех пор как я начал писать это, я больше не знаю, какое поведение кажется мне более «неправильным», смеется.

Полный код приведен на Codepen здесь . Попробуйте щелкнуть элементы в списке, а затем раскомментируйте стиль CSS для .item, чтобы понять, что я имею в виду.

Мое необразованное предположение состоит в том, что ответом на это будет то, как гибкие контейнеры обрабатывают предметы в них. Однако мое понимание этого очень ограничено, поэтому я пришел к вам за ответом.

Ответы [ 2 ]

4 голосов
/ 12 марта 2020

Просто оберните текст с span, чтобы решить вашу проблему. проверьте ниже фрагмент.

я не уверен, но вы применяете done класс к parent element, который пробивает оба элемента.

let button = document.querySelector('.smash');
let input = document.querySelector('.userinput');
let ul = document.querySelector('.list');
let listItems = document.querySelectorAll('.list > li');

function inputLengthValue() {
  let result = input.value.length;
  return result;
}

function createListElem() {
  let li = document.createElement('li');
  li.appendChild(document.createTextNode(input.value));
  li.classList.add('item');
  ul.appendChild(li);
  input.value = "";

  let delButton = document.createElement('button');
  delButton.appendChild(document.createTextNode('Delete item'));
  li.appendChild(delButton);
  delButton.addEventListener('click', removeItem)
}

function addListItemOnclick() {
  if (inputLengthValue() != 0) {
    createListElem();
  }
}

function addListItemOnEnterPress(event) {
  if (inputLengthValue() != 0 && event.keyCode === 13) {
    createListElem();
  }
}

function createDeleteButtons() {
  for (let i = 0; i < listItems.length; i++) {
    let delButton = document.createElement('button');
    delButton.appendChild(document.createTextNode('Delete item'));
    listItems[i].appendChild(delButton);
    delButton.addEventListener('click', removeItem);
  }
}

function markAsDone(event) {
  let target = event.target;
  target.classList.toggle('done');
}

function removeItem(event) {
  let target = event.target;
  target.parentNode.remove();
}


button.addEventListener('click', addListItemOnclick);
input.addEventListener('keydown', addListItemOnEnterPress);
ul.addEventListener('click', markAsDone);
createDeleteButtons(); // create delete btn for default items
.done {
  text-decoration: line-through;
}

.item {
  display: flex;
  justify-content: space-between;
  max-width: 300px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<h1 class="title">Some list</h1>
<input type="text" placeholder="enter your text" class="userinput">
<button class="smash">Add item</button>
<ul class="list">
  <li class="item"><span>Romboid</span></li>
  <li class="item"><span>Square</span></li>
  <li class="item"><span>Circle</span></li>
  <li class="item"><span>Ellipse</span></li>
  <li class="item"><span>Rectangle</span></li>
  <li class="item"><span>Oval</span></li>
</ul>
1 голос
/ 12 марта 2020

Чтобы ответить на вопрос «ПОЧЕМУ», давайте взглянем на спецификацию .

Свойство text-художественное оформление на дочерних элементах не может влиять на художественное оформление предка.

Ваш код в порядке. Такое поведение согласуется с spe c, text-decoration, затрагивающим всех детей (с некоторыми исключениями) . Есть только одна вещь, которую вы можете сделать: просто попытайтесь избежать text-decoration на родительском элементе, если вы не хотите, чтобы этот text-decoration был применен к дочерним элементам.

Обратите внимание, что текстовые декорации не распространяются на плавающих и абсолютно позиционированных потомков, а также на содержимое дочерних элементов atomi c, таких как встроенные блоки и встроенные таблицы.

Кнопки по умолчанию display: inline-block;, поэтому они выглядят нормально, если родительский контейнер не контролирует их, например, flex или grid.

Вот пример:

.item {
  font-size: 20px;
  padding: 10px;
  border: 1px solid green;

  text-decoration: line-through;
  text-decoration-color: red;
}

.item-flex { display: flex; }
.item-inline-flex { display: inline-flex; }

.item-grid { display: grid; }
.item-inline-grid { display: inline-grid; }

.item-table { display: table; }
.item-inline-table { display: inline-table; }

.item-inline { display: inline; }
.item-inline-block { display: inline-block; }

.item span, .item button {
  margin-left: 10px;
  text-decoration: overline underline;
  text-decoration-color: blue;
}
<div class="item">
  display:
  <span>block</span>
  <button>button</button>
</div>

<div class="item item-flex">
  display:
  <span>flex</span>
  <button>button</button>
</div>

<div class="item item-grid">
  display: <span>grid</span>
  <button>button</button>
</div>

<div class="item item-table">
  display:
  <span>table</span>
  <button>button</button>
</div>

<div class="item item-inline">
  display:
  <span>inline</span>
  <button>button</button>
</div>

<div class="item item-inline-block">
  display:
  <span>inline-block</span>
  <button>button</button>
</div>

<div class="item item-inline-flex">
  display:
  <span>inline-flex</span>
  <button>button</button>
</div>

<div class="item item-inline-grid">
  display:
  <span>inline-grid</span>
  <button>button</button>
</div>

<div class="item item-inline-table">
  display:
  <span>inline-table</span>
  <button>button</button>
</div>
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...