Случай столкновения с flex-wrap: перенос при увеличении ширины onHover - PullRequest
0 голосов
/ 11 февраля 2019

У меня есть забавная проблема, которая, возможно, кто-то уже имел, у меня есть список, использующий display: flex и flex-wrap: wrap.Это также работает нормально, моя проблема в том, что при наведении указателя li на правую сторону от li устанавливается значок видимого, поэтому ширина li увеличивается, а li перемещается ниже из-за недостатка места и флага переноса.Пока все хорошо, но я также скрываю иконку в onmouseleave, чтобы пространство снова уменьшалось, а li отскакивал назад, так что все это сходит с ума, если вы можете себе это представить.Приведенный ниже код воспроизводит проблему, по крайней мере, на моем мониторе и crhome, зависших в последний раз.

var ul = document.getElementById("fileList");
let listItem = document.createElement("li");
listItem.setAttribute('id', "li");
listItem.textContent = "Crazy jumping";
listItem.onmouseover = function (event) {  
  let removeIcon = document.getElementById("remove");
  removeIcon.setAttribute('class', 'removeIconVisible');
  event.preventDefault();
  return false;
};

listItem.onmouseleave = function () {
  let idTemp = listItem.getAttribute("id");
  let id = idTemp.slice(2, idTemp.length);
  let removeIcon = document.getElementById("remove" + id);
  removeIcon.setAttribute('class', 'removeIcon');
  return false; // Prevents propagation of the event to the parents.
};

let removeButton = document.createElement('img');
removeButton.setAttribute('id', "remove");
removeButton.setAttribute('src', "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAYAAADgdz34AAAARElEQVR42mNgGAVUAApAfB+I/6Ph+1A5ssB/MvHgsYAugOauH7Vg1IJRC0YtIAI8IsHwR+RY4AHEj4kw/DFU7SggDwAAyTHHV/YXjncAAAAASUVORK5CYII=");
removeButton.setAttribute('class', 'removeIcon');
listItem.appendChild(removeButton);
ul.appendChild(listItem);
<!DOCTYPE html>
<html>
<head>
<style>
ul {
  list-style-type: none;
  margin: 0;
  padding: 0;
  overflow: hidden;
  background-color: #333;
  display: flex;
            align-items: center;
            flex-wrap: wrap;
}

li {
   display: flex;
            font-family: sans-serif;
            background-color: gold;
            float: left;
            padding: 8px;
            margin-right: 8px;
            margin-bottom: 8px;
            border-radius: 10px;
            text-align: center;
            align-items: center;
}

li:hover {
  background-color: #FFFFFF;
}

.removeIcon {
    display: none;
    visibility: collapse;
}

.removeIconVisible {
    display: flex;
    visibility: visible;
}
        
</style>
</head>
<body>

<ul class="fileList" id="fileList">
  <li>
    <span class="text">Home</span>
  </li>
  <li>
    <span class="text">Home2</span>
  </li>
  <li>
    <span class="text">Home3</span>
  </li>
  <li>
    <span class="text">Home4</span>
  </li>
  <li>
    <span class="text">Home5</span>
  </li>
  <li>
    <span class="text">Home6Bigger</span>
  </li>
</ul>

</body>
</html>

1 Ответ

0 голосов
/ 11 февраля 2019

Для элемента просто не хватает места для изображения (без переноса).«Сумасшедшие прыжки» не такие уж сумасшедшие, если вы об этом думаете:

  1. вы зависаете и onmouseover запускается
  2. изображение добавляется и элемент списка переносится
  3. из-за нехватки места это вызывает событие onmouseleave (мышь больше не зависает)
  4. изображение удаляется, и элемент возвращается на место
  5. и снова и снова ...

Для предотвращения упаковки элементов удалите flex-wrap: wrap; из списка.Но это может означать, что элементы не помещаются в контейнер.

В качестве альтернативы вы всегда можете зарезервировать место для изображения.Это означает, что вы всегда визуализируете изображение, скрываете его по умолчанию и показываете его при наведении.В приведенном ниже примере для отображения / скрытия изображения используется курсор мыши:

let ul = document.getElementById("fileList");

// Create new list item
let listItem = document.createElement("li");
listItem.textContent = "Crazy jumping";

// Create remove icon
let removeIcon = document.createElement("img");
removeIcon.classList.add("removeIcon");
removeIcon.setAttribute("id", "remove");
removeIcon.setAttribute("src", "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAYAAADgdz34AAAARElEQVR42mNgGAVUAApAfB+I/6Ph+1A5ssB/MvHgsYAugOauH7Vg1IJRC0YtIAI8IsHwR+RY4AHEj4kw/DFU7SggDwAAyTHHV/YXjncAAAAASUVORK5CYII=");

// Append items
listItem.appendChild(removeIcon);
ul.appendChild(listItem);
ul {
  list-style-type: none;
  margin: 0;
  padding: 0;
  overflow: hidden;
  background-color: #333;
  display: flex;
  align-items: center;
  flex-wrap: wrap;
}

li {
  display: flex;
  font-family: sans-serif;
  background-color: gold;
  float: left;
  padding: 8px;
  margin-right: 8px;
  margin-bottom: 8px;
  border-radius: 10px;
  text-align: center;
  align-items: center;
}

li:hover {
  background-color: #FFFFFF;
}

li:hover .removeIcon {
  visibility: visible;
}

.removeIcon {
  visibility: hidden;
}
<ul class="fileList" id="fileList">
  <li>
    <span class="text">Home</span>
  </li>
  <li>
    <span class="text">Home2</span>
  </li>
  <li>
    <span class="text">Home3</span>
  </li>
  <li>
    <span class="text">Home4</span>
  </li>
  <li>
    <span class="text">Home5</span>
  </li>
  <li>
    <span class="text">Home6Bigger</span>
  </li>
</ul>

Редактировать:

Кажется нелогичным говорить "когда мышьесли элемент не переносится, просто переполнится "или что-то в этом роде.

Как я уже говорил, удалите flex-wrap: wrap из списка, чтобы предотвратить его перенос.Вы также можете предотвратить перенос текста, добавив white-space: nowrap (см. Пример ниже).

Разве невозможно установить свойство в onmouseover?Вопрос также будет в том, какое свойство?

Я рекомендую использовать CSS для стилей вместо JavaScript, где это возможно, например, для скрытия при наведении и т. Д. (Как пример выше). Но изКонечно, вы можете использовать события onmouseover и onmouseleave для переключения класса removeIconVisible:

let ul = document.getElementById("fileList");

// Create new list item
let listItem = document.createElement("li");
listItem.textContent = "Crazy jumping";

// Create remove icon
let removeIcon = document.createElement("img");
removeIcon.classList.add("removeIcon");
removeIcon.setAttribute("id", "remove");
removeIcon.setAttribute("src", "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAYAAADgdz34AAAARElEQVR42mNgGAVUAApAfB+I/6Ph+1A5ssB/MvHgsYAugOauH7Vg1IJRC0YtIAI8IsHwR+RY4AHEj4kw/DFU7SggDwAAyTHHV/YXjncAAAAASUVORK5CYII=");

listItem.onmouseover = function () {  
  removeIcon.classList.add("removeIconVisible");
};

listItem.onmouseleave = function () {
  removeIcon.classList.remove("removeIconVisible");
};

// Append items
listItem.appendChild(removeIcon);
ul.appendChild(listItem);
ul {
  list-style-type: none;
  margin: 0;
  padding: 0;
  overflow: hidden;
  background-color: #333;
  display: flex;
  align-items: center;
  /*flex-wrap: wrap;*/
  white-space: nowrap;
}

li {
  display: flex;
  font-family: sans-serif;
  background-color: gold;
  float: left;
  padding: 8px;
  margin-right: 8px;
  margin-bottom: 8px;
  border-radius: 10px;
  text-align: center;
  align-items: center;
}

li:hover {
  background-color: #FFFFFF;
}

.removeIcon {
  display: none;
  visibility: collapse;
}

.removeIconVisible {
  display: flex;
  visibility: visible;
}
<ul class="fileList" id="fileList">
  <li>
    <span class="text">Home</span>
  </li>
  <li>
    <span class="text">Home2</span>
  </li>
  <li>
    <span class="text">Home3</span>
  </li>
  <li>
    <span class="text">Home4</span>
  </li>
  <li>
    <span class="text">Home5</span>
  </li>
  <li>
    <span class="text">Home6Bigger</span>
  </li>
</ul>

Альтернатива

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

li {
  position: relative;
}

li:hover .removeIcon {
  background-color: white;
  position: absolute;
  right: 2px;
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...