The One with the Thoughts of Frans

Add Show or Hide Deleted Text Button

For an upcoming post, I used the DEL element quite extensively. I figured that, while potentially interesting, it would help readability to be able to temporarily remove them from display, so I wrote this little script. Incidentally, it was the first time in about three years—meaning the first time since I finished the layout and scripts when I started this blog—that I added any new scripts, or even edited the file containing them. While I am probably far from the most suitable person for this job, I decided to write a little tutorial, explaining what I used and why I used it.

I’ll start by dropping a major bomb. Here is the script.

// Checks if there is deleted text in post entries. Adds a Show or hide deleted text button if there is.
// Copyright © Frans de jonge 2009. Licensed under a Creative Commons Atrribution 2.0 license.
function AddShowHideDeletedTextButton() {
	var postEntries = document.getElementsByClassName('postentry');
	var postEntry = postEntries[0];
	if ( postEntries.length == 1 && postEntry.getElementsByTagName('del').length > 0 ) {
		var hideText = 'Hide deleted text', showText = 'Show deleted text';
		var button = document.createElement('input');
		button.setAttribute('type', 'button');
		button.setAttribute('value', hideText);
		button.addEventListener('click',
		function () {
			var e = postEntry.getElementsByTagName('del');
			for ( var i = 0; i<e.length; i++ ) {
				if (e[i].style.display == 'none') {
					e[i].style.display = 'inline';
					this.setAttribute('value', hideText);
				}
				else {
					e[i].style.display = 'none';
					this.setAttribute('value', showText);
				}
			}
		}
		,false);
		postEntry.insertBefore(button,postEntry.firstChild);
	}
}

I’m going to assume that you have at least a basic understanding of functions and variables, but may not be completely aware of DOM methods and how to use them. A very valuable resource is the Mozilla Developer Center, or MDC. It provides information on much more than just JavaScript and the DOM, but while I find the CSS and even HTML specifications fairly easy to get around in, the DOM specifications, with their language neutral, very extensive descriptions are quite hard in comparison. They are exactly the way they ought to be, but this makes it somewhat hard to find relevant information about actual usage and how to use it. That’s where the MDC comes in. It typically comes with a clear, concise summary at the top of the page, and if you don’t understand that, it usually comes with more extensive code samples as well.

	var postEntries = document.getElementsByClassName('postentry');
	var postEntry = postEntries[0];
	if ( postEntries.length == 1 && postEntry.getElementsByTagName('del').length > 0 ) {

DOM methods used:

In my blog, I have marked up all of the contents of my posts with a DIV element, with, as you might have guessed, a class postentry. This particular bit of code is meant to make sure that we are on the individual page of the post (i.e. not in some kind of overview) and that there are actually deleted elements around. Adding a button on an overview page would result in all kinds of problems—if you add only one it may not be anywhere near where it is needed, so you’d have to add multiple buttons, check if the post where it will be added has deleted elements, etc.—which are easy to avoid by keeping it restricted to one post.

		var button = document.createElement('input');
		button.setAttribute('type', 'button');
		button.setAttribute('value', hideText);

DOM methods used:

Here we see the proper way to create an element through the DOM. First we create an element, in this case input, and then we set a few attributes to the values we want. Note that I defined hideText earlier, with the value Hide deleted text.

		button.addEventListener('click',
		function () {
			var e = postEntry.getElementsByTagName('del');
			for ( var i = 0; i<e.length; i++ ) {
				if (e[i].style.display == 'none') {
					e[i].style.display = 'inline';
					this.setAttribute('value', hideText);
				}
				else {
					e[i].style.display = 'none';
					this.setAttribute('value', showText);
				}
			}

DOM methods used:

Here we definitely have one of the more interesting parts of the code. Had I written this script about 8 years ago, I would have used something like var button = '<input type="button" value='+hideText+'>' and consequently added an eventListener like button.onclick = someFunction;, where someFunction would be separately defined. I am using the proper DOM method instead. This may cause problems in IE, for which there are fixes available, but since this blog is strictly personal I decided not to care about that. Notice how I did not define the function separately, but included it as an anonymous function. Since the function is not intended to be used anywhere else, it’s easier, and, ideally, it will be completely removed from memory if the button were to be removed.

The element.style property allows you to access and change style properties on an element. As the MDC says, It is generally better to use the style property than to use elt.setAttribute('style', '...'), since use of the style property will not overwrite other CSS properties that may be specified in the style attribute. I may not be defining any other styles on DEL elements yet, but this way the script won’t break my site if I do add some more style to it in the future, or if someone else wishes to adapt it for use on their own page.

		postEntry.insertBefore(button,postEntry.firstChild);

DOM methods used:

To finish it off, we’ve got the insertBefore construct. It inserts a node as a child of the node to which it is applied, before a specified other child of this parent node. When I first came across it a few years ago, I thought it was somewhat confusing at first. It should be noted that node means much more than element, but in these specific examples it shouldn’t matter, so I didn’t go into it. If you wish to learn more, I recommend you try the MDC or a search engine.

In conclusion, I hope this helped someone out there a bit. I thought it was interesting to reminisce about how I would have written this script if it were 2003.

Leave a Comment

You must be logged in to post a comment.