Search code examples
javascriptjquerycodeigniter

Why is javascript throwing error over regex


I am trying to use an HTML truncating function called 'cutKeepingTags()' found and demonstrated online (https://jsfiddle.net/7mbxf5hq/) but when I try to run it I get a console error: Uncaught TypeError: Cannot read property 'match' of undefined at cutKeepingTags ((index):566). I am using the framework Codeigniter 3, the OS is Windows 10 latest, the version of jQuery is 3.3.1, PHP version 7.4.7 and I am using Vscode as my editor.

The function code is:

function cutKeepingTags(elem, reqCount) {
    var grabText = '',
        missCount = reqCount;
    $(elem).contents().each(function() {
        switch (this.nodeType) {
            case Node.TEXT_NODE:
                // Get node text, limited to missCount.
                grabText += this.data.substr(0, missCount);
                missCount -= Math.min(this.data.length, missCount);
                break;
            case Node.ELEMENT_NODE:
                // Explore current child:
                var childPart = cutKeepingTags(this, missCount);
                grabText += childPart.text;
                missCount -= childPart.count;
                break;
        }
        if (missCount === 0) {
            // We got text enough, stop looping.
            return false;
        }
    });
    return {
        text:
            // Wrap text using current elem tag.
            elem.outerHTML.match(/^<[^>]+>/m)[0] + grabText + '</' + elem.localName + '>',
        count: reqCount - missCount
    };
}

and the line objected to is the penultimate line containing 'match(/^<[^>]+>/m)[0]'. As the demo works it should work for me as 'advertised'. Why is Javascript throwing the error?


Solution

  • When you select an element by class (.), it always returns an array regardless of whether or not you have more than one. The element being passed in the first argument must be a native dom element, not an array of dom elements.

    var target = $('.truncated'); is not the same as var target = $('.truncated')[0];

    Under the hood, JQuery is doing this: document.getElementsByClassName('truncated')[0];