Main Page Content
Show Your Attributes
Through the W3C's Document Object Model (DOM), normally invisible parts of a Web page can be easily made a part of the visible page. The DOM, for example, can be used to reveal the information contained within things like the title
attribute in most modern browsers. (This can easily be accomplished onclick="window.open(this.href);return false;">using CSS, but not in Internet Explorer on Windows.)
To see how this works, let's assume there's a page with a bulleted list of news items. Each LI
has the date the item was posted in the element's title
:
<div id="news"> <ul> <li title="January 1, 2002">Happy New Year's</li> <li title="March 17, 2002">Happy St. Patrick's Day</li> <li title="April 1, 2002">April Fool's</li> </ul></div>
Before attempting to access the content, it's important to check the browser's higher-level DOM support:
if((document.createElement) && (document.createTextNode))
(This should be true for IE5+, Konqueror, Netscape 6.x, Mozilla, and other Gecko-based browsers. Opera 5 and 6 should test false.)
Finding the right elements
With the appropriate browsers selected, it's time to collect references to the various LI
s.
The page may contain a number of LI
s, but, for this example, only ones within the DIV
called “news” are needed, so that element, and its contents, are isolated:
var sObj = document.getElementById('news')
This associates the DIV
containing the LI
s with the variable sObj
. With that variable, the LI
s can be gathered into an array:
var tag = sObj.getElementsByTagName('LI')
Collecting the information
The next step is to cycle through each LI
in the array, creating a new text object filled with the content from the element's title
:
for(x=0;x<tag.length;x++) var value = document.createTextNode(tag[x].title)
(An alternate to tag[x].title
would be tag[x].getAttribute('title')
.)
Displaying the content
A new SPAN
element will be created to hold the title
's content:
var wrap = document.createElement('SPAN')
That content, held in the value
variable filled earlier, is placed within the newly created element using appendChild
:
wrap.appendChild(value)
Finally, this new node is placed within the appropriate LI
:
tag[x].appendChild(wrap)
Styling the content
Like the other elements on the page, this newly created node can be styled by setting the style
attribute:
wrap.setAttribute('style','color: #F00;')
Unfortunately Internet Explorer on Windows doesn't recognize styles created using setAttribute
so, for that browser, a Microsoft-specific DOM method must be used:
var agt = navigator.userAgent.toLowerCase();if((agt.indexOf('msie')!=-1) && (agt.indexOf('win')!=-1)){ document.styleSheets[0].addRule('#news LI SPAN','color: #F00;')} else { wrap.setAttribute('style','color: #F00;') }
If you have a browser that supports these methods, you can see this script in action.
One generic script
Since this script could be used to pull any attribute information from any element, it makes sense to make the script more universal. So, the previous steps have been combined, with minor alterations, into one generic function.
Here are the variables used in the function (called “writeAttribute”) mapped to the values from this example:
Variable | Description | Example |
---|---|---|
i | element's id | news |
sT | source tag | LI |
sA | source attribute | title |
nT | new, created tag | SPAN |
nA | new, created attribute | style |
nAv | value for the new attribute | color: #F00; |
The full script with alterations
One note: the last else if
is for Opera 5 and 6 only, and can be safely deleted. The section writes a style rule so Opera can use CSS to duplicate what the script does with the DOM. This additionally functionality will only work in Opera if the new, created attribute (nA
) has a value of style
.
function writeAttribute(i,sT,sA,nT,nA,nAv){ var d = document; var agt = navigator.userAgent.toLowerCase(); if((d.createElement) && (d.createTextNode)){ var sObj = d.getElementById(i); var tag = sObj.getElementsByTagName(sT); for(x=0;x<tag.length;x++){ var value = d.createTextNode(' '+tag[x].getAttribute(sA)); var wrap = d.createElement(nT); wrap.appendChild(value); tag[x].appendChild(wrap); if((nA='style') && (agt.indexOf('msie')!=-1) && (agt.indexOf('win')!=-1) && (parseInt(navigator.appVersion)==4)) d.styleSheets[0].addRule('#'+i+' '+sT+' '+nT,nAv); else wrap.setAttribute(nA,nAv); } } else if((agt.indexOf("opera")!=-1) && (nA="style")){ d.write("<style type=\"text\/css\" media=\"screen\">"+ "#"+i+" "+sT+"["+sA+"]:after { content: ' 'attr("+sA+")''; "+nAv+"; }"+ "</style>") }}
Putting writeAttribute
to work
Because the function reads the elements within the document, it can't be called from within the head
. To keep the page organized, place the writeAttribute
call immediately after the elements you want to access, and fill in the relevant variables:
<div id="news">...</div><script type="text/javascript"><!-- writeAttribute('news','LI','title','SPAN','style','color: #F00')//--></script>
Growing the code
This is just one example of how the DOM can be used to access previously unavailable elements of a Web page. With some imagination, the writeAttribute
function could be used to add images or create CSS-based rollover effects using the information already contained within a page.