使用JavaScript存储(和检索!)特定于DOM元素的数据的最佳方法
使用JavaScript存储(和检索!)特定于DOM元素的数据的最佳方法
我有一个下拉列表的矩阵,并且我希望能够在用户编辑设置时通过视觉方式显示出来(例如通过将表格单元格的背景设置为红色)。如果他们将其切换回原始值,它将恢复到默认的背景颜色。这样,系统的状态将清晰明了。为了实现这一点,我想到了在
function chSel(node, origSelIndex) { if (node.selectedIndex == origSelIndex) // 切换回设置状态 node.parentNode.removeAttribute('class'); else node.parentNode.setAttribute('class','cell_changed'); }
\n这不需要检索动态数据,尽管在onchange处理程序中保存的selectedIndex值作为元素特定的静态数据。我想通过在表格周围添加一个边框来扩展这个描述的功能,当其中任何内容被修改时,将边框颜色设置为红色,这样,即使表格很大,仍然可以一眼看出其中的任何条目是否被修改了。\n有一种不好的方法和一种更好的方法来实现这个。不好的方法,我知道如何在符合HTML/XHTML的情况下实现,就是让chSel(每当用户与下拉菜单交互时执行)在整个表格中进行完整搜索以计算编辑次数,并相应地标记表格边框。这实际上可能不是一个性能问题,但我预计会是这样。我不认为它会很好地扩展。\n更好的方法是保持编辑元素的数量计数。当这个数字降到零时(用户将所有编辑都改回原始值),我可以重新标记表格为未编辑状态。\n然而,这需要我有一种方法来确定选择菜单是否已从一个新值更改为另一个新值,而不是从原始值更改为新值,即现在关注的是被改变的值。似乎没有办法做到这一点。这个讨论似乎表明,我不能创建和检索自定义属性而保持文档有效。当我尝试分配任意属性时,我很难检索它们的值。\n还有什么办法吗?我可以构建一个将元素作为键映射到整数的对象吗?JavaScript会允许我这样做吗?
问题的出现原因:
在这个代码示例中,作者想要在每个select元素中存储和检索特定的数据。作者使用了dom属性作为一种全局变量的方式来存储数据。然而,这种方法可能不是最佳的解决方案,因为它可能会导致代码混乱和难以维护。
解决方法:
为了解决这个问题,有几种更好的方法可以存储和检索特定于dom元素的数据。以下是几种可能的解决方案:
1. 使用对象存储数据:
创建一个对象,将dom元素作为键,将数据作为值存储在对象中。通过这种方式,可以轻松地存储和检索特定于dom元素的数据。
2. 使用闭包:
使用闭包可以在dom元素上存储和检索特定的数据。通过将数据存储在闭包内部的变量中,可以确保数据的私密性和安全性。
3. 使用自定义属性:
使用自定义属性是存储和检索dom元素特定数据的另一种方法。通过在dom元素上添加自定义属性,可以将特定数据与dom元素关联起来,并且可以很容易地通过访问自定义属性来检索数据。
在这个问题中,作者试图找到一种最佳的方法来存储和检索特定于dom元素的数据。通过使用对象、闭包或自定义属性,可以实现这一目标。这些解决方案都有各自的优点和缺点,根据具体情况选择最合适的方法来存储和检索dom元素特定的数据。
在使用JavaScript存储和检索dom元素特定数据时,可能会遇到一些问题。大多数表单控件都有一个defaultValue属性,可以通过循环遍历它们,并将当前的value与defaultValue进行比较,以判断是否有任何更改。对于select元素,始终设置其中一个option为selected,并检查当前选中的option的defaultSelected属性是否为true。对于单选按钮和复选框也是类似的处理方式。
这样一来,就不需要存储任何值,DOM元素自身会完成这个任务。
不过,可能会有一些情况下需要手动设置这些值,而它们并不会自动设置,这有点让人不爽。但是了解到这一点之后,下次就不需要重复造轮子了。另外,这些方法还无法告诉我从哪个选项切换过来。
当然,以上方法的有用与否取决于你想做什么。与默认值或选中状态进行比较可以判断是否与默认值不同,但不会提供其他信息。通常情况下这已经足够了。如果你想要跟踪每次值的变化,包括从哪个值切换过来,那你将需要使用多种方法,并且可能在某些浏览器中失败,因为当用户可以以各种方式输入数据和更改值时,跟踪这些变化是相当困难的。
最佳的方法来存储(和检索!)使用JavaScript的dom元素特定数据的问题是如何解决原因以及解决方法。在JavaScript中,您可以在JavaScript变量或自定义DOM属性中跟踪状态。JavaScript变量稍微容易一些,但您必须为它们提供适当的范围,以便它们在操作的持续时间内存活下来。自定义DOM属性有时更容易使其面向对象化,并避免使用任何全局JavaScript变量。jQuery的.data()功能实际上介于两者之间。它使用一个自定义数据属性为DOM对象打上唯一的标签,然后在JavaScript映射中存储所有实际数据。
一旦适当地存储了状态,每当您获得更改事件时,您可以将其与先前值进行比较,看看从先前状态实际更改了什么,更新新状态并将新值保存为先前值或执行其他任何需要的操作。
例如,通过这种方式,您可以保持编辑项目的计数,并且每当该值从0变为非零或非零变为0时,您都可以根据需要更改整个表的外观。同样,每当单个单元格更改时,您都可以更新其外观。
如果您的DOM元素是唯一的数据结构,那么最简单的方法可能就是创建一个自定义属性并在那里保存其他数据。这样做的HTML5方式是在属性名前添加"data-",如obj.setAttribute("data-origSelectIndex", x)
或obj["data-origSelectIndex"] = x
,以避免与标准属性的任何名称冲突。
如果您有任何原因不想使用自定义属性,那么您需要创建一个平行的JavaScript数据结构(可能是一个数组),它可以保存表中每个对象的数据。
好的,但是我没有为我要跟踪的每个项目都有一个JavaScript变量。我正在使用DOM元素作为我的数据结构。编辑:好的,有没有一种不使用jquery的简单方法来构建这个?我不想为一个东西带来这种依赖性。
然后使用setAttribute和getAttribute在DOM对象上保存状态。我不太明白您要做什么,所以无法推荐特定的代码。如果出于某种原因您不想使用自定义属性,则必须声明一个平行的JavaScript数据结构(可能是一个数组),可以为表中的每个对象保存数据。
如下所示,最好将内容存储在对象中,而不是data-属性中。为每个控件分配一个用于引用的id,并将值写入对象中(比使用getAttribute,解析值,构建新值,然后setAttribute更快且更简单)。每个控件类型存储的内容是不同的,例如,如果使用选择器,则只需跟踪所选索引的值。对于文本输入,您需要存储整个值。
是的,根据reference.sitepoint.com/javascript/Element/getAttribute,getAttribute在所有浏览器上都存在错误,尽管根据quirksmode.org/dom/w3c_core.html#t113,它并非如此。我将避免使用getAttribute。
- 是的,好主意。DOM属性在各个浏览器中更一致。如果您将内容存储在对象中,您可以更直接且更快地定义结构和访问值。