让JS API返回一个polyfilled DOM节点

时间:2017-12-04 05:24:50

标签: javascript html polyfills

我正在使用HTML中的<data>元素,该元素具有良好的支持,但对我的目的来说还不够。 HTMLDataElement中的额外功能是value的getter,它返回相应的属性。

当然这很容易实现,只需使用以下代码(当然,在特征检测之后)

class HTMLDataElement extends HTMLElement {
    constructor() {
        super();
    }

    get value() {
        return this.getAttribute(`value`);
    }
}

这很有效。只有一个问题:当使用getElementByIdquerySelector等本机API时,返回的节点不是实例HTMLDataElement。如果可能的话,我怎么能这样做呢?

为了清楚起见,我希望能够document.querySelector('foo').value执行<data>,无论是否支持.getAttribute('value')的浏览器支持。

(我很清楚我可以使用.value代替CXEndCallAction *action = [[CXEndCallAction alloc] initWithCallUUID:callUUID]; [self.callController requestTransaction:[CXTransaction transactionWithActions:@[action]] completion:completion]; 。重点是我不想。)

1 个答案:

答案 0 :(得分:2)

在Twitter上与Jonathan Neal *联系后,他提供了一个如何做到这一点的好例子。

if (!this.HTMLDataElement) {
    this.HTMLDataElement = this.HTMLUnknownElement;

    const valueDescriptor = Object.getOwnPropertyDescriptor(HTMLDataElement.prototype, 'value');

    Object.defineProperty(
        HTMLDataElement.prototype,
        'value',
        valueDescriptor || {
            get() {
                return 'DATA' === this.nodeName && this.getAttribute('value');
            }
        }
    );
}

console.log('data:', document.querySelector('data').value);

console.log('xdata:', document.querySelector('xdata').value);
<data value="this should work">
<xdata value="this should not work">

*对于不熟悉的人来说,Jonathan Neal是PostCSS插件的主要贡献者,并且自己创建了许多JavaScript polyfills。