Reputation: 52942
Looking to create a list like this:
1. Section Header
1.1 Some Text Here That is Quite Long
1.2 Some Text Here That is Quite Long
1.3 Some Text Here That is Quite Long
2. Section Header
2.1 Some Text Here That is Quite Long
2.2 Some Text Here That is Quite Long
2.3 Some Text Here That is Quite Long
but ideally as a proper or combination thereof (I like to have neat proper pages). Is this possible?
Upvotes: 3
Views: 5128
Reputation: 10795
Here's a JavaScript solution for browsers that don't fully support CSS2. I've tested it in Firefox 3.5, IE6, IE7, IE8 and Chrome 4.0. I've written a pure JavaScript version and an equivalent jQuery (1.4!) version which, as you can imagine, is much shorter.
The benefit to using JavaScript is that it is much more customizable than CSS. For example, the JavaScript solution allows for interspersed content (i.e. You can have multiple <ol>
s inside a single parent <li>
and the numbering will be continuous regardless of what HTML you put in between the child <ol>
s. (See the demo)).
One drawback is that selecting the text in the JavaScript list will select the numbers as well as the text (the CSS solution helpfully omits the numbers from the selection).
http://jsbin.com/unujo (editable via http://jsbin.com/unujo/edit)
http://jsbin.com/ekono (editable via http://jsbin.com/ekono/edit)
(function ($) {
$.fn.addNumbering = function (separator, parentNumbering) {
var root = !parentNumbering;
parentNumbering = parentNumbering || '';
separator = separator || '.';
$.each(this, function () {
var items = root ? $(this).children() : this;
items.each(function (ii, item) {
var numberingText = parentNumbering + (ii + 1) + separator;
// We don't add numbering to root list items since
// the CSS already does that correctly.
if (!root) {
$('<span></span>', {
text: numberingText,
className: 'numbering'
}).prependTo(this);
}
$.fn.addNumbering.call([$(this).find('>ol>li')], separator, numberingText);
});
});
}
})(jQuery);
$('.numbered').addNumbering();
function addNumbering(list, separator, parentNumbering) {
var root = !parentNumbering;
parentNumbering = parentNumbering || '';
separator = separator || '.';
// If 'list' is an Array, assume we were given a
// collection of ordered lists and call addNumbering on each
if (Object.prototype.toString.call(list) === "[object Array]") {
each(
list,
function (list, ii) {
addNumbering(list, separator, parentNumbering);
}
);
return;
}
var
listItem = function (childNode) {
// Ignore text nodes. We assume that
// the HTML follows standards so all the
// remaining nodes should be list items.
return childNode.nodeType === 1;
},
items = select(list.childNodes, listItem);
each(
items,
function (item, ii) {
var numberingText = parentNumbering + (ii + 1) + separator;
// We don't add numbering to root list items since
// the CSS already does that correctly.
if (!root) {
var numbering = document.createElement('span');
numbering.innerHTML = numberingText;
numbering.className = 'numbering';
item.insertBefore(numbering, item.childNodes[0]);
}
var
subLists = select(
item.childNodes,
function (childNode) {
return childNode['tagName'] && childNode.tagName.toLowerCase() === 'ol';
}
),
subListItemWrapper = {childNodes: []};
each(
subLists,
function (subList) {
subListItemWrapper.childNodes =
subListItemWrapper.childNodes.concat(select(
subList.childNodes,
listItem
));
}
);
addNumbering(subListItemWrapper, separator, numberingText);
}
);
}
function select (things, selectFunction) {
if (Array.filter) {
return Array.prototype.slice.call(things, 0).filter(selectFunction);
}
var selected = selected || [];
each (
things,
function (thing) {
selectFunction(thing) && selected.push(thing);
}
);
return selected;
}
function each (things, eachFunction) {
if (Array.forEach) {
things.forEach(eachFunction);
return;
}
var numThings = things.length, ii;
for (ii = 0; ii < numThings; ii++) {
eachFunction(things[ii], ii, things);
}
}
addNumbering(select(
document.body.childNodes,
function (childNode) {
return childNode.nodeType === 1 && childNode.className.indexOf('numbered') !== -1;
}
));
<!doctype html>
<html lang="en">
<head>
<title></title>
<meta http-equiv="Content-type" content="text/html; charset=utf-8" />
<style type="text/css" media="screen">
body { background-color: #000; font: 16px Helvetica, Arial; color: #fff; }
.numbering { padding: 0 0.8em 0 1.2em; }
.numbered ol { list-style-type: none; }
.numbered > li > ol { padding-left: 0; }
</style>
</head>
<body>
<ol>
<li>This</li>
<li>is a
<ol>
<li>vanilla</li>
<li>list</li>
</ol>
</li>
</ol>
<ol class="numbered">
<li>This is a numbered list</li>
<li>Vestibulum auctor dapibus neque.
<ol>
<li>Lorem ipsum dolor sit amet, consectetuer adipiscing elit.</li>
<li>Aliquam tincidunt mauris eu risus.</li>
</ol>
It even handles interspersed content! Note that he numbering continues where it left off:
<ol>
<li>Lorem ipsum dolor sit amet, consectetuer adipiscing elit.</li>
<li>Aliquam tincidunt mauris eu risus.</li>
</ol>
</li>
</ol>
<ol class="numbered">
<li>This is another numbered list</li>
<li>Aliquam tincidunt mauris eu risus.</li>
<li>Vestibulum auctor dapibus neque.
<ol>
<li>Lorem ipsum dolor sit amet, consectetuer adipiscing elit.</li>
<li>Aliquam tincidunt mauris eu risus.</li>
<li>Vestibulum auctor dapibus neque.
<ol>
<li>Lorem ipsum dolor sit amet, consectetuer adipiscing elit.</li>
<li>Aliquam tincidunt mauris eu risus.</li>
</ol>
</li>
<li>Aliquam tincidunt mauris eu risus.</li>
<li>Vestibulum auctor dapibus neque.</li>
</ol>
</li>
<li>Aliquam tincidunt mauris eu risus.</li>
<li>Vestibulum auctor dapibus neque.</li>
<li>Aliquam tincidunt mauris eu risus.</li>
<li>Vestibulum auctor dapibus neque.</li>
</ol>
</body>
</html>
Upvotes: 3
Reputation: 790
Use CSS.
http://www.webmaster-talk.com/css-forum/151861-ol-css-4-1-2-formatting.html
http://www.w3.org/TR/CSS2/generate.html
Upvotes: 10