Bir öğeyi JavaScript kullanmadan başka bir öğeden sonra kitaplık kullanmadan nasıl ekleyebilirim?


757

Orada insertBefore()JavaScript, ama nasıl bir öğe ekleyebilirsiniz sonra jQuery veya başka kütüphane kullanmadan başka eleman?


4
en son alt düğümün özel durumuna ihtiyacınız varsa - stackoverflow.com/questions/5173545/…


2
@AlanLarimer harika. Teşekkürler. insertAdjacentElement'ın ne zaman tanıtıldığını biliyor musunuz?
Xah Lee

1
MDN'ye göre IE8 ve Firefox 48'de (2016 08 Ağustos) desteklenmektedir. İzi takip edin: bugzilla.mozilla.org/show_bug.cgi?id=811259 -> w3.org/Bugs/Public/show_bug.cgi?id=19962 (2016 14 Mart)
Alan Larimer

Yanıtlar:


1276
referenceNode.parentNode.insertBefore(newNode, referenceNode.nextSibling);

Sonra referenceNodekoymak istediğiniz düğüm nerede newNode. Eğer referenceNode, çünkü gayet iyi onun ana öğesinin içinde son çocuk olduğunu referenceNode.nextSiblingolacak nullve insertBeforekolları listenin sonuna eklenerek durumda olduğunu.

Yani:

function insertAfter(newNode, referenceNode) {
    referenceNode.parentNode.insertBefore(newNode, referenceNode.nextSibling);
}

Aşağıdaki kod parçasını kullanarak test edebilirsiniz:

function insertAfter(referenceNode, newNode) {
  referenceNode.parentNode.insertBefore(newNode, referenceNode.nextSibling);
}

var el = document.createElement("span");
el.innerHTML = "test";
var div = document.getElementById("foo");
insertAfter(div, el);
<div id="foo">Hello</div>


8
Harika bir yanıt için teşekkürler, ancak argümanlar listesinde referenceNode ve newNode'u çevirmek kafa karıştırıcı değil mi? İnsertBefore sözdizimine neden uymuyorsunuz?
GijsjanB

9
Bu kod pasajı, referenceNode öğesinin appendChild olması gereken son alt öğe olması durumunda işlemez.
Brad Vogel

72
MDN'ye göre öğe son ise (ve böylece nextSibling boşsa) newNode beklendiği gibi eklenecektir
electroCutie

9
referenceNode.nextElementSibling kullanımı daha iyi bir seçenektir
Bhumi Singhal

8
@BhumiSinghal: Yanlış. insertBefore()metin düğümleriyle çalışır. Neden insertAfter()farklı olmak istiyorsun ? Sen adında işlevlerin ayrı çifti oluşturmalı insertBeforeElement()ve insertAfterElement()bunun için.
7vujy0f0hy

116

Basit JavaScript Şunlardır:

Önce Ekle:

element.parentNode.insertBefore(newElement, element);

Sonra Ekle:

element.parentNode.insertBefore(newElement, element.nextSibling);

Ancak, Kullanım Kolaylığı İçin Bazı Prototipleri Vurun

Aşağıdaki prototipleri oluşturarak, bu işlevi doğrudan yeni oluşturulan öğelerden çağırabilirsiniz.

  • newElement.appendBefore(element);

  • newElement.appendAfter(element);

.appendBefore (eleman) Prototipi

Element.prototype.appendBefore = function (element) {
  element.parentNode.insertBefore(this, element);
},false;

.appendAfter (element) Prototipi

Element.prototype.appendAfter = function (element) {
  element.parentNode.insertBefore(this, element.nextSibling);
},false;

Hepsini İşlem Görmek İçin Aşağıdaki Kod Parçacığını Çalıştırın

JSFiddle'da çalıştırın


4
Uzatma fonksiyonu isimleri yanıltıcı. Bunun yerine appendMeBefore ve appendMeAfter olarak adlandırılması gerektiğini düşünüyor. Ben appendChild () yöntemi gibi kullanıldığını düşündüm , örn existingElement.appendAfter(newElement);. Bu güncellenmiş jsfiddle'da ne demek istediğimi görün .
stomtech

2
Sonrası Çalışır, çünkü element.nextSibling öğesinin bir sonraki kardeşi yoksa, nextSibling NULL olur ve sonunda eklenir.
Stefan Steiger

45

insertAdjacentHTML + outerHTML

elementBefore.insertAdjacentHTML('afterEnd', elementAfter.outerHTML)

Upsides:

  • KURUTUCU: önceki düğümü bir değişkende saklamanız ve iki kez kullanmanız gerekmez. Değişkeni yeniden adlandırırsanız, daha az değişiklikle değiştirin.
  • daha iyi golfs insertBefore(mevcut düğüm değişkeni adı 3 karakter uzunluğunda olsa bile mola)

Downsides:

  • daha yeni olduğundan daha düşük tarayıcı desteği: https://caniuse.com/#feat=insert-adjacent
  • outerHTMLöğeyi bir dizeye dönüştürdüğünden öğenin olaylar gibi özelliklerini kaybeder . Buna ihtiyacımız var çünkü insertAdjacentHTMLöğelerden ziyade dizelerden içerik ekliyor.

12
Eleman zaten inşa .insertAdjacentElement()
edilmişse

6
2018 itibarıyla tarayıcı desteği oldukça sağlam görünüyor: caniuse.com/#feat=insert-adjacent
madannes

Bu güzel bir çözüm, eveyone bu xahlee.info/js/js_insert_after.html
Rahmani

37

Hızlı bir Google araması bu komut dosyasını gösterir

// create function, it expects 2 values.
function insertAfter(newElement,targetElement) {
    // target is what you want it to go after. Look for this elements parent.
    var parent = targetElement.parentNode;

    // if the parents lastchild is the targetElement...
    if (parent.lastChild == targetElement) {
        // add the newElement after the target element.
        parent.appendChild(newElement);
    } else {
        // else the target has siblings, insert the new element between the target and it's next sibling.
        parent.insertBefore(newElement, targetElement.nextSibling);
    }
}

29
Bu senaryoyu tökezleyen herkes için, bunu kullanmanızı önermiyorum. @ Karim79'un doğal çözümünün zaten çözdüğü sorunları çözmeye çalışır. Onun komut dosyası daha hızlı ve daha verimli - bunun yerine bu komut dosyasını kullanmanızı şiddetle tavsiye ederim.
James Long

10
JavaScript'te genel bir kural olarak, tarayıcı yazabildiğiniz her şeyden daha hızlı bir görev yapabilir. İki çözüm işlevsel olarak aynı olsa da, JavaScript çözümümün kullanılmadan önce tarayıcı tarafından anlaşılması gerekiyor ve her yürütüldüğünde ek bir kontrol gerektiriyor. Karim79 tarafından sunulan çözüm tüm bunları dahili olarak yapacak ve bu adımları kaydedecektir. Fark en iyi ihtimalle önemsiz olacaktır, ancak çözümü daha iyidir.
James Long

3
Başka bir deyişle, var olmayan bir sorunu çözmeye çalışıyor. Ekstra kontrolün doğasında yanlış olan bir şey yok, ancak bu yöntemlerin en iyi anlaşılmasını
yaymadığını varsayalım

3
Neredeyse. Senaryoyu burada bırakıyorum çünkü eskiden yazdığım bir şey, ama kabul edilen cevap daha iyi, yöntemleri daha iyi anlıyor ve daha hızlı. Bunun yerine bu cevabı kullanmanız için hiçbir neden yok - neden hala vekiller aldığından emin değilim
James Long

3
TargetElement, kardeşleri arasındaki son öğeyse, targetElement.nextSiblinggeri döner null. Ne zaman node.insertBeforeçağrılır nullikinci argüman olduğu gibi, o zaman toplama sonunda düğüm ekleyecektir. Başka bir deyişle, if(parent.lastchild == targetElement) {şube gereksizdir, çünkü parent.insertBefore(newElement, targetElement.nextSibling);ilk başta başka şekilde görünmesine rağmen, tüm vakalarla düzgün bir şekilde ilgilenecektir. Birçok kişi bunu diğer yorumlarda belirtmişti.
Rolf

26

Gerçi insertBefore()(bkz. MDN ) harika ve burada çoğu cevap tarafından referans verildi. Ek esneklik ve biraz daha açık olmak için şunları kullanabilirsiniz:

insertAdjacentElement()(bkz. MDN ) Bu, herhangi bir öğeye başvurmanıza ve taşınacak öğeyi tam olarak istediğiniz yere eklemenize olanak tanır:

<!-- refElem.insertAdjacentElement('beforebegin', moveMeElem); -->
<p id="refElem">
    <!-- refElem.insertAdjacentElement('afterbegin', moveMeElem); -->
    ... content ...
    <!-- refElem.insertAdjacentElement('beforeend', moveMeElem); -->
</p>
<!-- refElem.insertAdjacentElement('afterend', moveMeElem); -->

Diğerleri benzer kullanım durumları için dikkate almalıdır: insertAdjacentHTML()veinsertAdjacentText()

Referanslar:

https://developer.mozilla.org/tr-TR/docs/Web/API/Element/insertAdjacentElement https://developer.mozilla.org/en-US/docs/Web/API/Element/insertAdjacentHTML https: // developer.mozilla.org/en-US/docs/Web/API/Element/insertAdjacentText


Bu cevaba gerçekten biraz sevgi vermeli, 2020'ler için hızla yaklaşmakta olan modern yaklaşım.
serraosays

1
Bu cevap nasıl bu kadar derin gömüldü? Daha fazla dikkat çekmek için bazı puanları ödüllendireceğim.
Qwerty

16

Yöntem node.after( doc ) başka bir düğümden sonra bir düğüm ekler.

İki DOM düğümlerinin için node1ve node2,

node1.after(node2)node2sonra ekler node1.

Bu yöntem eski tarayıcılarda mevcut değildir, bu nedenle genellikle bir çoklu dolgu gerekir.


Bu, işleyen bir insert olarak uygulamak için biraz manuel çalışma gerektirir.Ama ne yazık ki, bunun doğru çalışacağını düşünmüyorum.
Bay SirCode

6

2018 Çözümü (Kötü Uygulama, 2020'ye gidin)

Bu sorunun Kadim olduğunu biliyorum, ancak gelecekteki kullanıcılar için, değiştirilmiş bir prototip heres, bu prototip var olmayan .insertAfter işlevi için sadece bir mikro çoklu dolgu, doğrudan baseElement.insertAfter(element);Element prototipine yeni bir işlev ekler :

Element.prototype.insertAfter = function(new) {
    this.parentNode.insertBefore(new, this.nextSibling);
}

Çoklu dolguyu bir kitaplığa, özete veya sadece kodunuza (veya referans verilebilecek başka bir yere) yerleştirdikten sonra document.getElementById('foo').insertAfter(document.createElement('bar'));


2019 Çözümü (Çirkin, 2020'ye gidin)

Yeni Düzenleme: PROTOTİP KULLANMAMALISINIZ. Varsayılan kod tabanının üzerine yazarlar ve çok verimli veya güvenli değildirler ve uyumluluk hatalarına neden olabilirler, ancak eğer ticari olmayan projeler için önemli değil. ticari kullanım için güvenli bir fonksiyon istiyorsanız, sadece varsayılan bir fonksiyon kullanın. güzel değil ama çalışıyor:

function insertAfter(el, newEl) {
    el.parentNode.insertBefore(newEl, this.nextSibling);
}

// use

const el = document.body || document.querySelector("body");
// the || means "this OR that"

el.insertBefore(document.createElement("div"), el.nextSibling);
// Insert Before

insertAfter(el, document.createElement("div"));
// Insert After 


2020 Çözümü

ChildNode için Mevcut Web Standartları: https://developer.mozilla.org/en-US/docs/Web/API/ChildNode

Şu anda Yaşam Standartlarında ve GÜVENLİ.

Desteklenmeyen Tarayıcılar için bu Çoklu Dolguyu kullanın: https://github.com/seznam/JAK/blob/master/lib/polyfills/childNode.js

Birisi, Polyfill'in Protos kullandığını, kötü uygulama olduklarını söylediğimde bahsetti. Bunlar, özellikle yanlış kullanıldıklarında, 2018'deki çözümüm gibi. Ancak, bu çoklu dolgu MDN Belgelerinde ve daha güvenli olan bir tür başlatma ve yürütme kullanıyor. Ayrıca Prototip Üzerine Yazma'nın o kadar da kötü olmadığı gün ve yaşta daha eski tarayıcı desteği içindir.

2020 Çözümü nasıl kullanılır:

const el = document.querySelector(".class");

// Create New Element
const newEl = document.createElement("div");
newEl.id = "foo";

// Insert New Element BEFORE
el.before(newEl);

// Insert New Element AFTER
el.after(newEl);

// Remove Element
el.remove();

// Remove Child
newEl.remove(); // This one wasnt tested but should work

5

Veya şunları yapabilirsiniz:

referenceNode.parentNode.insertBefore( newNode, referenceNode )
referenceNode.parentNode.insertBefore( referenceNode, newNode )

Bu yaklaşımı düşünmezdim. @ Karim79'un daha doğrudan cevabını kullanmayı tercih ederim , ama akılda tutmak güzel.
Ben J

5

Adım 1. Elemanları Hazırlayın:

var element = document.getElementById('ElementToAppendAfter');
var newElement = document.createElement('div');
var elementParent = element.parentNode;

2. Adım. Sonra ekleyin:

elementParent.insertBefore(newElement, element.nextSibling);

3

insertBefore () yöntemi gibi kullanılır parentNode.insertBefore(). Yani bunu taklit etmek ve bir yöntem yapmak parentNode.insertAfter()için aşağıdaki kodu yazabiliriz.

JavaScript

Node.prototype.insertAfter = function(newNode, referenceNode) {
    return referenceNode.parentNode.insertBefore(
        newNode, referenceNode.nextSibling); // based on karim79's solution
};

// getting required handles
var refElem = document.getElementById("pTwo");
var parent = refElem.parentNode;

// creating <p>paragraph three</p>
var txt = document.createTextNode("paragraph three");
var paragraph = document.createElement("p");
paragraph.appendChild(txt);

// now we can call it the same way as insertBefore()
parent.insertAfter(paragraph, refElem);

HTML

<div id="divOne">
    <p id="pOne">paragraph one</p>
    <p id="pTwo">paragraph two</p>
</div>

DOM'u genişletmenin bu makalede belirtildiği gibi Sizin için doğru çözüm olmayabileceğini unutmayın .

Hovewer, bu makale 2010 yılında yazılmıştır ve şimdi farklı olabilir. Bu yüzden kendiniz karar verin.

JavaScript DOM insertAfter () yöntemi @ jsfiddle.net


2

İdeal insertAfterolarak insertBefore'ye benzer şekilde çalışmalıdır . Aşağıdaki kod aşağıdakileri gerçekleştirir:

  • Çocuk yoksa, yeni Nodeeklenir
  • Referans yoksa, Nodeyeni Nodeeklenir
  • NodeReferanstan sonra hayır varsa Node, yeni Nodeeklenir
  • Referansın Nodeardından bir kardeşi varsa, yeni Nodebu kardeşten önce eklenir
  • Yeniyi döndürür Node

uzatma Node

Node.prototype.insertAfter = function(node, referenceNode) {

    if (node)
        this.insertBefore(node, referenceNode && referenceNode.nextSibling);

    return node;
};

Yaygın bir örnek

node.parentNode.insertAfter(newNode, node);

Çalışan koda bakın


2

Bu sorunun zaten çok fazla cevabı olduğunu biliyorum, ancak bunların hiçbiri tam gereksinimlerimi karşılamadı.

Tam tersi davranışı olan bir işlev istedimparentNode.insertBefore - yani, bir null referenceNode( kabul edilen cevabın vermediği) kabul etmeli ve çocukların sonuna nereye insertBeforeekleyecekti, aksi takdirde orada başlamalıdır , çünkü ' d bu işlevle başlangıç ​​konumuna yerleştirmenin hiçbir yolu yoktur; aynı sebep sonunda eklenir.insertBefore

Bir boş referenceNode, ebeveyni bulmanızı gerektirdiğinden, ebeveyni bilmemiz gerekir - insertBeforebir yöntemdir parentNode, bu nedenle ebeveyne bu şekilde erişimi vardır; bizim fonksiyonumuz yoktur, bu yüzden üst öğeyi parametre olarak geçirmemiz gerekir.

Ortaya çıkan işlev şöyle görünür:

function insertAfter(parentNode, newNode, referenceNode) {
  parentNode.insertBefore(
    newNode,
    referenceNode ? referenceNode.nextSibling : parentNode.firstChild
  );
}

Veya (eğer yapmanız gerekiyorsa, bunu tavsiye etmiyorum) elbette Nodeprototipi geliştirebilirsiniz :

if (! Node.prototype.insertAfter) {
  Node.prototype.insertAfter = function(newNode, referenceNode) {
    this.insertBefore(
      newNode,
      referenceNode ? referenceNode.nextSibling : this.firstChild
    );
  };
}

0

Bu kod, son mevcut çocuğun hemen ardından küçük bir css dosyasını satır içine almak üzere bir bağlantı öğesi eklemek için kullanılır

var raf, cb=function(){
    //create newnode
    var link=document.createElement('link');
    link.rel='stylesheet';link.type='text/css';link.href='css/style.css';

    //insert after the lastnode
    var nodes=document.getElementsByTagName('link'); //existing nodes
    var lastnode=document.getElementsByTagName('link')[nodes.length-1]; 
    lastnode.parentNode.insertBefore(link, lastnode.nextSibling);
};

//check before insert
try {
    raf=requestAnimationFrame||
        mozRequestAnimationFrame||
        webkitRequestAnimationFrame||
        msRequestAnimationFrame;
}
catch(err){
    raf=false;
}

if (raf)raf(cb); else window.addEventListener('load',cb);


0

insertAfter'ın sağlam bir uygulaması.

// source: https://github.com/jserz/domPlus/blob/master/src/insertAfter()/insertAfter.js
Node.prototype.insertAfter = Node.prototype.insertAfter || function (newNode, referenceNode) {
  function isNode(node) {
    return node instanceof Node;
  }

  if(arguments.length < 2){
    throw(new TypeError("Failed to execute 'insertAfter' on 'Node': 2 arguments required, but only "+ arguments.length +" present."));
  }

  if(isNode(newNode)){
    if(referenceNode === null || referenceNode === undefined){
      return this.insertBefore(newNode, referenceNode);
    }

    if(isNode(referenceNode)){
      return this.insertBefore(newNode, referenceNode.nextSibling);
    }

    throw(new TypeError("Failed to execute 'insertAfter' on 'Node': parameter 2 is not of type 'Node'."));
  }

  throw(new TypeError("Failed to execute 'insertAfter' on 'Node': parameter 1 is not of type 'Node'."));

};


Bu cevabın mevcut sorunu
çözmede OP'ye

Yukarıdaki kodu çalıştırın, ardından belirtilen referenceNode öğesinden sonra bir newNode ekleyebilirsiniz.
jszhou

0

Tüm senaryoları ele alalım

 function insertAfter(newNode, referenceNode) {
        if(referenceNode && referenceNode.nextSibling && referenceNode.nextSibling.nodeName == '#text')
            referenceNode = referenceNode.nextSibling;

        if(!referenceNode)
            document.body.appendChild(newNode);
        else if(!referenceNode.nextSibling)
            document.body.appendChild(newNode);
        else            
            referenceNode.parentNode.insertBefore(newNode, referenceNode.nextSibling);            
    }

0
if( !Element.prototype.insertAfter ) {
    Element.prototype.insertAfter = function(item, reference) {
        if( reference.nextSibling )
            reference.parentNode.insertBefore(item, reference.nextSibling);
        else
            reference.parentNode.appendChild(item);
    };
}

0

Aslında daha after()yeni Chrome, Firefox ve Opera sürümlerinde çağrılan bir yöntem olabilir . Bu yöntemin dezavantajı, Internet Explorer'ın henüz desteklememesidir.

Misal:

// You could create a simple node
var node = document.createElement('p')

// And then get the node where you want to append the created node after
var existingNode = document.getElementById('id_of_the_element')

// Finally you can append the created node to the exisitingNode
existingNode.after(node)

Bunu test etmek için basit bir HTML Kodu:

<!DOCTYPE html>
<html>
<body>
     <p id='up'>Up</p>
    <p id="down">Down</p>
  <button id="switchBtn" onclick="switch_place()">Switch place</button>
  <script>
    function switch_place(){
      var downElement = document.getElementById("down")
      var upElement = document.getElementById("up")
      downElement.after(upElement);
      document.getElementById('switchBtn').innerHTML = "Switched!"
    }
  </script>
</body>
</html>

Beklendiği gibi, yukarı öğeyi aşağı öğeden sonra taşır

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.