为什么我得到此输出? (jQuery .append()问题)

时间:2018-12-07 11:37:24

标签: javascript jquery append

为什么append在这里的表现大不相同。.任何人都可以解释一下!

最近在练习jQuery时被卡在这里,不明白发生了什么:在第一个按钮上单击,元素按预期正常添加,但是在第二次单击上/之后,事物(输出)开始变得怪异。有人可以解释一下这里发生了什么吗?
我是jQuery新手。谢谢与和平:)

function appendText() {
  var txt1 = "<p id='set'>Text1</p>";
  console.log("Text1", txt1);

  var txt2 = $("<p></p>").text("Text2");
  console.log("Text2", txt2);

  var txt3 = document.createElement("p");
  txt3.innerHTML = "Text3";
  console.log("Text3", txt3);

  var txt4 = $("#set").html("Text4");
  console.log("Text4", txt4);

  $("body").append(txt1, txt2, txt3, txt4);
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>

<p>Append Test Example</p>
<button onclick="appendText()">Append text</button>

Output Image

4 个答案:

答案 0 :(得分:1)

尝试一下?

var ourButton = document.getElementById("btn");
    
var ourList = document.getElementById("our-list");

ourButton.addEventListener("click",func2);

newAddedText = 1;

function func2() {
  ourList.innerHTML += "<li>anything " + newAddedText + "</li>";
  newAddedText++;
}
<button id="btn">Add New</button>
<ul id="our-list">
</ul>

答案 1 :(得分:1)

首先,id在文档中必须是唯一的。请改用class。另外,不必要地混合使用JavaScript和jQuery也不是一个好习惯。

第二次追加时,('#set')实际上会找到第一个匹配的元素,该元素已由第一次单击按钮追加,并更改了它的html。不必使用 class 引用元素,而必须使用包含元素的变量。

更改

var txt4 = $('#set').html("Text4");

收件人

var txt4 = $(txt1).html("Text4");

function appendText() {
  var txt1 = "<p class='set'>Text1</p>";

  var txt2 = $("<p></p>").text("Text2");
  var txt3 = document.createElement("p");
  txt3.innerHTML = "Text3";

  var txt4 = $(txt1).html("Text4");

  $("body").append(txt1, txt2, txt3, txt4);
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>

<p>Append Test Example</p>
<button onclick="appendText()">Append text</button>

答案 2 :(得分:1)

我在您的示例中添加了一个计数器,可让您更轻松地了解此处的情况。每行输出中括号中的数字表示创建该行的按钮单击。

let counter = 0;

function appendText() {
  counter++;

  let txt1 = `<p id="set">Text1 (${counter})</p>`;
  console.log('Text1', counter, txt1);

  let txt2 = $('<p></p>').text(`Text2 (${counter})`);
  console.log('Text2', counter, txt2);

  let txt3 = document.createElement('p');
  txt3.innerHTML = `Text3 (${counter})`;
  console.log('Text3', counter, txt3);

  let txt4 = $('#set').html(`Text4 (${counter})`);
  console.log('Text4', counter, txt4);

  $('body').append(txt1, txt2, txt3, txt4);
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>

<p>Append Test Example</p>
<button onclick="appendText()">Append text</button>

点击1:

<p id="set">Text1 (1)</p>
<p>Text2 (1)</p>
<p>Text3 (1)</p>

但是没有Text4!返回到用于创建txt4的表达式:

$('#set').html(`Text4 (${counter})`)

这不是在创建 new 元素,而是从文档中获取 existing 元素。 匹配Text1 (1),但该元素尚未写入文档。

点击2:

<p>Text2 (1)</p>
<p>Text3 (1)</p>

<p id="set">Text1 (2)</p>
<p>Text2 (2)</p>
<p>Text3 (2)</p>
<p id="set">Text4 (2)</p>

现在Text1 (1)存在,因此txt4选择器可以检索它。

由于txt4是通过获取现有#set元素创建的,因此使用id等于set的第一个元素:<p id="set">Text1 (1)</p>。此时,一些潜在的意外jQuery行为开始起作用:当附加文档中已经存在的元素https://github.com/manoelcampos/cloudsim-plus时。

点击3:

<p>Text2 (1)</p>
<p>Text3 (1)</p>

<p>Text2 (2)</p>
<p>Text3 (2)</p>
<p id="set">Text4 (2)</p>

<p id="set">Text1 (3)</p>
<p>Text2 (3)</p>
<p>Text3 (3)</p>
<p id="set">Text4 (3)</p>

在此点击之前,我们发生了 id冲突(请参见上一小节)。回想一下it’s removed from its original location first应该是唯一的(强调我的意思):

  

id全局属性定义一个唯一标识符(ID),该标识符在整个文档中必须是唯一的。

由于您的文档不再是有效的HTML,因此我们进入了未定义行为的世界。 JS调用其id属性来查找元素可能会返回带有该id的任何元素。在我的浏览器(可能还有许多其他浏览器)中,第一个返回。

就像单击2一样,具有id set的元素将从文档中删除,用作新的txt4。在这种情况下,这是第一个:<p id="set">Text1 (2)</p>

点击n:

从这一点开始,图案重复出现。每次单击都会删除带有id set的第一个元素,但又添加两个。

答案 3 :(得分:0)

好吧,看来您正在混合不同的东西。头三个txt变量就可以了,您可以通过不同的方式创建HTML元素以将其附加到HTML文档中。但是,让我们看一下这一行;

var txt4 = $("#set").html("Text4");

这是问题所在。您正在选择其ID为set(即txt1)的元素,并将其内部HTML更改为仅“文本4”,然后将该操作的结果(无)附加到您的HTML。

如果删除该行,则一切正常,但是对于该行,这就是发生的情况:

第一步

单击附加文本,由于没有添加任何元素,因此将附加以下内容:

<p id="set">Text1</p> <--- txt1
<p>Text2</p>          <--- txt2
<p>Text3</p>          <--- txt3

由于txt4不返回任何内容,因此未添加其他任何内容

第二步

再次单击按钮,然后:

----------- previous step --------------
<p id="set">Text1</p> <--- txt1
<p>Text2</p>          <--- txt2
<p>Text3</p>          <--- txt3
----------- current step ---------------
<p id="set">Text1</p> <--- txt1
<p>Text2</p>          <--- txt2
<p>Text3</p>          <--- txt3

您预计会发生这种情况,但是由于您有txt4变量更改了<p id='set'>元素,因此实际发生的是:

----------- previous step --------------
<p id="set">Text4</p> <--- txt1 BUT changed by txt4
<p>Text2</p>          <--- txt2
<p>Text3</p>          <--- txt3
----------- current step ---------------
<p id="set">Text1</p> <--- txt1
<p>Text2</p>          <--- txt2
<p>Text3</p>          <--- txt3

新的Text1 <p>保持不变,因为在txt4中选择它时,它尚不存在。

如果除了最后一行外,您对代码没有任何更改:

From this
$("body").append(txt1, txt2, txt3, txt4);

To this
$("body").append(txt1, txt2, txt3);

Yoy将完全复制我在这里写的内容。如果还附加txt4,则<p>元素将获得“随机播放”。我怀疑是因为txt4包含jQuery,因为html function作为setter会返回该值。