Frontend/javascript

jQuery 선택자를 이용해서 DOM 요소를 선택할 때 주의점

민57 2024. 3. 29. 00:49

 

다양한 라이브러리 및 메소드의 매개변수로 DOM 요소를 전달할 때 jQuery 선택자를 이용해서 지정하면 에러를 출력한다.

사실 jQuery를 이용하지 않으면 그만인 문제이지만 코드의 일관성을 위해서 이 문제에 대해 찾아보게 되었고 근본적인 원인을 알게 되어 나름 공부가 된 듯 하다.

 

아래에서는 에디터와 자바스크립트 내장 메소드를 이용할 때를 예제로 가져왔다.


 

예시 (1) CKEditor

let editorElement = document.querySelector('#editor');

const initializeEditor = () => {
    _editor
        .create(editorElement)
        .then(editor => {
            editorElement = editor;
        })
        .catch();
}

 

에러 로그

editor:72 CKEditorError: datacontroller-init-non-existent-root
Read more: https://ckeditor.com/docs/ckeditor5/latest/support/error-codes.html#error-datacontroller-init-non-existent-root
    at Sd.init (datacontroller.ts:359:10)
    at Sd.<anonymous> (observablemixin.ts:277:33)
    at Sd.fire (emittermixin.ts:241:31)
    at <computed> [as init] (observablemixin.ts:281:17)
    at classiceditor.ts:221:31

 

https://ckeditor.com/docs/ckeditor5/latest/support/error-codes.html#error-datacontroller-init-non-existent-root

 

Error codes | CKEditor 5 Documentation

Learn how to install, integrate and configure CKEditor 5 Builds and how to work with CKEditor 5 Framework, customize it, create your own plugins and custom editors, change the UI or even bring your own UI to the editor. API reference and examples included.

ckeditor.com

 

해당 에러는 CKEditor docs에서 자세히 확인할 수 있다:

 

CKEditor Docs

 

예시 (2) MutationObserver

const synchronizeEditor = () => {
    const targetElement = $(".ck-editor__editable");
    const observer = new MutationObserver(mutations => {});

    const config = {
        attributes: true,
        childList: true,
        characterData: true
    }

    observer.observe(targetElement, config);
}

 

에러 로그

editor:72 TypeError: Failed to execute 'observe' on 'MutationObserver': parameter 1 is not of type 'Node'.
    at synchronizeEditor (editor:97:18)
    at editor:80:17

 


 

원인

 

에디터에서 발생한 문제는 존재하지 않는 루트 이름(= 알 수 없는 루트)으로 에디터를 초기화하려고 해서 발생한 문제였고,

MutationObserver에서의 문제는 첫 번째 매개변수가 Node 타입이 아니어서 발생했다.

 

에러 내용에는 차이가 있지만 결국은 Node 같은 네이티브 DOM 요소가 필요한 곳에 jQuery 객체를 전달하려고 해서 발생한 같은 문제였다.

 

document.querySelector(”.target”)는 네이티브 자바스크립트 메소드고, $(”.target”)jQuery 라이브러리 메소드이다.

두 구문 모두 CSS 선택자를 사용하여 일치하는 요소를 반환하지만, 한 가지 차이점이 있다.

 

자바스크립트 메소드는 단일 DOM 요소를 반환하지만

jQuery 메소드의 경우 일치하는 모든 요소를 jQuery 객체로 래핑하여 반환한다.

 

그럼 jQuery 객체는 결국 배열인가?라고 생각할 수도 있지만, 배열은 아니고 DOM 요소의 집합을 나타내는 특별한 형태의 객체라고 한다. 그래서 jQuery가 제공하는 다양한 메소드와 유틸리티를 사용할 수 있다.

 


 

해결

 

jQuery 객체를 네이티브 DOM 요소로 변환하거나 네이티브 자바스크립트의 메소드를 이용하여 단일 DOM 요소를 전달하는 방법으로 해결할 수 있다.

// jQuery 객체를 네이티브 DOM 요소로 변환
const container = $(".container")[0];
const container = $(".container").get(0);

// 네이티브 자바스크립트 메소드 이용
const container = document.querySelector(".container");
728x90