2

I need to rewrite document.createElement() method and I'm looking for a javascript source code online to get some ideas. I searched http://code.google.com/p/v8/source/browse but it seems like the search returns results from all svn sources (even non-related libraries) which makes it messy. I browsed the code in the svn, and there are of course C++ source code, but obviously no javascript implementations.

lyxio
  • 123
  • 2
  • 9
  • Such a thing is not possible. If you `alert` or `console.log` this or any other native function you will see something like `function name() { [native code] }` – Niet the Dark Absol Feb 20 '13 at 20:09
  • 6
    _"I need to rewrite document.createElement()"_ - Why? _"but obviously no javascript implementations"_ - You can't just rewrite a native DOM method because you can only interact with the DOM via the methods the browser provides (unless you write your own browser). You _can_ write a wrapper method that calls the built-in DOM methods... – nnnnnn Feb 20 '13 at 20:09
  • 1
    What exactly are you trying to do? – epascarello Feb 20 '13 at 20:12
  • I need to implement DOMNodeInserted event for IE. – lyxio Feb 20 '13 at 20:15
  • nnnnnn you CAN rewrite any DOM method that it's "writable" property is set to true. Could you explain a bit about the wrapper method? – lyxio Feb 20 '13 at 20:17
  • 2
    DOMNodeInserted is slated for deprecation, so you won't be writing this for only IE.... – Chris Baker Feb 20 '13 at 20:18
  • It's not yet depreciated, but will be soon, so that's correct I'll use it for other browsers too... – lyxio Feb 20 '13 at 20:20
  • _"you CAN rewrite any DOM method that it's "writable" property is set to true"_ - I meant (and indeed said) that your replacement method couldn't interact with the DOM unless you call the browser's built-in DOM methods (or in the case where you've overwritten a built-in method you might need to keep a reference to the original first). By "wrapper" I meant `function myCreateElement(some params here) { /* some code here that does some stuff and then calls document.createElement() and then possible does more stuff */ }`. – nnnnnn Feb 20 '13 at 20:31

1 Answers1

1

You should not, and usually cannot, re-write native DOM methods. Methods such as createElement are "close to the surface" of a client's EMACscript implementation, have protected scopes, and are simply not able to be reproduced by "userland" script.

In the case of createElement, you might be able to overwrite the createElement function of the document object in certain browsers (see below), but you'll also quickly find that it crashes and burns on certain existing clients/versions. Further, you cannot change the prototype of document because it has none.

You can, however, easily and without risk create a small wrapper function:

var createElement = function (ele_type, attrs) {
    var ele = document.createElement(ele_type);
    if (!ele)
        return false;

    for (var idx in attrs) {
        if ((idx == 'styles' || idx == 'style') && typeof attrs[idx] == 'object') {
            for (var prop in attrs[idx]){ele.style[prop] = attrs[idx][prop]}
        } else if (idx == 'html') {
            ele.innerHTML = attrs[idx]
        } else {
            ele.setAttribute(idx, attrs[idx]);
        }
    }

    // now fire any custom events or do whatever you needed to do

};

var myNewDiv = createElement ('div', {'id':'myNewDiv', 'styles':{'color':'red'}});

That gives you the opportunity to implement custom code upon creation of a new element. It will work on all browsers regardless of implementation differences, and is as future-proof as any other code you would write today.

Another route mentioned above, which is NOT cross-browser or guaranteed to work even tomorrow, is to overwrite the createElement function of active document instance. The trouble with this approach is that the document object isn't defined by the specification -- it is implementation specific. Today, Firefox (for example) will allow you to overwrite this function, but that could change without notice.

document.createElement = function(originalDocumentCreate) {
    return function() {
        var ele = originalDocumentCreate.apply(this, arguments);

        // now fire any custom events or do whatever you needed to do

        return ele;
    };
}(document.createElement);

See also: https://stackoverflow.com/a/11727842/610573 (code concept credit to Esailija)

Community
  • 1
  • 1
Chris Baker
  • 49,926
  • 12
  • 96
  • 115
  • I'm just curious: How crazy/compatible would it be to "extend" `document.createElement`. Like so: `var nativeMethod = document.createElement;` and then `document.createElement = function(ele_type, attrs) { nativeMethod.call(document, ele_type, attrs); /* Then do other stuff */ })`. Works in Chrome, via the dev console anyway. – meetamit Feb 20 '13 at 20:30
  • @meetamit Chrome plays nice. I hear that (older versions?) of MSIE (surprise surprise) don't. – Alnitak Feb 20 '13 at 20:31
  • Thanks Chris. But wrapping won't work in my case, simply because I have no control to force users to use this wrapper function to create new elements, and in fact this is the main reason I need to rewrite the native code so users can continue creating elements with the "native" code, and I can add functionality to it. – lyxio Feb 20 '13 at 20:33
  • 2
    @meetamit You can get away with it in Firefox and Chrome **today**. The specification does NOT dictate, however, that this is the case. The `document` object contains many implementation-specific quirks and is not predictable or trustworthy. – Chris Baker Feb 20 '13 at 20:33