【问题标题】:JavaScript array won't update and can't type anything in inputsJavaScript 数组不会更新,也不能在输入中输入任何内容
【发布时间】:2019-05-25 15:42:05
【问题描述】:

当我点击费用管理器网站上的“创建注释”按钮时,编辑页面出现,但不断尝试重新加载,我无法在任何一个输入中输入任何内容。

我收到一个错误:'无法读取未定义的属性'标题''和一条消息:'限制导航以防止浏览器挂起。命令行开关 --disable-ipc-flooding-protection 可用于绕过保护'

我希望能够创建一项费用并在我返回主页时看到它更新,但是我什至无法输入任何内容,无论如何也不会更新任何内容。

// JS代码

// Read existing expenses from localStorage
const getSavedExpenses = function () {
    const expensesJSON = localStorage.getItem('expenses')

    if (expensesJSON !== null) {
        return JSON.parse(expensesJSON)
    } else {
        return []
    }
}
// Save expenses to localStorage
const saveExpenses = (expenses) => {
    localStorage.setItem('expenses', JSON.stringify(expenses))
}

const titleElement = document.querySelector('#expense-title')
const bodyElement = document.querySelector('#expense-body')
const removeElement = document.querySelector('#remove-note')
const expenseId = location.hash.substring(1)
const expenses = getSavedExpenses()
const expense = expenses.find(function (expense) {
    return expense.id === expenseId
})

// Get the DOM elements for an individual expense
const generateExpenseDOM = function (expense) {
    const expenseEl = document.createElement('div')
    const textEl = document.createElement('a')
    const removeButton = document.createElement('button')

// Setup the expense text
if (expense.title.length > 0) {
    textEl.textContent = expense.title
} else {
    textEl.textContent = 'Unnamed note'
}
textEl.setAttribute('href', `expense-edit.html#${expense.id}`)
expenseEl.appendChild(textEl)


// Remove expense by id
const removeExpense = function (id) {
const expenseIndex = expenses.findIndex(function (expense) {
return expense.id === id
})
if (expenseIndex > -1) {
    expenses.splice(expenseIndex, 1)
  }
}

// Setup the remove expense button
removeButton.textContent = 'x'
expenseEl.appendChild(removeButton)
removeButton.addEventListener('click', function () {
    removeExpense(expense.id)
    getSavedExpenses(expenses)
    renderExpenses(expenses, filters)
})
return expenseEl
}

if (expense === undefined) {
    location.assign('expense-edit.html')
}

titleElement.value = expense.title
bodyElement.value = expense.body

titleElement.addEventListener('input', function (e) {
    expense.title = e.target.value
    savedExpenses(expenses)
})
// add new expenses
document.querySelector('#new-expense').addEventListener('click', function (e) {
   const id = uuidv4()
      expenses.push({
         id: id,
         title: '',
         body: ''
      })
      getSavedExpenses()
     location.assign(`/expense-edit.html#${id}`)
   })

// HTML 代码

   <input id="title" placeholder="Expense title">
    <textarea id="body" placeholder="Expense body"></textarea>
    <button id="remove-expenses">Remove expense</button>
<script src="expenses-functions.js"></script>
<script src="expenses-edit.js"></script>
   <input id="search-text" type="text" placeholder="Filter todos">
     <div id="expenses"></div>
    <button id="new-expense">Submit</button>
    <script src="/uuidv4.js"></script>
    <script src="/expenses-functions.js"></script>
    <script src="/expenses-app.js"></script>

【问题讨论】:

    标签: javascript html arrays input uuid


    【解决方案1】:

    您在两个地方使用location.assign(),它导航到一个新页面。

    我的猜测是这个一直触发:

    if (expense === undefined) {
        location.assign('expense-edit.html')
    }
    

    expense 未定义,因此页面重新加载; expense 未定义,因此页面重新加载...

    找出为什么expense 没有值。 (您也可以将这些行注释掉,以确认这实际上是问题所在。)


    更新:此外,我认为您假设变量(如expenses 数组)在页面加载期间持续存在。 JS 变量不会在页面加载后持续存在。在您调用location.assign() 后,所有 JS 变量都会重置。

    所以这部分代码实际上并没有做任何事情:

    expenses.push({
         id: id,
         title: '',
         body: ''
      })
    

    我不确定getSavedExpenses() 中会发生什么,并认为变量可能通过localstorage 或其他方式保留在那里。 (否则这可能也是死代码,因为它的返回值甚至没有被使用。)

    有两种方法可以跨“页面加载”持久化数据:

    1. 将数据保存到持久存储,如数据库或本地存储。然后在下次加载页面时重新加载数据。如果使用数据库,通常表单中的数据会通过 API 请求发送到数据库服务器。
    2. 不要重新加载页面;通过 JS 修改页面 DOM(因此它可能看起来像页面“重新加载”。)

    更新 2:

    TypeError:无法将属性“值”设置为 null

    此错误是由于尝试访问值为 null 的变量上名为 value 的属性引起的。在您的代码中,这发生在两个地方:

    titleElement.value = expense.title
    bodyElement.value = expense.body
    

    遇到错误后,JS停止执行。这可能是 localStorage.getItem('expenses') 导致 null 的原因。

    【讨论】:

    • 感谢您的回答,这似乎是个问题,因为当我将它们注释掉时,页面加载正常,我仍然收到该错误并且数据仍然没有保存。我不明白为什么费用没有价值。
    • @RJDdev:我添加了一个更新,可能会给你更多的洞察力。
    • @RJDdev:如果您从事件处理程序中注释掉location.assign,我想您会看到数据已保存。 (它会立即在导航中被丢弃。)
    • @RJDdev:你注释掉整行了吗?我现在看到 getSavedExpenses() 使用 localStorage。有一个localStorage.getItem。但是,也应该有一个匹配的localStorage.setItem,也许在一个名为saveExpenses()的方法中
    • 感谢您的更新,我不太明白您所说的持久数据是什么意思。当我注释掉 location.assign 时,网站崩溃了。我在我的问题中添加了一些代码,包括 getSavedExpenses() 函数。
    猜你喜欢
    • 1970-01-01
    • 2021-10-01
    • 1970-01-01
    • 2021-04-02
    • 2015-07-22
    • 2013-04-08
    • 1970-01-01
    • 2016-03-30
    • 1970-01-01
    相关资源
    最近更新 更多