6

My client has asked for the letter 4 to appear in red, wherever it is used in his website navigation.

For instance, where he has 'bikes4kids' as a menu item.

Unfortunately, I am using a 'mega menu' style plugin for his Magento site that only allows for plain text menu items - I cannot use HTML code in the menu item title box, which takes away the chance of me using <span>.

Is there a way of achieving this with JS? I assume not with CSS alone.

EDIT: The mega menu I am working with can be seen here: http://www.magentech.com/extensions/commercial-extensions/item/246-sm-mega-menu-responsive-magento-module

6
  • anyway (with JS or without it), you have to wrap the character you want to style in some HTML element, otherwise there is no chance for you to style the character. Commented Jun 2, 2014 at 10:30
  • Can't you just put that character inside a tag? Like: <span>bike<span class="special">s</span>4kids</span> Commented Jun 2, 2014 at 10:30
  • 2
    @DanielLisik, I think you were meant to wrap the 4! Commented Jun 2, 2014 at 10:31
  • @Pete oh missed that! :) Well, the point was still understood I think. Commented Jun 2, 2014 at 10:34
  • @DanielLisik he mentioned that he can't place HTML code inside the menu items - he is using a plugin that requires plain text. Commented Jun 2, 2014 at 10:42

4 Answers 4

3

I did it.

Please have a look at this Link

<div class="title">menu1</div> <div class="title">bike4kids</div> <div class="title">menu2</div> var avno = $(".title:nth-child(2)").text(); var avn = avno.split('4'); var item = avn[0]+"<span style='color:red'>4</span>"+avn[1]; $(".title:nth-child(2)").html(item); 

enter image description here

Sign up to request clarification or add additional context in comments.

Comments

2

No, within “plain text menu items” (as described in the question) you cannot style one character differently from others (except in a few very special cases, which do not apply here: styling the first letter, and setting the font of some characters different from others). JavaScript won’t help, because you would still need to make the character an element, and anything containing an element is by definition not plain text.

So you need to consider other approaches, like menus with items that allow some markup.

1 Comment

The input to the menu plugin is plain text- but surly after the plugin has done its magic to create DOM you can use javascript to modify it - assuming the plugin does its thing only once and not again and again - an assumption that proves true by a small test in the demo page.
0

If you can process the document after it's finished loading, or sometime after magento has finished doing its thing, you can try the following. It will wrap a provided character in a span with a supplied class. A root element can be provided to limit the scope of the replace. If no root is provided, it searches the entire document.

// Simple function to convert NodeList to Array // Not suitable for general application function toArray(obj) { var a = []; for (var i=0, iLen=obj.length; i<iLen; i++) { a[i] = obj[i]; } return a; } // Highlight character c by wrapping in a span with class className // starting with element root. If root not provided, document.body is used function highlightChar(c, className, root) { if (!root) root = document.body; var frag, idx, t; var re = new RegExp(c); // Add tag names to ignore var ignoreTags = {'script':'script'}; // Child nodes is a live NodeList, convert to array // so don't have to deal with changing as nodes are added var node, nodes = toArray(root.childNodes); var span = document.createElement('span'); span.appendChild(document.createTextNode(c)); span.className = 'highlightChar'; for (var i=0, iLen=nodes.length; i<iLen; i++) { node = nodes[i]; // If node is a text node and contains the chacter, highlight it if (node.nodeType == 3 && re.test(node.data)) { t = node.data.split(re); frag = document.createDocumentFragment(); // Insert higlight spans after first but not after last for (var j=0, jLen = t.length-1; j<jLen; j++) { frag.appendChild(document.createTextNode(t[j])); frag.appendChild(span.cloneNode(true)); } // Append last text node if (j > 0 && t[j]) { frag.appendChild(document.createTextNode(t[j])); } // Replace the original text node with higlighted fragment node.parentNode.replaceChild(frag, node); // Otherwise, if node is an element, process it } else if (node.nodeType == 1 && !(node.tagName.toLowerCase() in ignoreTags)) { highlightChar(c, className, node); } } } 

It can be used to process the entire document using:

window.onload = function() { highlightChar('4','highlightChar'); }; 

Comments

-1

Edit: Modified to find menu-items in 'mega menu'... I hope. In the demo site the "$" variable isn't jQuery so I modified the answer as well to use the jQuery function.

Testing in the demo site I found that the letter I modified did color yellow, but there was a bullet added to the left of it - apparently their css adds a bullet to the left (ie. :before) every span...

After the plugin completes its DOM modifications - simply run over the menu items and search-and-replace "4" with a colored span

eg.

// loop over all dom elements with class 'menu-item' // - I assume here below them exist only text jQuery('.sm-megamenu-child span').each(function() { var $item = jQuery(this); var text = $item.text(); var modified = text.replace(/4/g, "<span style='color:yellow'>4</span>"); $item.html(modified); }) 

3 Comments

And what particular library is that? Is there a tag for it on the question?
he mentioned using "mega menu" plugin, I made a fairly small assumption that the menu items have some class attribute - but looking at the 'mega menu' demo now I see that was a false assumption.
fixed the answer to iterate the menu items better.. still not perfect

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.