Javascript 如何测试DOM元素属性是否为只读

Javascript 如何测试DOM元素属性是否为只读,javascript,dom,propertyinfo,Javascript,Dom,Propertyinfo,这是一个关于使用纯Javascript(不是jQuery等)与DOM交互的问题 我的最终目标是收集任何给定DOM元素的可写属性的当前值,因此我想跳过该元素的所有不可写属性 虽然我可以浏览规范并创建一个列表,但规范会发生变化,所以我希望动态地(并且尽可能高效地)执行 我已经搜索过了,但是没有找到,所以欢迎您提出任何建议 伪代码:我需要一种在下面的代码中实现is_writable(element)->boolean的方法 let myObject = {}; for (propertyName in

这是一个关于使用纯Javascript(不是jQuery等)与DOM交互的问题

我的最终目标是收集任何给定DOM元素的可写属性的当前值,因此我想跳过该元素的所有不可写属性

虽然我可以浏览规范并创建一个列表,但规范会发生变化,所以我希望动态地(并且尽可能高效地)执行

我已经搜索过了,但是没有找到,所以欢迎您提出任何建议

伪代码:我需要一种在下面的代码中实现is_writable(element)->boolean的方法

let myObject = {};
for (propertyName in HTMLElement) {
    if(is_writable(HTMLElement[propertyName])){
        myObject[propertyName] = HTMLElement[propertyName];
    }
}

属性是否可写可以从其属性描述符确定。 可以使用object.getOwnPropertyDescriptor()获取对象的属性描述符。但是,此函数将仅查找对象自身的属性

因此,我们需要一个函数来搜索对象的原型链,直到找到我们要查找的属性并返回属性描述符:

function findPrototypeProperty(object, propertyName){
    while (object && object.constructor && object.constructor.name !== 'Object'){
        let desc = Object.getOwnPropertyDescriptor(object, propertyName);
        if(desc){
            return desc;
        }
        object = Object.getPrototypeOf(object);
    }
    return null;
}
属性描述符是最多可包含6个值的对象(从MDN复制):

首先要做的是检查可写值。如果为true,则该属性是可写的。但是,您还应该检查“value”是否不是函数

有些属性没有实际值,而是一个getter和setter函数。如果一个属性有一个set函数,它通常也是可写的

这就是可写函数的外观:

function is_writeable(object, propertyName){
    let desc = findPrototypeProperty(object, propertyName);
    if(!desc){
        return false;
    }
    if(desc.writable && typeof desc.value !== "function"){
        return true;
    }
    return !!desc.set;
}
结论:
不要这样做。使用列表。

使用
document.querySelectorAll
检查
DOM元素的特定属性

像这样:

document.querySelectorAll('*[readonly]'))

将返回具有
只读属性的所有元素的数组。

您所说的“元素属性是只读的”是什么意思?从
键入元素或
元素或可编辑的内容???到目前为止,您尝试的代码在哪里?你的HTML在哪里?你能澄清一下你指的是JS对象属性还是元素属性吗?编辑了这个问题以便更清楚我想接受这个答案,因为它正是我需要的答案。我同意列表是最好的,但这段代码是生成列表的一种很好的方法。对于生成列表,这段代码可能非常有效。您只需注意一些特殊属性,如innerHtml和outerHtml。
function is_writeable(object, propertyName){
    let desc = findPrototypeProperty(object, propertyName);
    if(!desc){
        return false;
    }
    if(desc.writable && typeof desc.value !== "function"){
        return true;
    }
    return !!desc.set;
}