Search

Custom Smart Tags In IE

5 min read
0 views

Understanding Custom Smart Tags in IE

Custom Smart Tags let a website automatically turn plain text into clickable links after a page has loaded. On EggHeadCafe the words “XML”, “XSL”, and “SQL Server” become active links even though they appear as ordinary text in the source. These tags are not Microsoft's built‑in Smart Tag technology; instead, they rely on a mix of JavaScript, IE’s native .createTextRange method, and a small .htc behavior file that enhances the bold elements created during the conversion. The main goal of this approach is to keep the experience seamless for users while preserving the integrity of existing <a> tags and form controls.

When a page loads, the JavaScript routine scans the document for any words that match a list stored in an XML data island. Each match is replaced with a <b> element that carries a custom attribute containing the URL for that keyword. The <b> tag is styled with a class that triggers the behavior file, giving it hover and click events. By wrapping the keyword in a styled element instead of a normal tag, the script keeps the original HTML structure intact and avoids interfering with form inputs or pre‑existing links.

One of the biggest obstacles encountered was ensuring that the script does not disturb the state of links or form fields that already exist on the page. Regular expressions would scan the whole DOM and could accidentally split or corrupt <a> elements. The solution was to capture a snapshot of all current links before any replacements take place, then restore them after the keyword processing is finished. This two‑step approach guarantees that the page’s original behavior remains unchanged.

The script uses document.body.createTextRange to create a text range that represents the body content. Text ranges are a legacy IE feature that allow precise control over text selection and replacement without parsing the entire DOM tree. The advantage over regular expressions is that the range can be moved and collapsed, then used to search for the next occurrence of a keyword with findText. When the range is exhausted, the code collapses it back to the start, ready to process the next keyword. A known bug in IE causes collapse(true) to sometimes fail after a number of replacements, so the script recreates the range every other keyword to reset its state reliably.

To provide a clean separation between data and code, the keyword list is stored in an XML data island placed directly in the HTML page. Each <KEYWORD> node holds the URL to be used and a keyphrase attribute with the text that should be linked. This design keeps the keyword list editable without touching the JavaScript, and it allows the code to iterate over a NodeList via selectNodes and nextNode in a straightforward loop.

Finally, the behavior file attaches event handlers to the elements created by the script. When the mouse hovers over a keyword, the Hilite function changes the text color and cursor to provide visual feedback. Moving the mouse away triggers Restore, and clicking opens the keyword’s destination in a popup window sized to 500x350 pixels. The behavior file uses IE's proprietary PUBLIC:ATTACH syntax to bind these events without polluting the global namespace.

Implementing Custom Smart Tags: Step‑by‑Step

Below is a complete, ready‑to‑copy implementation that you can drop into any IE‑only site. The example shows the HTML skeleton, the XML data island, the JavaScript logic, and the .htc behavior file. Follow each block carefully, making sure the paths match your folder structure.

1. HTML page skeleton
Insert the XML data island, link the behavior style, and reference the script. The onload attribute on <body> starts the keyword conversion once the page has finished loading. Replace the sample form and text with your own content. Note that the XML data island is placed in a <xml> tag; the async="false" attribute ensures it loads before the script runs.

Prompt
<html></p> <p> <head></p> <p> <title>Custom Smart Tags Example</title></p> <p> <xml src="/behaviors/keywordpro.xml" id="xmlkeywords" async="false"></xml></p> <p> <style></p> <p> .KeyWordHiliting{behavior:url(/behaviors/keywordpro.htc)}</p> <p> </style></p> <p> <script src="/behaviors/keywordpro.js" language="JavaScript"></script></p> <p> </head></p> <p> <body onload="KeyWordInit();"></p> <p> <form id="frmSubmit" name="frmSubmit"></p> <p> <table align="center" cellpadding="0" cellspacing="0" border="0"></p> <p> <tr><td align="left">xml stuff</td></tr></p> <p> <tr><td align="left"></p> <p> <a href="http://www.topxml.com" target="_blank">XML101.com</a></p> <p> </td></tr></p> <p> <tr><td align="left"><input name="txtBox" value="XML"></td></tr></p> <p> </table></p> <p> </form></p> <p> </body></p> <p></html></p>

2. XML data island
This file holds all keywords and their target URLs. It lives on the same server so the browser can read it without an external request. Each keyword entry has a unique id, a keyphrase attribute for the text to match, and the URL wrapped inside the element.

Prompt
<?xml version="1.0"?></p> <p><KEYWORDS></p> <p> <KEYWORD id="1" keyphrase="xsl"></p> <p> http://www.eggheadcafe.com/keywordpromo.asp</p> <p> </KEYWORD></p> <p> <KEYWORD id="2" keyphrase="xselerator"></p> <p> </KEYWORD></p> <p> <KEYWORD id="3" keyphrase="sql server"></p> <p> </KEYWORD></p> <p> <KEYWORD id="4" keyphrase="soap"></p> <p> </KEYWORD></p> <p> <KEYWORD id="5" keyphrase="xml"></p> <p> </KEYWORD></p> <p></KEYWORDS></p>

3. JavaScript logic
The KeyWordInit function runs when the body loads. It loads the XML, iterates over each keyword, and replaces matches in the document body with styled elements. Before modifying the DOM, it saves existing link URLs and innerHTML so that they can be restored afterward if the script inadvertently changes them.

Prompt
function KeyWordInit(){</p> <p> var xmlDoc = document.getElementById("xmlkeywords");</p> <p> var keywordList = xmlDoc.selectNodes("//KEYWORDS/KEYWORD");</p> <p> var total = keywordList.length;</p> <p> var links = [], linksHTML = [];</p> <p> var existingLinks = document.all.tags('A');</p> <p> for (var i=0; i<existingLinks.length; i++){</p> <p> links[i] = existingLinks[i].href;</p> <p> linksHTML[i] = existingLinks[i].innerHTML;</p> <p> }</p> <p> for (var n=0; n<total; n++){</p> <p> var node = keywordList[n];</p> <p> var url = node.text;</p> <p> var phrase = node.getAttribute("keyphrase");</p> <p> var range = (n % 2 == 0) ? document.body.createTextRange() : range.collapse(true);</p> <p> while(range.findText(phrase)){</p> <p> try{</p> <p> range.pasteHTML('<b KeyWordURL="'+url+'" style="color:#6666CC;text-decoration:none" class="KeyWordHiliting">'+range.text+'</b>');</p> <p> range.collapse(false);</p> <p> }catch(e){</p> <p> }</p> <p> }</p> <p> }</p> <p> existingLinks[i].href = links[i];</p> <p> existingLinks[i].innerHTML = linksHTML[i];</p> <p> }</p> <p>}</p>

4. Behavior file (.htc)
The .htc file attaches mouse events to each element created by the script. When the user hovers over a keyword, the text turns black and the cursor changes to a hand. Clicking opens the keyword’s URL in a popup. The behavior is applied through the .KeyWordHiliting CSS class defined in the style section of the HTML.

Prompt
<PUBLIC:ATTACH EVENT="onmouseover" ONEVENT="Hilite()" /></p> <p><PUBLIC:ATTACH EVENT="onmouseout" ONEVENT="Restore()" /></p> <p><PUBLIC:ATTACH EVENT="onclick" ONEVENT="KeyWordLaunch()" /></p> <p><script language="JavaScript1.2"></p> <p> var normalColor;</p> <p> function Hilite(){</p> <p> if (event.srcElement == element){</p> <p> normalColor = style.color;</p> <p> runtimeStyle.color = "#000000";</p> <p> runtimeStyle.cursor = "hand";</p> <p> }</p> <p> }</p> <p> function Restore(){</p> <p> runtimeStyle.color = normalColor;</p> <p> runtimeStyle.cursor = "";</p> <p> }</p> <p> }</p> <p> function KeyWordLaunch(){</p> <p> var options = "width=500,height=350,scrollbars=1,resizable=1";</p> <p> window.open(element.KeyWordURL,"",options);</p> <p> }</p> <p> }</p> <p></script></p>

5. Final checklist
- Verify that the .htc file is accessible at /behaviors/keywordpro.htc and that the behavior property in the CSS points to that exact path.
- Confirm that the XML data island is loading correctly; open the page in IE and check the XML element in the DOM inspector.
- Test the page with a mix of existing links, form fields, and plain text containing the target keywords to ensure that nothing else on the page is broken.
- Because the solution relies on IE-only features, be sure that it’s acceptable to limit the behavior to that browser, or add graceful degradation for others.

With the code above in place, the EggHeadCafe site can automatically turn selected phrases into interactive links after the page loads, all while keeping the original content structure intact and preserving user experience in forms and existing hyperlinks. This method demonstrates a practical, browser‑specific way to add dynamic keyword linking without the overhead of server‑side processing or complex third‑party libraries.

Suggest a Correction

Found an error or have a suggestion? Let us know and we'll review it.

Share this article

Comments (0)

Please sign in to leave a comment.

No comments yet. Be the first to comment!

Related Articles