动态生成的details元素无法展开至完整尺寸问题求助
动态生成的details元素无法展开至完整尺寸问题求助
我正在做一个纯JavaScript生成的菜单,按照社区里大家的建议实现后遇到了个问题:动态生成的菜单没办法展开到完整尺寸,里面的文本内容完全显示不出来。实际显示效果是只看到一个小的summary按钮,展开后也看不到下方的选项文本;但预期应该是展开后能完整展示所有带文本的复选框选项,所有元素的属性和文本内容我都确认过是正确填充的。
我对比了两种实现,唯一的区别就是:出问题的版本是完全动态生成模板的,而能正常工作的版本是静态构建的模板。
完整代码实现
class GLMenuTemplate { #style_id = "webgl_menu_template_style"; #template_id = "webgl_menu_template"; #webgl_css = ` div.webgl_menu /*element.class*/ { position:absolute;z-index:10;border:1px solid black; } div.webgl_menu summary /*element.class elements*/ { background-color: #eee; width: 1.3em; height: 1.3em; border: solid black thin; border-radius: .3em; padding: 0; margin: 0; align-content: center; text-align: center; cursor: pointer; } div.webgl_menu summary::marker { content: "+"; } /*element.class elements*/ div.webgl_menu summary:hover { background-color:#ddd; } div.webgl_menu details[open] summary::marker { content: "x"; }`; constructor () { this.#styleInit(); this.#templateInit(); } get template () {return document.getElementById(this.#template_id);} #styleInit() { if (document.getElementById (this.#style_id)) return; let style = document.createElement("style"); style.setAttribute ("id", this.#style_id); style.textContent = this.#webgl_css; document.body.appendChild(style); } #templateInit() { if (document.getElementById (this.#template_id)) return; let div = this.#createDiv(); let tr = this.#createTr(); let template = this.#createTemplate (this.#template_id, [div, tr]); document.body.appendChild(template); } #createElement(elementName, children) { let element = document.createElement (elementName); if (children) for (let child of children) element.appendChild (child); return element; } #createTemplate(id, contents) { let template = document.createElement("template"); template.setAttribute ("id", id); document.body.appendChild(template); if (contents) for (let content of contents) template.content.appendChild(content); return template; } #createDiv() { //template for menu item <tr><td><label><input> let summary = document.createElement ("summary"); let table = document.createElement ("table"); //table.appendChild(tr); let details = this.#createElement ("details", [summary, table]); let div = this.#createElement ("div", [details]); div.setAttribute ("class", "webgl_menu"); return div; } #createTr () { let label = this.#createElement ("label"); let td = this.#createElement ("td", [label] ); let tr = this.#createElement ("tr", [td]); return tr; } } class GLMenu { #x = 0xffff; #y = 0xffff; #rowt = null; #items = null; #tpl = null; constructor (x, y, relativeElement) { let menuTemplate = new GLMenuTemplate(); this.#template = menuTemplate.template; [this.#x, this.#y] = [window.scrollX + x, window.scrollY + y]; if (relativeElement) { let r = relativeElement.getBoundingClientRect(); this.#x += r.left; this.#y += r.top; } let divt = {div: this.#template.content.querySelector("div")}; let dive = {div: document.importNode(divt.div, true)}; [dive.div.style.top, dive.div.style.left] = [this.#y, this.#x]; document.body.appendChild(dive.div); this.#rowt = {tr: this.#template.content.querySelector("tr")}; this.#items = dive.div.querySelector ("table"); } set #template(value) { this.#tpl = value; } get #template() { return this.#tpl; } attachEventListeners(element, listeners) { if (!listeners) return; if (typeof listeners === "function") { element.addEventListener ("click", listeners); return; } if (Array.isArray(listeners)) { for (let listener of listeners) element.addEventListener (listener.name, listener.callback); return; } element.addEventListener (listeners.name, listeners.callback); } addCheckbox (text, events) { let input = document.createElement ("input"); input.setAttribute ("type", "checkbox"); input.textContent = text; this.attachEventListeners (input, events); let rowe = {tr: document.importNode(this.#rowt.tr, true)}; let label = rowe.tr.querySelector("label"); label.appendChild (input); this.#items.appendChild (rowe.tr); return input; } } document.addEventListener('DOMContentLoaded', (event) => { let menu1 = new GLMenu(10, 10); menu1.addCheckbox ("write to console", [{name:"click", callback: (e) => { console.log (e.target.textContent + ": checked:" + e.target.checked); }}] ); menu1.addCheckbox ("don't write to console", (e) => { console.log (e.target.textContent + ": don't, checked:" + e.target.checked); } ); //Menu 2 let menu2 = new GLMenu(100, 100); menu2.addCheckbox ("write to console 2", {name:"click", callback: (e) => { console.log (e.target.textContent + ": 2 checked:" + e.target.checked); }} ); menu2.addCheckbox ("don't write to console 2", (e) => { console.log (e.target.textContent + ": don't 2, checked:" + e.target.checked); } ); });
我已经检查过:
- 样式表正确加载到页面中了
- 所有DOM元素都正确创建并挂载到了页面上
- 复选框的文本内容也正确设置了
但就是展开后菜单尺寸不对,看不到文本内容,有没有大佬能帮忙看看问题出在哪里呀?
内容来源于stack exchange
相关产品推荐
相关产品推荐

