簡體   English   中英

在 div 上切換“顯示:無”和“顯示:塊”時呈現錯誤

[英]Rendering bug while toggling "display: none" and "display: block" on div

單擊第一個按鈕后,我試圖顯示兩個新按鈕。 為此,我將要顯示的兩個按鈕設置為display: none 單擊初始按鈕時,它會將其顯示切換為無,然后將其他兩個按鈕display: blockdisplay: block

這是有效的,但一個奇怪的顯示錯誤發生在最初按鈕比它們應該大得多的地方,然后迅速恢復到它們應該的大小。

我附上了圖片來展示這一點,但由於我的聲譽而無法嵌入。

截圖 1 在此處輸入圖片說明

截圖 2 在此處輸入圖片說明

截圖 3 在此處輸入圖片說明

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;
}

這是有效的,但一個奇怪的顯示錯誤發生在最初按鈕比它們應該大得多的地方,然后迅速恢復到它們應該的大小。

即使您的項目在您將它們附加到您的容器時已完全創建,您的瀏覽器仍需要重新計算您的流程,以使元素適合其中。 執行此操作時,您的項目最初可能沒有設置正確的值,這有時會導致奇怪的行為。

創建這樣的元素並不是一種有效的方法。 你最好用里面的所有東西來編寫你的 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,請小心執行,並盡可能不定期地執行。 您可以從這里開始並調整您的代碼,以查看更改是否有效。

這是建議首先為靜態頁面(沒有 JavaScript)構建 Web 應用程序,然后擴展功能以合並 JavaScript 以實現動態的原因之一。

例如,如果您遵循上述建議,那么在您通過 JavaScript 應用任何效果之前,瀏覽器的 html 解析器將首先計算所有DOM容器的屬性。 如果你不這樣做,那么這種不可預測的行為是預料之中的。

具體來說,從您的代碼來看,在您開始附加或操作其元素之前,無需努力確保DOM已准備就緒。 請參閱有關如何使用 vanilla JavaScript 實現此目的的帖子 一旦確定DOM已准備就緒,就可以使用 JavaScript 隱藏要動態顯示的元素,並添加要使用的事件偵聽器以使它們可見。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM