라이브러리를 사용하지 않고 JavaScript에서 다른 요소 뒤에 요소를 삽입하는 방법은 무엇입니까?


757

거기에 insertBefore()자바 스크립트,하지만 내가 어떻게 요소를 삽입 할 수 있습니다 jQuery를 또는 다른 라이브러리를 사용하지 않고 다른 요소를?


4
- 당신은 매우 마지막 자식 노드의 특정 케이스가 필요한 경우 stackoverflow.com/questions/5173545/...


2
@AlanLarimer 대단합니다. 감사. insertAdjacentElement가 언제 소개되는지 알고 있습니까?
Xah Lee

1
MDN에 따르면 IE8 및 Firefox 48 (2016 년 8 월 8 일)에서 지원됩니다. 흔적을 따라 bugzilla.mozilla.org/show_bug.cgi?id=811259 -> w3.org/Bugs/Public/show_bug.cgi?id=19962 (2016 3월 14일)
앨런 리머

답변:


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

referenceNode당신이 원하는 노드는 어디에 있습니까 newNode? 경우 referenceNode때문에, 괜찮 부모 요소 내의 마지막 아이 인 referenceNode.nextSiblingnullinsertBefore핸들리스트의 말미에 추가하여 케이스 그게.

그래서:

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

다음 스 니펫을 사용하여 테스트 할 수 있습니다.

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
훌륭한 답변을 주셔서 감사하지만 인수 목록에서 referenceNode 및 newNode를 뒤집는 것이 혼란스럽지 않습니까? insertBefore 구문을 준수하지 않는 이유는 무엇입니까?
GijsjanB

9
이 코드 스 니펫은 referenceNode가 마지막 하위 인 경우 처리하지 않습니다.
Brad Vogel

72
MDN 에 따르면 요소가 마지막이고 nextSibling이 null이면 newNode가 예상대로 추가됩니다.
electroCutie

9
referenceNode.nextElementSibling 사용하는 것이 더 좋은 옵션입니다
Bhumi Singhal

8
@BhumiSinghal : 잘못되었습니다. insertBefore()텍스트 노드와 함께 작동합니다. 왜 insertAfter()다른 사람 이되고 싶 습니까? 당신은 이름 지정된 함수의 별도의 쌍을 생성해야 insertBeforeElement()하고 insertAfterElement()그것에 대해합니다.
7vujy0f0hy

116

간단한 JavaScript는 다음과 같습니다.

전에 추가 :

element.parentNode.insertBefore(newElement, element);

추가 후 :

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

그러나 사용 편의성을 위해 일부 프로토 타입을 넣습니다.

다음 프로토 타입을 작성하면 새로 작성된 요소에서 직접이 함수를 호출 할 수 있습니다.

  • newElement.appendBefore(element);

  • newElement.appendAfter(element);

.appendBefore (element) 프로토 타입

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

.appendAfter (element) 프로토 타입

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

그리고 모든 것을 실제로 보려면 다음 코드 스 니펫을 실행하십시오.

JSFiddle에서 실행


4
확장 기능 이름은 오해의 소지가있다. 오히려 그것이 appendMeBefore와 appendMeAfter라고해야한다고 생각합니다. 나는 그것이처럼 사용되었다 생각 에 appendChild () 메소드existingElement.appendAfter(newElement);. 이 업데이트 된 jsfiddle의 의미를 확인하십시오 .
stomtech

2
Append After가 작동하면 element.nextSibling에 다음 형제가없는 경우 nextSibling이 NULL이므로 끝에 추가됩니다.
Stefan Steiger

45

insertAdjacentHTML + outerHTML

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

거꾸로 :

  • DRYer : before 노드를 변수에 저장하고 두 번 사용할 필요는 없습니다. 변수 이름을 바꾸면 수정 빈도가 줄어 듭니다.
  • 골프를 친다 더보다 insertBefore(손익분기 기존 노드 변수 이름은 길이 3 개 문자 인 경우)

단점 :

  • https://caniuse.com/#feat=insert-adjacent 이후 새로운 브라우저 지원
  • outerHTML요소를 문자열로 변환 하기 때문에 이벤트와 같은 요소의 속성이 손실됩니다 . insertAdjacentHTML요소가 아닌 문자열의 내용을 추가 하기 때문에 필요합니다 .

12
이미 구성 요소가 있다면 다음을 사용할 수 있습니다.insertAdjacentElement()
GetFree

6
2018으로, 브라우저 지원 꽤 단단한 외모 : caniuse.com/#feat=insert-adjacent
madannes

이것은 내가 eveyone이 읽을 제안하는 좋은 솔루션이었다 xahlee.info/js/js_insert_after.html
Mehregan 마니

37

빠른 Google 검색 으로이 스크립트가 표시됩니다

// 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
이 스크립트를 우연히 발견하는 사람에게는 사용하지 않는 것이 좋습니다. @ karim79의 기본 솔루션이 이미 해결 한 문제를 해결하려고 시도합니다. 그의 스크립트는 더 빠르고 효율적입니다.이 스크립트 대신 해당 스크립트를 사용하는 것이 좋습니다.
James Long

10
JavaScript의 일반적인 규칙으로서, 브라우저는 사용자가 작성할 수있는 것보다 빠르게 작업을 수행 할 수 있습니다. 두 솔루션은 기능적으로 동일하지만 내 JavaScript 솔루션을 사용하려면 브라우저에서 이해해야하며 실행될 때마다 추가 확인이 필요합니다. karim79가 제공하는 솔루션은 이러한 모든 단계를 내부적으로 수행하여 해당 단계를 저장합니다. 그 차이는 기껏해야 사소하지만 그의 해결책이 더 낫습니다.
James Long

3
즉, 존재하지 않는 문제를 해결하려고합니다. 추가 검사에 대해서는 본질적으로 잘못된 것이 없지만, 이러한 방법을 가장 잘 이해하고 있지 않다고 생각합니다.
1j01

3
거의 요 스크립트를 작성하는 데 사용했던 것과 같은 종류이기 때문에 여기에 스크립트를 남겨두고 있지만 받아 들일 수있는 대답이 더 낫습니다. 이 답변을 대신 사용할 이유가 없습니다. 왜 여전히 투표를했는지 모르겠습니다.
James Long

3
targetElement가 형제 중 마지막 요소 인 경우을 targetElement.nextSibling반환 null합니다. 두 번째 인수로 node.insertBefore호출 되면 null컬렉션 끝에 노드가 추가됩니다. 다시 말해 if(parent.lastchild == targetElement) {지점은 parent.insertBefore(newElement, targetElement.nextSibling);처음에는 다르게 나타날 수 있지만 모든 경우를 올바르게 처리 하기 때문에 불필요한 것입니다. 많은 사람들이 이미 다른 의견에서 지적했습니다.
Rolf

26

하지만 insertBefore()(참조 MDN은 ) 여기에 대부분의 답변에 의한 크고 참조입니다. 유연성을 높이고 좀 더 명시 적으로 나타내려면 다음을 사용할 수 있습니다.

insertAdjacentElement()( MDN 참조 ) 이렇게하면 모든 요소를 ​​참조하고 원하는 위치로 이동할 요소를 정확하게 삽입 할 수 있습니다.

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

유사한 사용 사례에 대해 고려해야 할 기타 사항 : insertAdjacentHTML()insertAdjacentText()

참고 문헌 :

https://developer.mozilla.org/en-US/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


이 답변에 정말 사랑을 주어야한다면, 2020 년대가 빠르게 다가오는 것은 현대적인 접근법입니다.
serraosays

1
이 대답은 어떻게 그렇게 깊이 묻혀 있습니까? 더 많은 관심을 끌기 위해 몇 가지 포인트를 보상하겠습니다.
Qwerty

16

메소드 node.after( doc )는 다른 노드 뒤에 노드를 삽입합니다.

이 개 DOM 노드 node1node2,

node1.after(node2)node2이후에 삽입합니다 node1.

이 방법은 구형 브라우저에서는 사용할 수 없으므로 일반적으로 폴리 필이 필요합니다.


기능적인 insertAfter로 구현하려면 약간의 수동 작업이 필요하지만 불행히도 이것이 올바르게 작동한다고 생각하지 않습니다.
Mister SirCode

6

2018 솔루션 (나쁜 연습, 2020으로 이동)

나는이 질문이 고대인 것을 알고 있지만 미래의 모든 사용자를 위해 수정 된 프로토 타입은이 프로토 타입이 존재하지 않는 .insertAfter 함수에 대한 마이크로 폴리 필입니다 baseElement.insertAfter(element);. 요소 프로토 타입에 직접 새로운 기능 을 추가합니다 .

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

라이브러리, 요지 또는 코드 (또는 참조 할 수있는 다른 위치)에 폴리 필을 배치하면 document.getElementById('foo').insertAfter(document.createElement('bar'));


2019 솔루션 (미운, 2020 년으로 이동)

새로운 편집 : 프로토 타입을 사용하지 않아야합니다. 기본 코드베이스를 덮어 쓰고 매우 효율적이거나 안전하지 않으며 호환성 오류가 발생할 수 있지만 비상업적 프로젝트의 경우 문제가되지 않습니다. 안전한 상용 기능을 원하면 기본 기능 만 사용하십시오. 예쁘지 않지만 작동합니다.

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 솔루션

ChildNode의 현재 웹 표준 : https://developer.mozilla.org/en-US/docs/Web/API/ChildNode

현재 생활 수준에 있으며 안전합니다.

지원되지 않는 브라우저의 경우 다음 Polyfill을 사용하십시오. https://github.com/seznam/JAK/blob/master/lib/polyfills/childNode.js

누군가 Polyfill이 Protos를 사용한다고 언급했는데, 나는 그들이 나쁜 연습이라고 말했습니다. 특히 2018 년 솔루션과 같이 잘못 사용되는 경우입니다. 그러나 polyfill은 MDN 설명서에 있으며 더 안전한 초기화 및 실행을 사용합니다. 또한 프로토 타입 덮어 쓰기가 그다지 나쁘지 않은 오래된 브라우저 지원을위한 것입니다.

2020 솔루션 사용 방법 :

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

아니면 간단하게 할 수 있습니다 :

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

나는 그 접근법을 생각하지 않았을 것입니다. @ karim79의 더 직접적인 답변 을 사용하고 싶지만 명심하십시오.
벤 J

5

1 단계. 요소 준비 :

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

2 단계 후 추가 :

elementParent.insertBefore(newElement, element.nextSibling);

3

insertBefore () 메소드는 다음과 같이 사용됩니다 parentNode.insertBefore(). 이것을 모방하고 메소드를 만들 parentNode.insertAfter()려면 다음 코드를 작성할 수 있습니다.

자바 스크립트

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 확장이 올바른 솔루션이 아닐 수도 있습니다 .

그러나이 기사는 2010 년에 작성되었으며 현재 상황이 다를 수 있습니다. 따라서 스스로 결정하십시오.

JavaScript DOM insertAfter () 메소드 @ jsfiddle.net


2

insertBeforeinsertAfter 와 유사하게 작동하는 것이 이상적 입니다. 아래 코드는 다음을 수행합니다.

  • 자녀가 없으면 새로운 자녀 Node가 추가됩니다.
  • 참조가 없으면 Node새로운 Node것이 추가됩니다.
  • Node참조 뒤에 아무 것도 없으면 Node새로운 Node것이 추가됩니다.
  • 참조 Node에 형제가있는 경우 Node해당 형제 앞에 새 가 삽입됩니다.
  • 새로운 것을 돌려줍니다 Node

확장 Node

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

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

    return node;
};

일반적인 예

node.parentNode.insertAfter(newNode, node);

실행중인 코드보기


2

나는이 질문에 이미 너무 많은 답변이 있지만, 내 정확한 요구 사항을 충족시키지 못했습니다.

나는 정확히 반대되는 동작을 가진 함수를 원했다.parentNode.insertBeforereferenceNode 즉, 허용되는 대답 이 아닌 null을 받아 들여야 하고 자식 insertBefore끝에 삽입 할 위치 는 어디 에서 시작 해야 합니까 ? d이 기능을 사용하여 시작 위치에 삽입 할 방법이 없어야합니다. 같은 이유로 insertBefore끝에 삽입합니다.

널 (null) referenceNode은 부모를 찾아야하므로 부모 (parent)는- insertBefore의 메소드 parentNode이므로 부모에 대한 액세스 권한이 있음을 알아야합니다. 우리의 함수는 그렇지 않으므로 부모를 매개 변수로 전달해야합니다.

결과 함수는 다음과 같습니다.

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

또는 (필요한 경우 권장하지 않습니다) 물론 Node프로토 타입을 향상시킬 수 있습니다 .

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

0

이 코드는 마지막 기존 자식 바로 다음 에 작은 CSS 파일 을 인라인 하기 위해 링크 항목을 삽입하는 작업입니다.

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의 강력한 구현.

// 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'."));

};


이 답변이 현재 문제를 해결하는 데 OP에 도움이되는 방법에 대한 답변이 포함 된 설명을 추가하십시오
ρяσѕρєя K

위의 코드를 실행하면 지정된 referenceNode 다음에 새 노드를 삽입 할 수 있습니다.
jszhou

0

모든 시나리오를 다룰 수 있습니다

 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

실제로 after()최신 버전의 Chrome, Firefox 및 Opera에서 호출되는 메소드를 사용할 수 있습니다 . 이 방법의 단점은 Internet Explorer가 아직 지원하지 않는다는 것입니다.

예:

// 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)

테스트 할 간단한 HTML 코드는 다음과 같습니다.

<!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>

예상대로 다운 요소 다음에 업 요소를 이동시킵니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.