Divs неправильное размещение после показа с интервалами (скрипка включена) - PullRequest
0 голосов
/ 10 апреля 2020

У меня проблемы с моим JavaScript кодом. Я реализую карточную игру, в которой я нажимаю кнопку, и 13 карт должны появляться с интервалами

$("button").click(function() {
	let i = 0;
	setInterval(function() {
  	if(i == 4) clearInterval();
  	$(".block").eq(i).css({visibility:"visible"});
  	$(".block").eq(i).html("TEXT" + i);
    i++;
  },100);
});
.block {
  display: inline-block;
  width: 100px;
  height: 140px;
  border: 2px solid;
  visibility: hidden;
}

button {
  position: absolute;
  top: 170px;
  left: 50px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<html>
  <body>
    <div class="block"></div>
    <div class="block"></div>
    <div class="block"></div>
    <div class="block"></div>
    <button id="button">Generate!</button>
  </body>
</html>

Как видно выше, я использую функцию setInterval(), чтобы отображать их с интервалами 100 мс, все делатели делают то, что я им говорю, но сначала они появляются совсем ниже, где я хочу, чтобы они были. Как сделать так, чтобы они появлялись в нужных местах напрямую?

Заранее спасибо!

Ответы [ 5 ]

1 голос
/ 11 апреля 2020

Установка блоков на display: none, а затем добавление display: inline-block - способ обойти проблему, но не решает саму проблему.

Основной проблемой является свойство vertical-align, установленное для класса block. По умолчанию установлено значение baseline. Перед нажатием на кнопку все ваши элементы делятся в ряд, невидимые, с базовой линией, установленной в нижней части элемента. Однако, когда кнопка нажата, ваши блоки не только становятся видимыми, но, что более важно, вы добавляете некоторый текст в div. Это изменяет базовую линию, делая вместо этого нижнюю часть текста внутри div. Однако из-за vertical-align: baseline базовые линии всех элементов в строке пытаются выровнять. Базовая линия видимых элементов div с текстом должна совпадать с базовой линией невидимых элементов div без текста. Но их базовые линии теперь другие, поэтому единственный способ, которым они все могут сидеть по прямой линии на своих базовых линиях, был бы, если бы элементы div с текстом были перемещены вниз.

Я упростил ваши фрагменты, чтобы показать вам, что я имею в виду. Я сделал div-элементы видимыми, удалил кнопку и вместо этого вручную добавил текст в ваши div-ы в html. Как вы можете видеть, для div с текстом нижняя часть текста совпадает с нижней частью div без текста.

body {
  background: white;
 }
 
.block {
  display: inline-block;
  width: 100px;
  height: 140px;
  border: 2px solid;
}
<html>
  <body>
    <div class="block">TEXT</div>
    <div class="block">TEXT</div>
    <div class="block"></div>
    <div class="block">TEXT</div>
  </body>
</html>

Причина, по которой сначала нужно изменить блоки на display: none, а затем отобразить их один за другим, заключается в том, что в этом случае никогда не бывает Точка, когда в DOM одновременно присутствуют безтекстовые div и div с текстом, поэтому никогда не происходит несоответствие базовых показателей. Дивы вводят DOM с текстом в них, поэтому их базовые показатели всегда совпадают. Однако это не совсем решает проблему. Например, если бы текст в элементах div был разной длины, нижняя часть многострочного текста совпала бы с нижней частью однострочного текста, что снова привело бы к смещению.

Пример:

body {
  background: white;
 } 

.block {
  display: inline-block;
  width: 100px;
  height: 140px;
  border: 2px solid;
}
<html>
  <body>
    <div class="block">text</div>
    <div class="block">text</div>
    <div class="block">very long text which takes up more than one line</div>
    <div class="block">text</div>
  </body>
</html>

Таким образом, правильным решением для этого будет добавление vertical-align: top к классу block, чтобы убедиться, что наше выравнивание не перепрыгивает через все место в ответ на изменение базовой линии.

1 голос
/ 10 апреля 2020

Добавьте vertical-align: top; к вашим встроенным элементам

$("button").click(function() {
	let i = 0;
	setInterval(function() {
  	if(i == 4) clearInterval();
  	$(".block").eq(i).css({visibility:"visible"});
  	$(".block").eq(i).html("TEXT" + i);
    i++;
  },100);
});
.block {
  display: inline-block;
  width: 100px;
  height: 140px;
  border: 2px solid;
  visibility: hidden;
  vertical-align: top;
}

button {
  position: absolute;
  top: 170px;
  left: 50px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<html>
  <body>
    <div class="block"></div>
    <div class="block"></div>
    <div class="block"></div>
    <div class="block"></div>
    <button id="button">Generate!</button>
  </body>
</html>
0 голосов
/ 10 апреля 2020

Вы можете поместить div обертки вокруг элементов .block.

<html>
  <body>
   <div class="container">
    <div class="block"></div>
    <div class="block"></div>
    <div class="block"></div>
    <div class="block"></div>
   </div>
    <button id="button">Generate!</button>
  </body>
</html>

А затем CSS:

.container {
  display: flex;
}
.block {
  /* display: inline-block; */
  width: 100px;
  height: 140px;
  border: 2px solid;
  visibility: hidden;

  margin-left: 15px;
}

Я добавил поля слева для всех элементов .block, но вы, конечно, можете установить их с помощью гибкого дисплея или как хочешь.

0 голосов
/ 10 апреля 2020

Вы можете установить элемент .block на display: none; вместо visibility: hidden; и изменить свой сценарий следующим образом:

 $("button").click(function() {
    let i = 0;
    setInterval(function() {
    if(i == 4) clearInterval();
    $(".block").eq(i).css({display:"inline-block"});
    $(".block").eq(i).html("TEXT" + i);
    i++;
  },100);
});

Fiddle

0 голосов
/ 10 апреля 2020

Вот рабочая скрипка .

Вы можете установить высоту на 0, а затем установить ее в функции интервала.

$("button").click(function() {
    let i = 0;
    setInterval(function() {
    if(i == 4) clearInterval();
    $(".block").eq(i).css({visibility:"visible", height: "140px"});
    $(".block").eq(i).html("TEXT" + i);
    i++;
  },100);
});

С этим css:

.block {
  display: inline-block;
  width: 100px;
  height: 0;
  border: 2px solid;
  visibility: hidden;
}

button {
  position: absolute;
  top: 170px;
  left: 50px;
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...