为什么修复后的元素会在彼此之间失去相互抵消?

时间:2014-12-23 14:49:17

标签: javascript html clone

我正在尝试为我的网站实现书签并对其进行测试:

<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();
}

出于一些奇怪的原因,书签恢复后文本框和按钮之间的空间消失了,但我不明白为什么会这样。我清楚地克隆了所有元素,那么还需要什么呢?enter image description here

1 个答案:

答案 0 :(得分:2)

在您使用children而不是childNodes的地方(例如Bookmark构造函数)中,您只处理元素子项(因为这是childrenchildNodes的关键点。始终使用childNodes以确保维护元素之间的文本节点,因为元素之间的文本节点可能很重要(例如,用于间距)。

您的原件丢失了间距:

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>

更新为在childNodes中使用children代替Bookmark,但不会丢失间距:

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>