首页 > 解决方案 > 单击时动态更改页面内容

问题描述

我在使用 Pug 模板和 express 框架应用程序时遇到问题。我目前有一个在我的index.js文件中检索到的 JSON 文档列表。messageList我在渲染模板时发送这个。我要使用的 UI 类似于常规的电子邮件 GUI,主题出现在 LHS 上,单击时会在页面中心打开消息/电子邮件。

图形用户界面示例

每个 JSON 都有一个主题消息字段作为字符串。我目前正在迭代/循环每个entryinmessageList并将每个主题作为内部文本显示到button. 我的思考过程是我想用来onclick()发送条目message以显示在我的readMessagediv 中。

这是代码

索引.js

app.get("/dashboard", (req, res) => {
  Message.find( {}, function(err, data){ //data is my json doc list
     if(err)  
      return console.error(err);
     res.render("dashboard.pug", {messageList: data})
   })
});

仪表板.pug

    .messages   
         each entry in messageList
          button.clickableMessage(onclick = '') /*where I want to send the msg data to be displayed below in p.messageText*/
            .unreadIndicator
            p.innerText #{entry.subject}
        span
        .readMessage
          p.messageText
            | Feedback:
            | Hi Bruce, I am in your class and I wanted to let you know that I really like
            | such and such about it. Thanks for such and such. I only wish you would do more
            | X, Y, and Z in class. Have a good one

到目前为止,我已经尝试script在 pug 文件中使用来进行 DOM 操作,以及多次渲染页面,但问题归结为在嵌套的文本中onclick()显示值p.message.readMessage.

这是我的脚本尝试。我意识到 appendChild 很可能不是我想要的。

  script. 
   msg = function putMsg(message){
    const div = document.createElement("div");
    div.classList.add("readMessage");
    div.innerHTML = `<p class = "messageText"> ${message} </p>`;
    document.querySelector(".readMessage").appendChild(div);
   }
   .messages
     each entry in messageList
      button.clickableMessage(onclick = "msg( #{entry.message})")
       .unreadIndicator
       p.innerText #{entry.subject}
    //span 
    .readMessage
      p.messageText 
       | this is where i want my #{entry.message} to display when a subject button clicked

我是哈巴狗和网络开发的新手,我真的很挣扎!任何意见表示赞赏。

标签: javascript

解决方案


Javascript 代码看起来大部分都不错,尽管它看起来确实会附加另一个.readMessage作为current的.readMessage级。IE

    .readMessage
      p.messageText 
       | this is where i want my #{entry.message} to display when a subject button clicked
      .readMessage //<-- dynamically inserted into DOM by JS code
        p.messageText
          | message

您可以通过在浏览器中打开开发者工具并查看 DOM 来确认这一点。可能值得学习如何在开发者工具中使用调试器。

您可能想要做的是替换该节点:

function putMsg(message) {
  const newReadMessage = document.createElement("div");
  newReadMessage.classList.add("readMessage");
  newReadMessage.innerHTML = `<p class = "messageText"> ${message} </p>`;
  const oldReadMessage = document.querySelector(".readMessage");
  const parent = oldReadMessage.parentNode;
  parent.replaceChild(newReadMessage, oldReadMessage);
}

这或多或少直接来自MDN 文档replaceChild()

意见及建议

选择器

您可能希望为要替换的节点分配一个 ID 并将其用作选择器(多个元素可以使用同一个类,但 ID 在文档中应该是唯一的)。

逻辑 DOM 组织

.readMessage将元素移动到与元素相同的级别可能也很有意义.messages(这可能只是上面粘贴的代码中的间距错误),并且这两者都不应该是scriptelement.

文件组织

如果它不会使您的路由逻辑复杂化,如果可以的话,您可能希望将您的 Javascript 移动到一个单独的文件中。这样做将使您能够更好地利用可用于 Javascript 的工具,并更容易测试您的代码

框架和技术

Pug 是一种正在衰落的技术。生成静态 HTML 绝对没问题,尽管您可以看到它对动态内容没有任何帮助。JS 代码用于显示所选消息的方法称为DOM 操作,而事件侦听器内部的 DOM 操作在很大程度上被认为在大型项目中难以维护,因为操作相同 HTML 元素的事件侦听器通常位于非常不同的部分的代码。这使得在进行更改时很难知道哪些代码依赖于其他代码。例如,如果您需要在anddiv之间添加另一个.readMessagep.messageText,您必须搜索所有 Javascript 以尝试找到替换该元素的任何代码并在那里进行更改。您可能想研究像 React 这样的前端框架(尽管不可否认,没有一个事实上的入门工具包/代码模板来创建一个在后端使用 Express 并在前端使用 React 的项目 - 这可能会使其难以集成对您的项目做出反应)。


推荐阅读