【问题标题】:Is it possible to make HTML element attributes immutable?是否可以使 HTML 元素属性不可变?
【发布时间】:2015-01-29 01:23:08
【问题描述】:

如果我想让 javascript 对象的属性不可变,可以使用 defineProperties()defineProperty()freeze() 等 Object 方法。我的问题是,我怎样才能对 HTML 元素属性做同样的事情?

我已经尝试过上述方法,虽然它们可以用来防止直接设置元素的属性(例如elem.id = 'foo';),但正如预期的那样,仍然可以通过setAttribute()更改底层属性。

“不,不可能”的回答是可以接受的,但我还没有遇到任何明确的声明。

【问题讨论】:

  • 到目前为止,javascript 还不支持它,但 ECMAScript 5 JavaScript 库可能支持不可变属性。
  • 您可以在该元素上重新定义 setAttribute() 以抛出错误。这可能行得通,虽然我还没有尝试过。
  • @iamnotmaynard:你仍然可以使用otherElement.setAttribute.call(thatElement, ...) 如果有人足够坚定... :p 但是,它可以防止简单的错误,即使它对恶意用户无效。真的取决于 OP 需要什么。
  • 我主要是想减少一些没有注意到我精心策划的属性操作的笨拙的新手程序员可能会绊倒并毁掉一切的可能性 :) iamnotmaynard 的想法可能有助于实现这一目标。
  • @DoctorDestructo 您应该真正编辑您的问题以指定您的目标。您在评论中提到想要防止失误。这比说“让它完全一旦设置就不可能再改变这个属性”要低得多。

标签: javascript html dom immutability


【解决方案1】:

您可以使用突变观察者来恢复旧的属性值。

new MutationObserver(callback)
    .observe(elem, {attributes: true, attributeOldValue: true});

function callback(mutations, observer) {
    var target = mutations[0].target;
    observer.disconnect();
    mutations.forEach(function(mutation) {
        target.setAttribute(mutation.attributeName, mutation.oldValue);
    });
    observer.observe(target, {attributes: true, attributeOldValue: true});
}

感谢@DoctorDestructo 提出的涉及observer.disconnect 的建议,这是避免无限循环所必需的。

【讨论】:

  • 这看起来像一个无限循环,但我喜欢这个主意。
  • 我没有使用MutationObserver 的经验,但它看起来很有希望。在没有像 defineProperty() 这样的“一劳永逸”解决方案的情况下,这可能是最好的选择。
  • 我测试了它的一个变体,发现它不会在脚本运行时恢复属性值,只有在之后。所以它甚至不会产生不变性的错觉。不过,我不确定这是否会消除它作为一种可行的替代方案。要注意的另一件事是 IE
  • 如果我之前的评论另有建议,我应该指出,这段代码根本不会按原样工作。无限循环需要修复,observe()方法需要一个额外的参数:attributeOldValue: trueLook here 如果您想查看我建议的编辑。它已经过测试,并且可以正常工作(以及这种技术可以)。
  • @DoctorDestructo 感谢您的修复。我已将它们纳入答案。
猜你喜欢
  • 2015-03-21
  • 1970-01-01
  • 1970-01-01
  • 2017-03-23
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-05-21
  • 1970-01-01
相关资源
最近更新 更多