오늘은 갑자기 리치 텍스트 편집기를 만드는 원리를 복습하고 싶었습니다. 그래서 아무 말도 하지 않고 차근차근 해나가기 시작했어요. 1년 전에 간단한 리치 텍스트 편집기를 작성했기 때문에 아직도 약간의 인상이 남아 있을 것입니다. 그런데 제가 작성한 코드를 실행해보니 문제가 발견되었습니다.
var ifr = document.createElement('iframe');
ifr.width = 300;
ifr.height = 300;
var idoc = ifr.contentDocument || ifr .contentWindow.document;
idoc.designMode = 'on';
idoc.contentEditable =
idoc.write('')
document.body.appendChild(ifr)
위의 코드를 살펴보세요. 오류를 발견하셨나요?
저와 비슷한 경험을 한 아이들이 없다면 아마 이 코드가 뭐가 문제인지 모를 것 같아요. 그래서 당신은 달리는 것이 좋을 수도 있습니다. 아마도 곧 문제를 발견하게 될 것입니다.
아래에 답을 공개하겠습니다.
이 코드는 개체를 찾을 수 없다는 예외를 발생시킵니다. 어떤 개체를 찾을 수 없습니까? 문서 개체를 찾을 수 없습니다. 무엇입니까? 문서 객체를 찾을 수 없다는 것이 어떻게 가능합니까? 물론 이 문서 개체는 iframe의 문서 개체입니다. 서식 있는 텍스트를 작성한 사람이라면 누구나 iframe을 편집 가능하게 만들기 전에 먼저 iframe의 문서 객체를 얻어야 한다는 것을 알고 있습니다. 그런데 왜 문서 객체를 얻을 수 없나요? 나는 여기서 너무 허세를 부리지 않을 것이다. 내 해결 과정에 대해 이야기하겠습니다.
우선 구글에 가보니 제가 문서를 받은 방식이 맞다는 걸 알게 됐어요. 그렇다면 Chrome인지 궁금합니다. Chrome은 이 두 개체를 지원하지 않나요? 그래서 Firefox로 전환했습니다. 결과는 여전히 동일합니다. 그렇다면 확실한 것은 자신의 코드에 문제가 있다는 것입니다.
나중에 인터넷에서 코드를 비교해보니 내 AppendChild의 위치가 좀 잘못된 걸 발견해서 문서 객체를 얻기 위해 미리 옮겨두었습니다:
var ifr = document.createElement('iframe')
ifr.width = 300;
ifr.height = 300;
document.body.appendChild(ifr);
var idoc = ifr.contentWindow.document; designMode = 'on';
idoc.contentEditable = true
idoc.write('')
결과는 순조롭게 진행되었습니다. 그러다가 이번에는 오류를 분석해봤습니다. 사실 이 오류가 발생하는 이유는 매우 간단합니다. iframe에는 실제로 다른 문서가 포함되어 있으며 이 문서는 초기화된 후에만 문서 개체를 가질 수 있다는 것을 누구나 알고 있습니다. 그리고 iframe 요소가 DOM 트리에 추가되지 않으면 iframe의 문서가 초기화되지 않습니다. 따라서 처음의 코드에서 얻은 ifr 변수의 contentDocument 값은 null입니다. 이는 iframe의 문서가 현재 초기화되지 않았음을 의미합니다.
이 줄에 따라 다른 노드의 초기화 상태를 확인한 결과 실제로 다른 요소 노드가 생성되면 DOM 트리에 추가되거나 DOM 트리에 추가되는지 여부에 관계없이 고유한 속성과 메서드를 갖게 된다는 사실을 발견했습니다. 아니다. 즉, iframe은 많은 요소 노드 중에서 이상치입니다.