2

A client has asked for all of the trademark symbols (™ and ®) on their website to be styled in a specific way; given the quantity in which they appear—everywhere from titles to body text and navigation—we've decided to do this with JavaScript.

What we want to do is find every instance of ™ and ® in the page text (but not inside element attributes) and wrap them in <sup> tags so we can style them in CSS.

This is the code we currently have:

Trademark = {
    init: function () {
        $('body').contents().each(function () {
            var element = $(this);
            if (element.html()) {
                element.html(element.html().replace(/(?![^<]+>)™/gi, '<sup class="trademark">™</sup>'));
                element.html(element.html().replace(/(?![^<]+>)®/gi, '<sup class="trademark">®</sup>'));
            }
        });
    }
}

$(function () {
    Trademark.init();
})

It works well, but we're now suffering the problem that JavaScript click events aren't being registered on elements that have had their contents replaced—I'm assuming because they're being removed from the DOM when they're being manipulated.

Is there a modification to this (to the JS or regex) that will stop this from happening? Thanks!

querkmachine
  • 132
  • 1
  • 8
  • It's odd that this is removing the events bound to an element, as you're only working on the content of the element. Could you set up a http://jsfiddle.net which shows the problem, as it seems to work fine: http://jsfiddle.net/5893n/ – Rory McCrossan Jul 01 '14 at 08:33
  • possible duplicate of [jQuery click not working for dynamically created items](http://stackoverflow.com/questions/9484295/jquery-click-not-working-for-dynamically-created-items) – Liam Jul 01 '14 at 08:35
  • @RoryMcCrossan - It's removing the event handlers as the entire html of every element is replaced. – adeneo Jul 01 '14 at 08:35
  • @adeneo seems ok here: http://jsfiddle.net/5893n/ – Rory McCrossan Jul 01 '14 at 08:36
  • @RoryMcCrossan - That's just because there's no nesting -> **http://jsfiddle.net/5893n/1/** – adeneo Jul 01 '14 at 08:37

1 Answers1

3

Filter for textNodes only and replace the innerHTML of the parentNode, that way the elements themselves are never replaced and the event handlers should stay intact.

Trademark = {
    init: function () {
        $('*').contents().each(function() {
            if (this.nodeType == 3 && this.nodeValue) {
                if ( this.nodeValue.indexOf('™') != -1 || this.nodeValue.indexOf('®') != -1 ) {
                    this.parentNode.innerHTML = this.parentNode.innerHTML.replace(/(?![^<]+>)(™|®)/gi, '<sup class="trademark">$1</sup>');
                }
            }
        });
    }
}

FIDDLE

adeneo
  • 312,895
  • 29
  • 395
  • 388