在 Javascript 中,你能扩展 DOM 吗?

IT技术 javascript dom
2021-02-13 02:45:31

在 Javascript 中,您可以使用其原型对象来扩展现有类:

String.prototype.getFirstLetter = function() {
    return this[0];
};

是否可以使用这种方法来扩展 DOM 元素?

5个回答

我在写问题的时候找到了答案,但我想我还是会发帖来分享信息。

您需要扩展的对象是Element.prototype.

Element.prototype.getMyId = function() {
    return this.id;
};

您可以使用 Element 的原型来扩展 DOM。但是,这在 IE7 及更早版本中不起作用。您将需要扩展特定元素,一次一个。Prototype 库就是这样做的。我建议查看源代码以确切了解它是如何完成的。

请注意,只有 IE6 和 IE7 才需要这样做,因为 IE8 支持此功能。请参阅msdn.microsoft.com/en-us/library/dd282900(VS.85).aspx
2021-03-26 02:45:31
是的,IE8 在 DOM 操作方面取得了很大的进步,但完全支持它现在并不是我的优先事项
2021-04-10 02:45:31

你不应该直接扩展任何东西(“任何东西”我的意思是原生 DOM 对象)——那只会导致不好的事情。加上重新扩展每个新元素(您必须做的事情才能支持 IE)会增加额外的开销。

为什么不采用 jQuery 方法并创建一个包装器/构造函数并对其进行扩展:

var myDOM = (function(){
    var myDOM = function(elems){
            return new MyDOMConstruct(elems);
        },
        MyDOMConstruct = function(elems) {
            this.collection = elems[1] ? Array.prototype.slice.call(elems) : [elems];
            return this;
        };
    myDOM.fn = MyDOMConstruct.prototype = {
        forEach : function(fn) {
            var elems = this.collection;
            for (var i = 0, l = elems.length; i < l; i++) {
                fn( elems[i], i );
            }
            return this;
        },
        addStyles : function(styles) {
            var elems = this.collection;
            for (var i = 0, l = elems.length; i < l; i++) {
                for (var prop in styles) {
                    elems[i].style[prop] = styles[prop];
                }
            }
            return this;
        }
    };
    return myDOM;
})();

然后你可以通过myDOM.fn...添加你自己的方法,你可以像这样使用它:

myDOM(document.getElementsByTagName('*')).forEach(function(elem){
    myDOM(elem).addStyles({
        color: 'red',
        backgroundColor : 'blue'
    });
});
这曾经是一个坏主意,现在还不错。github.com/nbubna/mind-hacking/blob/gh-pages/...
2021-03-23 02:45:31
我们不是在谈论 JavaScript 语言和设计模式或类似的东西。这是关于 DOM - 扩展原生 DOM 对象不是一个好主意;更不用说它不能在所有浏览器中正常工作的事实......
2021-03-27 02:45:31
“你不应该直接扩展任何东西——那只会导致坏事。” 如果您有充分的理由这样做并正确编写代码,它将带来好事。除了互操作性问题,没有理由不扩展 Element.prototype;对于其他默认对象,可以有很多好处(参见向 Date.prototype 添加格式化方法,或转义到 RegExp.prototype)。当它们可用且有用时放弃完全有用的 OO 实践是愚蠢的。
2021-04-12 02:45:31

可以,但强烈建议不要这样做。

如果您覆盖了另一个库期望成为原始库的内容,或者另一个库覆盖了您期望的内容.. 混乱!

最佳做法是将您的代码保存在您自己的命名空间/范围内。

如果有人正在寻找这个(我知道我是),这是所有 HTML 标签的 JavaScript 类型:

interface HTMLElementTagNameMap {
    "a": HTMLAnchorElement;
    "abbr": HTMLElement;
    "address": HTMLElement;
    "applet": HTMLAppletElement;
    "area": HTMLAreaElement;
    "article": HTMLElement;
    "aside": HTMLElement;
    "audio": HTMLAudioElement;
    "b": HTMLElement;
    "base": HTMLBaseElement;
    "bdi": HTMLElement;
    "bdo": HTMLElement;
    "blockquote": HTMLQuoteElement;
    "body": HTMLBodyElement;
    "br": HTMLBRElement;
    "button": HTMLButtonElement;
    "canvas": HTMLCanvasElement;
    "caption": HTMLTableCaptionElement;
    "cite": HTMLElement;
    "code": HTMLElement;
    "col": HTMLTableColElement;
    "colgroup": HTMLTableColElement;
    "data": HTMLDataElement;
    "datalist": HTMLDataListElement;
    "dd": HTMLElement;
    "del": HTMLModElement;
    "details": HTMLDetailsElement;
    "dfn": HTMLElement;
    "dialog": HTMLDialogElement;
    "dir": HTMLDirectoryElement;
    "div": HTMLDivElement;
    "dl": HTMLDListElement;
    "dt": HTMLElement;
    "em": HTMLElement;
    "embed": HTMLEmbedElement;
    "fieldset": HTMLFieldSetElement;
    "figcaption": HTMLElement;
    "figure": HTMLElement;
    "font": HTMLFontElement;
    "footer": HTMLElement;
    "form": HTMLFormElement;
    "frame": HTMLFrameElement;
    "frameset": HTMLFrameSetElement;
    "h1": HTMLHeadingElement;
    "h2": HTMLHeadingElement;
    "h3": HTMLHeadingElement;
    "h4": HTMLHeadingElement;
    "h5": HTMLHeadingElement;
    "h6": HTMLHeadingElement;
    "head": HTMLHeadElement;
    "header": HTMLElement;
    "hgroup": HTMLElement;
    "hr": HTMLHRElement;
    "html": HTMLHtmlElement;
    "i": HTMLElement;
    "iframe": HTMLIFrameElement;
    "img": HTMLImageElement;
    "input": HTMLInputElement;
    "ins": HTMLModElement;
    "kbd": HTMLElement;
    "label": HTMLLabelElement;
    "legend": HTMLLegendElement;
    "li": HTMLLIElement;
    "link": HTMLLinkElement;
    "main": HTMLElement;
    "map": HTMLMapElement;
    "mark": HTMLElement;
    "marquee": HTMLMarqueeElement;
    "menu": HTMLMenuElement;
    "meta": HTMLMetaElement;
    "meter": HTMLMeterElement;
    "nav": HTMLElement;
    "noscript": HTMLElement;
    "object": HTMLObjectElement;
    "ol": HTMLOListElement;
    "optgroup": HTMLOptGroupElement;
    "option": HTMLOptionElement;
    "output": HTMLOutputElement;
    "p": HTMLParagraphElement;
    "param": HTMLParamElement;
    "picture": HTMLPictureElement;
    "pre": HTMLPreElement;
    "progress": HTMLProgressElement;
    "q": HTMLQuoteElement;
    "rp": HTMLElement;
    "rt": HTMLElement;
    "ruby": HTMLElement;
    "s": HTMLElement;
    "samp": HTMLElement;
    "script": HTMLScriptElement;
    "section": HTMLElement;
    "select": HTMLSelectElement;
    "slot": HTMLSlotElement;
    "small": HTMLElement;
    "source": HTMLSourceElement;
    "span": HTMLSpanElement;
    "strong": HTMLElement;
    "style": HTMLStyleElement;
    "sub": HTMLElement;
    "summary": HTMLElement;
    "sup": HTMLElement;
    "table": HTMLTableElement;
    "tbody": HTMLTableSectionElement;
    "td": HTMLTableDataCellElement;
    "template": HTMLTemplateElement;
    "textarea": HTMLTextAreaElement;
    "tfoot": HTMLTableSectionElement;
    "th": HTMLTableHeaderCellElement;
    "thead": HTMLTableSectionElement;
    "time": HTMLTimeElement;
    "title": HTMLTitleElement;
    "tr": HTMLTableRowElement;
    "track": HTMLTrackElement;
    "u": HTMLElement;
    "ul": HTMLUListElement;
    "var": HTMLElement;
    "video": HTMLVideoElement;
    "wbr": HTMLElement;
}

取自“lib.dom.d.ts”(随 vs-code 一起提供)。