Невозможно вставить элемент до и после (оба) в jQuery

#javascript #jquery #dom

#javascript #jquery #dom

Вопрос:

Я использую jQuery 3.x. Я пытаюсь добавить динамически созданный элемент до и после элемента, используя insertBefore() и insertAfter() . Однако insertBefore() работает только один, а другой игнорируется. Когда я комментирую один, тогда работает другой. почему?

 p = $("<p></p>").text("This is a dynamicly created element");
p.insertAfter($('nav'));
p.insertBefore($('nav'));  
 * {
  margin: 0;
  padding: 0;
  box-sizing: border-box;
  font-size: 20px;
}

header,
nav,
main,
aside,
footer {
  padding: 10px 15px;
  border: 1px solid mediumseagreen;
  text-align: center;
}

header {
  background: dodgerBlue;
}

nav {
  background: mediumSeaGreen;
}

main {
  background: #d3d3d3;
}

main,
aside {
  height: 1200px;
}

main {
  width: 80%;
  float: left;
}

aside {
  width: 20%;
  float: right;
}

div::after {
  content: " ";
  float: none;
  clear: both;
  display: table;
}

main {
  text-align: left;
}  
 <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<header>
  This is header
</header>

<nav>
  This is navbar
</nav>

<main>
  <article>
    <h2>This is heading</h2>
    <p>
      Lorem ipsum dolor sit amet consectetur adipisicing elit. Cum atque fuga, eos neque ipsum enim id inventore necessitatibus laboriosam quo nobis, repellendus maxime veritatis error ut expedita, velit aspernatur asperiores!
    </p>
  </article>
</main>

<aside>
  This is side bar
</aside>
<div></div>
<footer>
  This is <a href="http://">footer</a>
</footer>  

Ответ №1:

Проблема в том, что p ссылается только на один элемент. Вы вставляете его в DOM в insertAfter() вызове, затем перемещаете тот же элемент в новое местоположение, используя insertBefore() .

Чтобы сделать то, что вам требуется, вы можете clone() вставить элемент перед второй вставкой. Также обратите внимание, что вам не нужно создавать весь объект jQuery для выбора nav , вы можете просто передать селектор в виде строки. Попробуйте это:

 let p = $("<p />", { 
  text: "This is a dynamicly created element"
});
p.insertAfter('nav');
p.clone().insertBefore('nav');  
 * {
  margin: 0;
  padding: 0;
  box-sizing: border-box;
  font-size: 20px;
}

header,
nav,
main,
aside,
footer {
  padding: 10px 15px;
  border: 1px solid mediumseagreen;
  text-align: center;
}

header {
  background: dodgerBlue;
}

nav {
  background: mediumSeaGreen;
}

main {
  background: #d3d3d3;
}

main,
aside {
  height: 1200px;
}

main {
  width: 80%;
  float: left;
}

aside {
  width: 20%;
  float: right;
}

div::after {
  content: " ";
  float: none;
  clear: both;
  display: table;
}

main {
  text-align: left;
}  
 <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<header>This is header</header>
<nav>This is navbar</nav>
<main>
  <article>
    <h2>This is heading</h2>
    <p>
      Lorem ipsum dolor sit amet consectetur adipisicing elit. Cum atque fuga, eos neque ipsum enim id inventore necessitatibus laboriosam quo nobis, repellendus maxime veritatis error ut expedita, velit aspernatur asperiores!
    </p>
  </article>
</main>

<aside>This is side bar</aside>
<div></div>
<footer>This is <a href="http://">footer</a></footer>  

Еще одна вещь, которую следует упомянуть, я бы предложил изучить макеты flexbox. Это гораздо более современный и расширяемый метод, чем принудительное display: table использование a div для создания макета с несколькими столбцами.

Комментарии:

1. Но, я думаю, что элемент — это просто строки, созданные в javascript в виде текста. Я прав?

2. В данном случае нет. Вы создаете объект jQuery из <p /> строки. Затем вы ссылаетесь на этот один объект несколько раз, поэтому он перемещается.

3. Я могу получить его тип, используя оператор typeof , и я также могу вставить его, просто снова инициализировав var p .