单击第一个按钮后,我试图显示两个新按钮。为此,我要将要显示的两个按钮设置为display: none
。单击初始按钮后,它将显示切换为无,然后将其他两个按钮显示为display: block
。
这可以工作,但是会出现奇怪的显示错误,即最初的按钮要大得多,然后迅速恢复到应该的大小。
我已附上图片以显示此内容,但由于我的声誉而无法嵌入。
HTML
<div class = "container">
<div class = "row p-0">
<div class = "col text-field-wrapper m-0 p-0"></div>
<div class = "col button-field-wrapper"></div>
</div>
</div>
CSS:
.button-field-wrapper {
font-size: 12px;
margin: 18px 0 0 0;
height: 36px;
display: block;
}
.hide {
display: none
}
.text-field-wrapper: {
height: 56px;
display: block;
}
JavaScript:
constructor() {
super();
this.active = false;
this.default = true;
this.maxWidth = 200;
this.error = false;
this.overflow = false;
this.getWidth();
this.inputText = "Enter A Title";
this.appendChild(template.content.cloneNode(true));
this.tf_wrapper = this.getElementsByClassName("text-field-wrapper")[0];
this.bt_wrapper = this.getElementsByClassName("button-field-wrapper")[0];
this.renderInputField.bind(this)(this.tf_wrapper);
this.renderButtonField.bind(this)(this.bt_wrapper);
this.renderOptionField.bind(this)(this.bt_wrapper);
this.optionWrapper.setAttribute("class", "hide", "option-wrapper")
}
renderOptionField(bt_wrapper) {
this.optionWrapper = document.createElement("DIV");
this.optionWrapper.setAttribute("class", "option-wrapper");
bt_wrapper.appendChild(this.optionWrapper);
this.cancelButton = document.createElement("Button");
this.cancelButton.setAttribute("class", "cancel-button");
this.cancelButton.addEventListener("click",
this.onCancel.bind(this))
this.closeIcon = document.createElement("object");
this.closeIcon.setAttribute("type", "image/svg+xml");
this.closeIcon.setAttribute("class", "close-icon");
this.closeIcon.setAttribute("data", "Close.svg")
this.cancelButton.appendChild(this.closeIcon)
this.cancelButton.innerHTML += "Cancel";
this.saveButton = document.createElement("Button");
this.saveButton.setAttribute("class", "save-button");
this.saveButton.addEventListener("click", this.onSave.bind(this))
this.saveIcon = document.createElement("object");
this.saveIcon.setAttribute("type", "image/svg+xml");
this.saveIcon.setAttribute("class", "save-icon");
this.saveIcon.setAttribute("data", "Check.svg")
this.saveButton.appendChild(this.saveIcon)
this.saveButton.innerHTML += "Save";
this.optionWrapper.appendChild(this.cancelButton);
this.optionWrapper.appendChild(this.saveButton);
}
onEdit() {
this.editWrapper.setAttribute("class", "edit-wrapper hide")
this.optionWrapper.setAttribute("class", "option-wrapper")
this.textField.setAttribute("class", "text-field-active single-
line")
this.active = true;
}
答案 0 :(得分:1)
这可以工作,但是会出现奇怪的显示错误,即最初的按钮要大得多,然后迅速恢复到应有的大小。
即使在将项目附加到容器时完全创建了项目,您的浏览器也需要重新计算流程以使元素适合内部。这样做时,您的商品最初可能没有设置正确的值,有时可能会导致奇怪的行为。
创建这样的元素并不是有效的方法。最好编写HTML并包含所有内容,包括要显示的元素和要隐藏的元素,并随时更改其属性。您将避免使用冗长且难以维护的javascript代码,同时获得更稳定的行为。
这里是一个小提琴,可以重现您要实现的目标:
// Script.js
// Load all the elements you need to operate on
const container = document.querySelector('#container');
const staticElements = container.querySelectorAll('.static');
const editElements = container.querySelectorAll('.edit');
const inputField = container.querySelector('input');
const title = container.querySelector('.title');
// Hide all static elements, and display the edit ones
function setEditMode() {
inputField.value = title.innerHTML;
for (const element of staticElements) {
element.classList.add('hidden');
}
for (const element of editElements) {
element.classList.remove('hidden');
}
}
// Reverse of above function
function setStaticMode() {
for (const element of staticElements) {
element.classList.remove('hidden');
}
for (const element of editElements) {
element.classList.add('hidden');
}
}
// Call above, but before update static value
function save() {
title.innerHTML = inputField.value;
setStaticMode();
}
/* style.css */
#container {
display: flex;
}
#container > * {
margin: 5px;
}
.editable {
font-size: 20px;
color: #AAAAAA;
}
.button {
border-style: solid;
border-color: lightblue;
border-width: 1px;
border-radius: 3px;
padding: 3px;
cursor: pointer;
}
.editActions {
display: flex;
}
.editActions > * {
margin: 0 5px;
}
.hidden {
display: none;
}
<!—-index.html—->
<div id="container">
<div class="title static">Enter a title</div>
<input type="text" class="hidden edit">
<div class="button static" onClick="setEditMode()">
edit
</div>
<div class="hidden editActions edit">
<div class="button" onClick="setStaticMode()">
cancel
</div>
<div class="button" onCLick="save()">
save
</div>
</div>
</div>
在这里,我们没有从javascript修改DOM,并且一切看起来都很清晰,表现出预期。
如果您必须使用javascript构建HTML,请小心谨慎,并尽可能做到偶尔。您可以从这里修改代码,以查看更改是否有效。
答案 1 :(得分:0)
这是建议您首先为静态页面(不包含JavaScript)构建Web应用程序,然后扩展该功能以合并JavaScript以实现动态的原因之一。
例如,如果您遵循上述建议,那么在通过JavaScript应用任何效果之前,浏览器的html解析器将首先计算所有DOM
容器的属性。如果您不这样做,那么这种不可预测的行为是可以预期的。
具体来说,从您的代码开始,在开始附加到或操作其元素之前,无需做任何工作来确保DOM
已准备就绪。请参阅此post,以了解如何使用原始JavaScript实现此目标。确保DOM
就绪后,您就可以使用JavaScript隐藏要动态显示的元素,并添加要用于使其可见的事件侦听器。