Durumu kaybetmeden DOM öğesini taşıma

Web özellikleri: moveBefore()

appendChild() veya insertBefore() gibi geleneksel yöntemleri kullanarak DOM öğelerini yeniden üst öğeye bağlarken tarayıcı, öğeyi DOM'dan dolaylı olarak kaldırır ve ardından yeni konumuna ekler. Bu "kaldırma ve ekleme" işlemi, birçok dahili durumu sıfırlayarak <iframe> öğelerinin yeniden yüklenmesine, CSS animasyonlarının yeniden başlatılmasına ve giriş alanlarının odağı kaybetmesine neden olur.

Bir öğeyi durumunu koruyarak taşımak için moveBefore() API'sini kullanın. Bu yöntem, kaldırma ve ekleme adımlarını tamamen atlayarak atomik bir taşıma işlemi gerçekleştirir.

Durumu olan bir öğeyi taşıma

moveBefore(), insertBefore() ile aynı şekilde kullanılır. İki bağımsız değişken gerektirir: taşınacak düğüm ve önüne eklenecek referans düğüm (veya yeni üst öğenin sonuna eklenecek null).

const newParent = document.getElementById('new-parent');
const elementWithState = document.getElementById('iframe-or-focused-input');

// MANDATORY: Use moveBefore to preserve state. 
// Passing null as the second argument appends the element to the end of newParent.
newParent.moveBefore(elementWithState, null);

Özel öğeleri (Web Bileşenleri) taşıma

Özel öğeleri moveBefore() kullanarak taşıyorsanız connectedCallback ve disconnectedCallback yaşam döngüsü yöntemleri tetiklenmez.

Özel öğenizin taşındığında belirli bir mantığı uygulaması gerekiyorsa özel öğe tanımında connectedMoveCallback() yöntemini uygulayın.

class MyCustomElement extends HTMLElement {
  connectedCallback() {
    // Runs on initial insertion.
  }
  
  connectedMoveCallback() {
    // Runs when the element is moved via moveBefore().
    // Use this to update state that depends on the new DOM location.
  }
}

Yedek stratejiler

moveBefore(), progresif geliştirme olduğundan, çağırmadan önce özellik algılamayı kullanmanız ve eski tarayıcılar için geleneksel insertBefore() veya appendChild() işlemlerine geri dönmeniz GEREKİR.

const targetParent = document.getElementById('target-container');
const nodeToMove = document.getElementById('moving-element');

// Check if moveBefore is supported on the Element prototype
if ('moveBefore' in Element.prototype) {
  targetParent.moveBefore(nodeToMove, null);
} else {
  // Fallback: traditional move. 
  // Note: This WILL reset <iframe>, animation, and focus state in unsupported browsers.
  targetParent.insertBefore(nodeToMove, null);
}