#javascript #html #css
#javascript #HTML #css
Вопрос:
function myclick() {
let node = document.createElement("div");
node.className = "popover";
node.innerText = "hello world hello world";
event.srcElement.appendChild(node);
}
.container {
width: 230px;
height: 200px;
border: 1px solid #ddd;
display: flex;
flex-flow: wrap;
}
.tag {
border: 1px solid #ddd;
padding: 5px;
margin: 5px;
display: flex;
height: 20px;
position: relative;
}
.popover {
position: absolute;
top: 30px;
width: 60px;
left: 0px;
background-color: #dfdfdf;
}
<div class="container">
<div class="tag" onclick="myclick();">apple</div>
<div class="tag" onclick="myclick();">banana</div>
<div class="tag" onclick="myclick();">carrot</div>
<div class="tag" onclick="myclick();">dog</div>
<div class="tag" onclick="myclick();">elephant</div>
<div class="tag" onclick="myclick();">firetruck</div>
</div>
Я разработал полное воспроизведение проблемы, с которой я столкнулся выше. В принципе, у меня всплывающие окна появляются из тегов, когда вы нажимаете на них. Все это работает отлично, за исключением случаев, когда тег находится рядом с краем его контейнера. В этом случае тег вырезается из контейнера. В приведенном примере, если вы нажмете «dog», всплывающее окно будет вырезано за пределами container
div.
Скорее, я хотел бы, чтобы всплывающее окно перемещалось влево настолько, насколько это необходимо, чтобы предотвратить само отсечение контейнера. Я некоторое время возился с этим, но я не могу понять, как это сделать.
Комментарии:
1. Я бы создал класс css для popper (что-то вроде
.popper.right
), который устанавливаетleft: auto; right: 0
, а затем добавил этот класс в вашуmyClick
функцию для элементов на краю. Но это сложная часть, вам нужно будет динамически определять, что находится на краю, на основе ширины контейнера и ширины каждого дочернего элемента.2. Невозможно сделать это только с помощью CSS, но вам понадобится JS: вы могли бы получить ширину всех
.tag
элементов и (для каждого элемента) вычислить сумму ширин всех предыдущих элементов плюс их поля, и если текущий.tag
элемент имеет ширину менее 60 пикселей (т. Е. Ширину ваших выпадающих списков), вы могли бы выровнять этот выпадающий список по.tag
элементу. Но начиная со второй строки, это становится более сложным, поскольку вам придется перезапустить вычисление общей ширины элементов в каждой строке…
Ответ №1:
Вы можете попробовать это. Я добавил вызываемую функцию javascript onEdge
, которая, предположительно, определяет, насколько близко дочерний элемент находится к краю. Это, вероятно, потребуется изменить для ваших нужд (например, установить, насколько близко к родительскому краю вы считаете «слишком близко»).
function onEdge(child) {
if (child.parentElement.offsetWidth < (child.offsetLeft child.offsetWidth))
return true;
return false;
}
function myclick(elm) {
var addClass = onEdge(elm);
let node = document.createElement("div");
node.className = "popover" (addClass ? " right" : "");
node.innerText = "hello world hello world";
event.srcElement.appendChild(node);
}
.container {
width: 230px;
height: 200px;
border: 1px solid #ddd;
display: flex;
flex-flow: wrap;
}
.tag {
border: 1px solid #ddd;
padding: 5px;
margin: 5px;
display: flex;
height: 20px;
position: relative;
}
.popover {
position: absolute;
top: 30px;
width: 60px;
left: 0px;
background-color: #dfdfdf;
}
.popover.right {
left: auto;
right: 0;
}
<div id="tag-container" class="container">
<div class="tag" onclick="myclick(this);">apple</div>
<div class="tag" onclick="myclick(this);">banana</div>
<div class="tag" onclick="myclick(this);">carrot</div>
<div class="tag" onclick="myclick(this);">dog</div>
<div class="tag" onclick="myclick(this);">elephant</div>
<div class="tag" onclick="myclick(this);">firetruck</div>
</div>
Комментарии:
1. О, это очень приятно, мне особенно нравится
popover.right
трюк. Пробуем сейчас.2. К сожалению, у меня возникают трудности с получением,
offsetLeft
поскольку элементы в моем коде должны бытьposition: relative
, поэтому он просто выдает мне7
все значения offsetLefts.. Хм..3. хм, интересно. В приведенном выше фрагменте это, кажется, работает. Должен ли ваш контейнер также быть
position: relaitive
?tag
Уже есть4. Я знаю, что есть проблемы с левым и правым полями, потому что это не будет включено в
offsetWidth
значение дочерних элементов, но повлияет на егоoffsetLeft
значение. Но если ваши поля статичны, вы должны быть в состоянии понять это (возможно, придется добавить значения полей к дочерней ширине в функции onEdge для большей точности)
Ответ №2:
ОТРЕДАКТИРОВАНО: Вы можете вычислить правильную точку тега и проверить, достаточно ли места во всплывающем окне. Добавьте параметр в myclick
и передайте элемент.
var popUpWidth = 60;
var containerWidth = 200;
function myclick(element) {
let node = document.createElement("div");
if(element.offsetLeft popUpWidth > containerWidth){
node.style.left = -20 "px";
}
node.className = "popover";
node.innerText = "hello world hello world";
event.srcElement.appendChild(node);
}
Снипет:
var popUpWidth = 60;
var containerWidth = 200;
function myclick(element) {
let node = document.createElement("div");
if(element.offsetLeft popUpWidth > containerWidth){
node.style.left = -20 "px";
}
node.className = "popover";
node.innerText = "hello world hello world";
event.srcElement.appendChild(node);
}
.container {
width: 230px;
height: 200px;
border: 1px solid #ddd;
display: flex;
flex-flow: wrap;
}
.tag {
border: 1px solid #ddd;
padding: 5px;
margin: 5px;
display: flex;
height: 20px;
position: relative;
}
.popover {
position: absolute;
top: 30px;
width: 60px;
left: 0px;
background-color: #dfdfdf;
}
<div class="container">
<div class="tag" onclick="myclick(this);">apple</div>
<div class="tag" onclick="myclick(this);">banana</div>
<div class="tag" onclick="myclick(this);">carrot</div>
<div class="tag" onclick="myclick(this);">dog</div>
<div class="tag" onclick="myclick(this);">elephant</div>
<div class="tag" onclick="myclick(this);">firetruck</div>
</div>
Комментарии:
1. К сожалению, это также приводит к перемещению других всплывающих окон влево, что нежелательно. Только когда всплывающее окно вырезается из своего контейнера, оно должно перемещаться влево (и только настолько, насколько это необходимо для предотвращения отсечения)
2. да, это похоже на установку right: 0; вместо left: 0;
3. Итак, вы хотите
myclick
быть общей функцией для каждого тега, а не только dog?4. Вы можете рассчитать, достаточно ли места для всплывающего окна. Я внес некоторые изменения.
5. К сожалению, что-то подобное нужно сделать. Ну что ж, если другого ответа не придет, я приму этот, спасибо.
Ответ №3:
Просто слегка уменьшите левую позицию:
.popover {
position: absolute;
top: 30px;
width: 60px;
left: -19px;
background-color: #dfdfdf;
}
Комментарии:
1. Верно, я полагаю, что это сработало бы в этом случае, но я ищу более общее решение. Всплывающие окна в моем приложении намного шире и должны поддерживать свой размер.
2. Извините, это действительно должно быть динамическим, а не жестко запрограммированным.