Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

.html() vs .innerHTML

I'm working on a text editor. When the user double-clicks on a specific <div>, the contentEditable property is set to true and some editor tools appear. Then, the user can choose between clicking on "save" and "escape". If he escapes, I want to restore the previous data in this <div>. So I copy data on first double-click (temp['htmlTxt']) and then:

$('#esc').click(function() {
    var confEsc = confirm('---\n\nSouhaitez-vous quitter sans enregistrer vos modifications ?\n\n---');

    if(confEsc) { 

       //Do you know why that works :
       var id = document.getElementById(temp['myId']);
       id.innerHTML = temp['htmlTxt'];

       //and why that doesn't work ?
       $('#'+temp['myId']).html(temp['htmlTxt'])
    }
});

I don't understand why it works fine with classic JavaScript and not with jQuery...

like image 225
Vincencino il Franssoso Avatar asked Aug 08 '26 17:08

Vincencino il Franssoso


1 Answers

Those 2 are practically identical. However jQuery does some pre-processing that might be getting in your way...

jQuery Globals

rnoInnerHtml = /<(?:script|style)/i;
rtagName = /<([\w:]+)/;
rleadingWhitespace = /^\s+/;
rxhtmlTag = /<(?!area|br|col|embed|hr|img|input|link|meta|param)(([\w:]+)[^>]*)\/>/gi;
wrapMap = {
    "option": [1, "<select multiple='multiple'>", "</select>"],
    "legend": [1, "<fieldset>", "</fieldset>"],
    "thead": [1, "<table>", "</table>"],
    "tr": [2, "<table><tbody>", "</tbody></table>"],
    "td": [3, "<table><tbody><tr>", "</tr></tbody></table>"],
    "col": [2, "<table><tbody></tbody><colgroup>", "</colgroup></table>"],
    "area": [1, "<map>", "</map>"],
    "_default": [0, "", ""],
    "optgroup": [1, "<select multiple='multiple'>", "</select>"],
    "caption": [1, "<table>", "</table>"],
    "colgroup": [1, "<table>", "</table>"],
    "tfoot": [1, "<table>", "</table>"],
    "tbody": [1, "<table>", "</table>"],
    "th": [3, "<table><tbody><tr>", "</tr></tbody></table>"]
};

.html(value) setter

var elem = this[0] || {},
    i = 0,
    l = this.length;

if (typeof value === "string" && !rnoInnerhtml.test(value) && 
    (jQuery.support.leadingWhitespace || !rleadingWhitespace.test(value)) && 
    !wrapMap[(rtagName.exec(value) || ["", ""])[1].toLowerCase()]) {

    value = value.replace(rxhtmlTag, "<$1></$2>");

    try {
        for (; i < l; i++) {
            // Remove element nodes and prevent memory leaks
            elem = this[i] || {};
            if (elem.nodeType === 1) {
                jQuery.cleanData(elem.getElementsByTagName("*"));
                elem.innerHTML = value;
            }
        }

        elem = 0;

        // If using innerHTML throws an exception, use the fallback method
    } catch(e) {}
}

if (elem) {
    this.empty().append(value);
}

that's straight out of the current version for the setter on .html(string)

so basically if you value (1) isn't a string, (2) has a script tag, (3) your on a browser that doesn't support leading white-space and you string isn't trimmed, (4) you tag falls into the wrapMap special use cases OR (5) innerHTML fails for ANY other reason.. THEN you are essentially calling .empty().append(value) which is a whole different ball of wax... -ck

like image 96
ckozl Avatar answered Aug 10 '26 06:08

ckozl



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!