Comments are recommended practice in programming and software development in general, they can state a reason why a coding decision was taken or explain what needs to be done to improve the code you are working on.
HTML might not be considered as a programming language but it sure has comments. In HTML comments are mostly used to indicate segments of code like the header, sidebar or custom components.
Comments don't show up in your HTML (as in any language that has comments) but, you can display them on the page for debugging purposes.
Let's find out how we can actually pull this off.
HTML tags (including HTML comments) are represented as nodes in the DOM tree and each node has nodeType
property which is a numerical value that identifies the type of node.
In order to get the numerical value, the format is node.nodeType
where node is an HTML element. The numerical value is a value greater than 1
.
The table below lists the possible return values.
Value | Meaning |
---|---|
1 | ELEMENT_NODE |
2 | ATTRIBUTE_NODE |
3 | TEXT_NODE |
4 | CDATA_SECTION_NODE |
5 | ENTITY_REFERENCE_NODE |
6 | ENTITY_NODE |
7 | PROCESSING_INSTRUCTION_NODE |
8 | COMMENT_NODE |
9 | DOCUMENT_NODE |
10 | DOCUMENT_TYPE_NODE |
11 | DOCUMENT_FRAGMENT_NODE |
12 | NOTATION_NODE |
From the table above its evident that HTML comments have a numerical value of 8
, this is the crucial requirement to actually get the comment and then show it on any part of the page.
The other requirement is the data
value. The data
as the name implies is the content of the node.
Here is the HTML code:
<noscript style="color: red; text-align: center; text-decoration: underline;">
<p>The core functionality of this app requires
JavaScript to work. Please enable JavaScript</p>
</noscript>
<div class="container">
<!-- Information -->
<div class="show" id="comments_section">
<button class="btn remove-paragraph" id="remove-paragraph" title="Close"></button>
<p id="number_of_comments"></p>
<button id ="view_comments" class="btn success">Yes</button>
<button id ="dont_view_comments" class="btn">No</button>
<button class="btn success" id="show_comments">Show Comments</button>
<button class="btn" id="hide_comments">Hide Comments</button>
<div id="commentsInCode">
<h2 style="display: none;" id="comment_subheading">Comments in your code</h2>
</div>
</div>
<!-- A dummy text -->
<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod
tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam,
quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo
consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse
cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non
proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</p>
</div>
<script>
// JS code here
</script>
And the CSS:
p {
font-weight: bold;
line-height: 1.618;
font: 18px Georgia;
}
pre {
font-weight: bold;
text-decoration: underline;
font-family: Georgia;
}
.container {
width: 70%;
margin: 0 auto;
}
.form__label {
display: block;
margin-bottom: 0.6em;
}
.btn {
border: none;
padding: 1.2em;
background-color: #cd5b45;
color: #ffffff;
}
.btn.success {
background-color: green;
}
.btn:hover {
cursor: pointer;
}
.hidden {
display: none;
}
.show {
display: block;
}
#comments_section {
border: 2px solid #1560bd;
box-shadow: -3px 3px #1560bd;
padding: 1.2em;
position: relative;
}
.remove-paragraph {
padding: 0.8em;
position: absolute;
top: 0em;
right: 0em;
border: 50%;
}
.remove-paragraph:hover {
cursor: pointer;
font-weight: bold;
}
.remove-paragraph::before {
content: 'x';
}
#commentsInCode {
background-color: #cccccc;
}
#commentsInCode pre {
padding: 1em;
}
#commentsInCode h2 {
text-align: center;
}
.hidden {
display: none;
}
.show {
display: block;
}
Taking a look at the HTML, you'll notice we use id's
. The first thing we'll do in our script is to create variables. Among the variables is an accumulator that'll keep track of the comments found in the code segment.
/**
* querySelector. jQuery style
* Inspiration from Todd Motto
* https://ultimatecourses.com/blog/attaching-event-handlers-to-dynamically-created-javascript-elements
*/
let $ = function (selector) {
return document.querySelector(selector);
};
// variables
let container = $('.container');
let comments_section = $('#comments_section');
let dont_view_comments = $('#dont_view_comments');
let view_comments = $('#view_comments');
let number_of_comments = $('#number_of_comments');
let hide_comments = $('#hide_comments');
let show_comments = $('#show_comments');
let remove_paragraph = $('#remove-paragraph');
let commentsInCode = $('#commentsInCode');
let comment_subheading = $('#comment_subheading');
let accumulator = 0;
We need to know the number of comments, therefore, we loop through the childNodes
and when we encounter a nodeType
with a value of 8
we increment the accumulator.
for (let i = 0; i < container.childNodes.length; i++) {
// save the childnode in a variable for
// easy referencing
let e = container.childNodes[i];
if (e.nodeType === 8) { // we found a comment!
// increment the accumulator
accumulator += 1;
// show the comments section
comments_section.style.display = "block";
}
}
We gladly tell the user the number of comments.
// Tell the user the number of comments found
number_of_comments.innerHTML =
"<p>We found " + accumulator + " comment(s) in the selected
section of code, will you like to see them?";
On initial page load we hide three HTML buttons:
show_comments
hide_comments
-
remove_paragraph
/**
* On initial page load, hide the "show",
* hide" remove paragraph buttons
*/
show_comments.classList.toggle('hidden');
hide_comments.classList.toggle('hidden')
remove_paragraph.classList.toggle('hidden');
We attach an event listener to the view comments button. Inside the event listener we loop through the childNodes
to find the comments then we create div
and pre
tag that will contain the data
. The pre
tag is then attached to the div
tag which in turn is attached to the page via the appendChild()
method and the comment subheading is shown.
The view_comments
and dont_view_comments
are hidden then we show the hide_comments
and remove_paragraph
buttons.
view_comments.addEventListener('click', function() {
// loop through the childnodes
for (let i = 0; i < container.childNodes.length; i++) {
// save the childNodes in a variable
// for easy referencing
let e = container.childNodes[i];
if (e.nodeType === 8) { // we found a comment
/**
* create a text node with the "data",
* after which we create a div and pre
* elements.
*
* The data is attached to the pre tag
* and the pre tag to the created div
* which in turn is attached to a section
* on the page
*/
let text = document.createTextNode(e.data);
let div = document.createElement('div');
let pre = document.createElement('pre');
pre.appendChild(text);
div.appendChild(pre);
commentsInCode.appendChild(div);
comment_subheading.style.display = "block";
}
}
/**
* We are using four buttons to make things simple
* after the user click yes to view the comments
* we hide the "yes" and "no"buttons. Afterward,
* we show the "hide" and "remove" paragraph
* buttons
*/
view_comments.classList.toggle("hidden");
dont_view_comments.classList.toggle("hidden");
hide_comments.classList.toggle("show");
remove_paragraph.classList.toggle("show");
});
If the user prefers not to view the comments we close the comments section entirely:
// a button to close the comments section on initial
// page load
dont_view_comments.addEventListener('click', function() {
comments_section.style.display = 'none';
});
Once the user decides to see the comments, we toggle two buttons on and off when clicked by the user — the hide comments and show comments.
/**
* Add an event listener to the hide, show,
* dont view comments and view comments buttons
*/
hide_comments.addEventListener("click", function() {
commentsInCode.style.display = "none";
hide_comments.style.display = "none";
show_comments.style.display = "block";
});
show_comments.addEventListener("click", function() {
hide_comments.style.display = "block";
commentsInCode.style.display = "block";
show_comments.style.display = "none";
});
Finally, we provide an alternative for the user to close the entire comments section.
// a button to close the entire comments section
remove_paragraph.addEventListener("click", function() {
comments_section.style.display = "none";
});
The image below is an example of this code in action:
Limitations
This approach does not take comments in a child element into consideration. For example:
<div>
<!-- comment -->
<div class="child element">
<!-- This approach won't see this comment -->
</div>
</div>
Conclusion
This is useful for debugging purposes. The code is hacky but it works. It's up to you to improve the code or better still, turn it into a function that accepts a selector as an argument.
Reference
Have fun!
Top comments (2)
There's no point to this when you can just use element inspector to see the comments if you really need to see them.
It's up to you. The last time I checked there are varieties of ways to achieve a specific task.