0

自分用に小さな演習を設定して、基本的な JS スキルを練習しています。この例では<a>、div 内に s のリストがあります。演習の目的は、それぞれ<a>を div でラップすることです。この場合に使用replaceChildしています。

奇妙なことに (少なくとも私にとっては) スクリプトは最初の 3 つのリンクに対して機能しますが、その後はエラーがスローされます。

キャッチされていない TypeError: 未定義のプロパティ 'parentNode' を読み取ることができません

スクリプトが部分的に機能する理由がわかりません。ここで私が間違っていることを誰かが見ることができますか? 私が使用しているコードは次のとおりです。

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">

<style media="all">
div div {padding: 10px; background: #e7e7e7; margin: 5px;}
</style>

</head>
<body>

<div>
    <a href="">link</a>
    <a href="">link</a>
    <a href="">link</a>
    <a href="">link</a>
    <a href="">link</a>
    <a href="">link</a>
</div>

<script>
var links = document.getElementsByTagName("a");
for (var i=0, ii=links.length; i<ii; i++) 
{
    var container = document.createElement("div");
    links[i].parentNode.replaceChild(container, links[i]);
    container.appendChild(links[i]);
}
</script>

</body>
</html>

オンライン版はこちら: http://codepen.io/anon/pen/Lpuky

このエラー メッセージについて知っていて読んだいくつかのデバッグ手法を試しましたが、何が問題なのかわかりませんでした。6 つのリンクのうち 3 つが機能するのはおかしいと思います。

4

4 に答える 4

4

コレクションlinksライブNodeListです。

それらを置き換えているため、それらはコレクションから消えており、それらへのインデックスは何も指していません。

于 2013-05-08T04:02:53.627 に答える
2

ノードリストを反復しながらノードリストを変更しています。リストのコピーを作成するには、Array スライス メソッドを使用します。

var linksCopy = Array.prototype.slice.call(links);
for (var i=0; i<linksCopy.length; i++) 
{
    var container = document.createElement("div");
    linksCopy[i].parentNode.replaceChild(container, linksCopy[i]);
    container.appendChild(linksCopy[i]);
}
于 2013-05-08T04:05:03.523 に答える
1

これのフォローアップとして、querySelectorAll()配列ではなく静的な Nodelist を返すという点で違うとよく耳にします。

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">

<style media="all">
div div {padding: 10px; background: #e7e7e7; margin: 5px;}
</style>

</head>
<body>

<div>
    <a href="">link</a>
    <a href="">link</a>
    <a href="">link</a>
    <a href="">link</a>
    <a href="">link</a>
    <a href="">link</a>
</div>

<script>
var links = document.querySelectorAll("a");
for (var i=0, ii=links.length; i<ii; i++) 
{
    var container = document.createElement("div");
    links[i].parentNode.replaceChild(container, links[i]);
    container.appendChild(links[i]);
}
</script>

</body>
</html>

また、代替手段Array.prototype.slice.call(links)は次の[].slice.call(links)とおりです。

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">

<style media="all">
div div {padding: 10px; background: #e7e7e7; margin: 5px;}
</style>

</head>
<body>

<div>
    <a href="">link</a>
    <a href="">link</a>
    <a href="">link</a>
    <a href="">link</a>
    <a href="">link</a>
    <a href="">link</a>
</div>

<script>
var links = document.getElementsByTagName("a");
var linksCopy = [].slice.call(links);
for (var i=0; i<linksCopy.length; i++) 
{
    var container = document.createElement("div");
    linksCopy[i].parentNode.replaceChild(container, linksCopy[i]);
    container.appendChild(linksCopy[i]);
}
</script>

</body>
</html>

また、別のオプションは次を使用すること[].forEach.call()です。

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">

<style media="all">
div div {padding: 10px; background: #e7e7e7; margin: 5px;}
</style>

</head>
<body>

<div>
    <a href="">link</a>
    <a href="">link</a>
    <a href="">link</a>
    <a href="">link</a>
    <a href="">link</a>
    <a href="">link</a>
</div>

<script>
[].forEach.call(document.querySelectorAll('a'), function(el) {
var container = document.createElement("div");
el.parentNode.replaceChild(container, el);
container.appendChild(el);
});
</script>

</body>
</html>

Array.from() を使用したさらに別のオプション:

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">

<style media="all">
div div {padding: 10px; background: #e7e7e7; margin: 5px;}
</style>

</head>
<body>

<div>
    <a href="">link</a>
    <a href="">link</a>
    <a href="">link</a>
    <a href="">link</a>
    <a href="">link</a>
    <a href="">link</a>
</div>

<script>
var links = document.getElementsByTagName("a");
var linksCopy = Array.from(links);
for (var i=0; i<linksCopy.length; i++)
{
    var container = document.createElement("div");
    linksCopy[i].parentNode.replaceChild(container, linksCopy[i]);
    container.appendChild(linksCopy[i]);
}
</script>

</body>
</html>
于 2013-12-06T05:32:25.300 に答える
1

あなた自身のフォローアップの答えについて:あなたの目的が、 、または他の方法で練習するのではなく、単に<a>s をs でラップする最も簡単な方法を見つけることであった場合、これは次のようになります。<div>createElementreplaceChildappendChild

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
    <title>Demo</title>
<style>
div div {
    padding: 10px;
    background: #e7e7e7;
    margin: 5px;
}
</style>
</head>
<body>

    <div>
        <a href="#">link</a>
        <a href="#">link</a>
        <a href="#">link</a>
        <a href="#">link</a>
        <a href="#">link</a>
        <a href="#">link</a>
    </div>

<script>
var links = document.querySelectorAll("a");
for (var i=0; i<links.length; i++) {
    links[i].outerHTML = '<div>'+links[i].outerHTML+'</div>';
}
</script>
</body>
</html>

.
ライブデモはこちら: http://jsbin.com/jasoho/1/edit?html,output . outerHTMLこの方法のもう 1 つの利点は、 nodeList. getElementsByTagNameそのため、代わりに を使用することもできますquerySelectorAll

于 2014-07-10T13:07:08.930 に答える