Why do the elements lose their offset between themselves after restoration?
I am trying to implement bookmark objects for my site and testing this:
<html>
<head>
<title>test bookmark</title>
<script type='text/javascript' src='libs/bookmarks.js'></script>
</head>
<body>
<input type = "text" id = "txt_id" />
<input type = "button" value = "create bk" onclick = "createBookmark();" />
<input type = "button" value = "restore bk 0" onclick = "restoreBookmarkNumber(0);" />
</body>
</html>
bookmarks.js:
function Bookmark(of_elem, name)
{
this.name = name;
this.of_elem = of_elem;
this.elems = new Array();
for (var i = 0; i < of_elem.children.length; i++)
this.elems.push(of_elem.children[i].cloneNode(true));
return this;
};
Bookmark.prototype.restore = function ()
{
while (this.of_elem.hasChildNodes())
this.of_elem.removeChild(this.of_elem.lastChild);
for (var i = 0; i < this.elems.length; i++)
this.of_elem.appendChild(this.elems[i].cloneNode(true));
};
var bookmarks = new Array();
function createBookmark()
{
var name = prompt("Enter bookmark name", "Bookmark " + bookmarks.length);
var bk = new Bookmark(document.body, name);
bookmarks.push(bk);
}
function restoreBookmarkNumber(num)
{
var bk = bookmarks[num];
if (bk)
bk.restore();
}
For some strange reason, the space between the textbox and the buttons disappears after the bookmark is restored, but I don't understand why this is happening. I have clearly cloned all the elements, so what else is needed?
source to share
In places where you use children
, not childNodes
(like a constructor Bookmark
), you only deal with the children of element (since the point is children
against childNodes
). Use childNodes
everywhere to ensure that text nodes are retained between elements, as text nodes between elements can be significant (for example, for spacing).
Your original, which is losing spacing:
function Bookmark(of_elem, name)
{
this.name = name;
this.of_elem = of_elem;
this.elems = new Array();
for (var i = 0; i < of_elem.children.length; i++)
this.elems.push(of_elem.children[i].cloneNode(true));
return this;
};
Bookmark.prototype.restore = function ()
{
while (this.of_elem.hasChildNodes())
this.of_elem.removeChild(this.of_elem.lastChild);
for (var i = 0; i < this.elems.length; i++)
this.of_elem.appendChild(this.elems[i].cloneNode(true));
};
var bookmarks = new Array();
function createBookmark()
{
var name = prompt("Enter bookmark name", "Bookmark " + bookmarks.length);
var bk = new Bookmark(document.body, name);
bookmarks.push(bk);
}
function restoreBookmarkNumber(num)
{
var bk = bookmarks[num];
if (bk)
bk.restore();
}
<html>
<head>
<title>test bookmark</title>
<script type='text/javascript' src='libs/bookmarks.js'></script>
</head>
<body>
<input type = "text" id = "txt_id" />
<input type = "button" value = "create bk" onclick = "createBookmark();" />
<input type = "button" value = "restore bk 0" onclick = "restoreBookmarkNumber(0);" />
</body>
</html>
Updated to use childNodes
instead of children
in Bookmark
, which doesn't lose spacing:
function Bookmark(of_elem, name)
{
this.name = name;
this.of_elem = of_elem;
this.elems = new Array();
for (var i = 0; i < of_elem.childNodes.length; i++)
this.elems.push(of_elem.childNodes[i].cloneNode(true));
return this;
};
Bookmark.prototype.restore = function ()
{
while (this.of_elem.hasChildNodes())
this.of_elem.removeChild(this.of_elem.lastChild);
for (var i = 0; i < this.elems.length; i++)
this.of_elem.appendChild(this.elems[i].cloneNode(true));
};
var bookmarks = new Array();
function createBookmark()
{
var name = prompt("Enter bookmark name", "Bookmark " + bookmarks.length);
var bk = new Bookmark(document.body, name);
bookmarks.push(bk);
}
function restoreBookmarkNumber(num)
{
var bk = bookmarks[num];
if (bk)
bk.restore();
}
<html>
<head>
<title>test bookmark</title>
<script type='text/javascript' src='libs/bookmarks.js'></script>
</head>
<body>
<input type = "text" id = "txt_id" />
<input type = "button" value = "create bk" onclick = "createBookmark();" />
<input type = "button" value = "restore bk 0" onclick = "restoreBookmarkNumber(0);" />
</body>
</html>
source to share