如何创建带有描述字段的框



我目前在创建盒子内部的盒子的一些 CSS/JS 逻辑方面遇到了一个小问题。JsFiddle 示例 : https://jsfiddle.net/pa7wt2g3/

我想创建 1 个框,单击该框后,在其下创建一个描述字段。 但是,目前在制作其他框时,描述字段都在第一个框中显示。

我怀疑我必须给每个盒子一个 uniqe ID,稍后用于指定将描述区域放在哪里,但我该怎么做呢?

function textarea() { // Toggles dropdown and sets the dropdown and textfield as the same width as the created div
document.getElementById('dropdown').classList.toggle("show");
style = window.getComputedStyle(crtdiv);
wdt = style.getPropertyValue('width');
dropdown.style.width = wdt;
}
document.getElementById("läggatill").onclick = function () { // Run function when läggatill is clicked
var div = document.createElement('div'); // create div element
div.className = 'newrect'; // apply css
div.setAttribute("id", "crtdiv");
var button = document.createElement('button'); // create button element
button.setAttribute("id", "hej"); // Giving an id
var buttontext = document.createTextNode("X"); // Sets the button value
button.appendChild(buttontext); // Shows the value of the button
button.className = 'hej'; // apply css
button.setAttribute("onClick", "removeDiv(this)"); // runs the removeDiv funtion
var dropdown = document.createElement('dropdown'); // create dropdown element
dropdown.setAttribute("id", "dropdown"); // Giving an id
dropdown.className = 'dropdown'; //apply css
div.setAttribute("onClick","textarea()"); // Run textarea funtion
var ptext = document.createElement('p'); // create p element
var textnode = document.createTextNode("Add description"); // Sets the innerText of the p element
ptext.appendChild(textnode); // Shows the InnerText
ptext.className = 'text'; // apply css
ptext.setAttribute("id", "text"); // Giving an id

var textfield = document.createElement('Textarea'); // create textarea element
textfield.className = 'autoExpand'; // apply css
textfield.setAttribute("id", "textfield"); // Giving an id

var text = document.getElementById("myText").value; //take the value of the text field
div.innerHTML = text; // show text in the div
if (text === "") { // Shows every element if the textfield has text in it
return 0; // Returns nothing if the text field is empty
} else { 
document.getElementsByTagName('span')[0].appendChild(div).appendChild(button);
document.getElementsByTagName('span')[0].appendChild(dropdown); 
document.getElementsByClassName('dropdown')[0].appendChild(ptext);
document.getElementsByClassName('dropdown')[0].appendChild(textfield);
}
};
function removeDiv(elem) { // Removes div when pressing the button
$(elem).parent('div').remove();
}
/* Start of lägga till kompetens */

.newrect {
min-width: 55px;
max-width: 195px;
margin-top: 1%;
margin-right: 1%;
margin-left: 1%;
margin-bottom: 0%;
padding: 1% 3%;
border: 1px solid green;
border-radius: 40px;
text-align: center;
float: left;
position: relative;
background-color: white;
z-index: 2;
cursor: pointer;
}
.dropdown {
display: none; 
background-color: darkgrey;
height: 400px;
position: absolute !important;
margin-top: 3%;
margin-right: 0%;
margin-left: 0.96%;
margin-bottom: 0%;
z-index: 1;
}
.show { 
display: block; 
}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>

<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js"></script>
</head>
<body>
<input id="myText" type="text" class="skriv" name="Kompetenser" autocomplete="off" autofocus> <!-- Textfield for kompetenser -->
<input id="läggatill" class="läggatill" type="button" value="Add box"> <!-- Button lägga till -->
<span style="display:block;"></span>
</body>
</html>

您是对的 - 所有 ID 都必须是唯一的。为了实现这一点,你必须重构大部分代码。例如,textarea函数是通过单击添加的框触发的 - 这很好。问题是该函数不知道实际单击了哪个框 - 它指的是具有固定 ID "下拉列表"的元素。由于有多个元素具有相同的 ID,因此无法知道需要扩展哪个框。 您可以简单地将this作为参数传递给此函数并引用上下文,但随后您必须考虑使用全局变量的事实,dropbox函数范围之外声明。

我已经重写了整个事情。这就是我实现此功能的方式。我看到你在几行中使用jQuery,因此我的代码在很大程度上依赖于它。如果你不能在你的最终项目中使用jQuery,请告诉我,我将发布一个纯原版JS版本。我还必须进行一些微小的CSS更改(flexbox(。

小提琴:https://jsfiddle.net/zLm2x5k6/

片段:

$(document).ready(() => {
//You can use IDs here because these elements are unique
const $addBtn = $("#läggatill");
const $inputBox = $("#myText");
const $flexBox = $("#flexbox");
$addBtn.click(() => {
//Creating a new box that contains everything we need and saving it to a variable
//I'm using ES6 template strings to embed the value of $inputBox
const $box = $(`
<div class="box">
<div class="newrect">
${$inputBox.val()}
<button class="hej">X</button>
</div>
<div class="dropdown">
<p class="text" id="text">Add description</p>
<textarea class="autoExpand"></textarea>
</div>
</div>
`);
//Adding event listeneres for the box elements
$box.find(".hej").click(function () {
//Removing the parent .box wrapper DIV
$(this).closest(".box").remove();
});
$box.find(".newrect").click(() => {
const $dropdown = $box.find(".dropdown");
//If the dropdown is invisible, show it. Otherwise, hide it
if ($dropdown.css("display") === "none") {
$box.find(".dropdown").show();
} else {
$box.find(".dropdown").hide();
}
});
//Appending the box to the flexBox
$box.appendTo($flexBox);
});
});
html, body { /* So you can adjust height */
height: 100%;
margin: 0;
padding: 0;
}
/* Start of lägga till kompetens */

.newrect {
min-width: 105px;
max-width: 195px;
margin-top: 1%;
margin-right: 1%;
margin-left: 1%;
margin-bottom: 0%;
padding: 5px 10px 5px 10px;
border: 1px solid green;
border-radius: 40px;
text-align: center;
background-color: white;
z-index: 2;
cursor: pointer;
}
.flexbox{
display: flex;
flex-direction: row;
}
.skriv {
border-radius: 40px 40px 40px 40px;
outline: none;
padding: 0 2%;
width: 51%; 
margin: 2%;
}
.läggatill {
border: 1px solid black;
background-color: white;
border-radius: 5px 5px 5px 5px;
outline: none;
margin: 2% 5%;
width: 23%;
max-width: 200px;
float: right;
}
.dropdown {
display: none; 
background-color: darkgrey;
height: 400px;
margin-top: 3%;
margin-right: 0%;
margin-left: 0.96%;
margin-bottom: 0%;
z-index: 1;
width: 100px;
}
.dropdown textarea{
width: 100px;
}
.show { 
display: block; 
} 
.hej {
position: relative;
border: none;
background-color: white;
color: darkblue;
}
.autoExpand {
/* display: none;  */
/* position: absolute !important; */
margin-top: 10%;
margin-right: 0%;
margin-left: 0.96%;
margin-bottom: 0%;
z-index: 2;
display: block;
overflow: hidden;
padding: 10px;
font-size: 14px;
border-radius: 6px;
border: 0;
resize: none;
}
.text {
text-align: center;
margin-top: 30%;
cursor: default;
}
/* End of lägga till kompetens */
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
<link rel="stylesheet" href="css/Profil.css"> <!-- Länk till CSS -->
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css"> <!-- Bootstrap -->
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.4.0/js/bootstrap.min.js"></script>
</head>
<body>
<input id="myText" type="text" class="skriv" name="Kompetenser" autocomplete="off" autofocus> <!-- Textfield for kompetenser -->
<input id="läggatill" class="läggatill" type="button" value="Add box"> <!-- Button lägga till -->
<div class="flexbox" id="flexbox"></div> <!-- Container for the boxes -->
<span style="display:block;">

</span>

</body>
</html>

那里! 我也研究过一个解决方案,我想分享它。 这与Kasperczyk@Tomasz回答的非常相似,我使用jQuery重写了您的代码,并在CSS中添加了一些flexbox功能(加上我重命名的一些类,这样我就不会混淆自己(。 它现在更加简化和工作。我希望你很容易理解。

function addTagBox(text) {
var $tagBox = $($('#tagBoxTemplate').html());
$tagBox.find('.tagBox-label').text(text);
$('#tagsContainer').append($tagBox);
}
$('#addTagBoxButton').click(function(e) {
e.preventDefault();
var tagName = $('#myText').val();
if (tagName.length) {
addTagBox(tagName);
}
})
//listeners for the dynamic elemtens
$('#tagsContainer').on('click', '.tagBox', function(evt) {
$('.tagBox-dropdown').removeClass('dropdown--isVisible');
$(this).find('.tagBox-dropdown').toggleClass('dropdown--isVisible');
})
$('#tagsContainer').on('click', '.tagBox-destroy', function(evt) {
$(this).parent().remove();
})
html,
body {
/* So you can adjust height */
height: 100%;
margin: 0;
padding: 0;
}
#tagsContainer {
display: flex;
flex-direction: row;
flex-wrap: wrap;
align-items: center;
justify-content: flex-start;
}
.tagBox {
min-width: 55px;
max-width: 195px;
margin: 0 1rem 2rem 0;
padding: .5rem 1rem;
text-align: center;
border: 1px solid green;
border-radius: 40px;
position: relative;
cursor: pointer;
}
#myText {
border-radius: 40px;
outline: none;
padding: 0 2%;
width: 51%;
margin: 2%;
}
.addTagBoxButton {
border: 1px solid black;
background-color: white;
border-radius: 5px 5px 5px 5px;
outline: none;
margin: 2% 5%;
width: 23%;
max-width: 200px;
float: right;
}
.tagBox-dropdown {
display: none;
padding: 1rem;
background-color: darkgrey;
position: absolute;
top: calc(100% + 5px);
left: 0;
z-index: 1;
}
.dropdown--isVisible {
display: block;
}
.tagBox-destroy {
position: relative;
border: none;
background-color: white;
color: darkblue;
}
.tagBox-dropdown-textarea {
margin-top: 10%;
margin-right: 0%;
margin-left: 0.96%;
margin-bottom: 0%;
z-index: 2;
display: block;
overflow: hidden;
padding: 10px;
font-size: 14px;
border-radius: 6px;
border: 0;
resize: none;
}
.text {
text-align: center;
margin-top: 30%;
cursor: default;
}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
</head>
<body>
<input id="myText" type="text" name="Kompetenser" autocomplete="off" autofocus>
<input id="addTagBoxButton" class="addTagBoxButton" type="button" value="Add box">
<div id="tagsContainer"></div>
<script src="./script.js"></script>
<template id="tagBoxTemplate">
	<div class="tagBox">
		<span class="tagBox-label"></span>
		<button class="tagBox-destroy">X</button>
		<div class="tagBox-dropdown">
			<textarea name="description" class="tagBox-dropdown-textarea" placeholder="Type some description here"></textarea>
		</div>
	</div>
</template>
</body>
</html>

PS:对于标签框,我选择将其基础结构包装在模板元素中,这样它就不会用 HTML 弄乱我们的 JS 代码(尽管这是非常主观的(。我将JS链接到外部文件。

最新更新