2009-04-11 2 views
1

브라우저에서 텍스트 파일 (.txt, .js, .css, ...)을 열면 멋진 DOM 트리로 정리됩니다. 주소 표시 줄에Firefox에서 일반 txt 파일에 innerHTML을 사용하는 방법은 무엇입니까?

예를 들어

오픈 this .txt file를 입력

javascript:alert(document.documentElement.innerHTML); 

. 모든 주요 브라우저는이 랩 된 텍스트 파일에서 DOM 조작을 지원합니다. 강력한 북마크 렛 또는 user scripts을 작성하는 데 가장 좋습니다.

그러나 Firefox는 요소의 innerHTML을 지정하지 못합니다. 예 :

javascript: document.body.innerHTML = document.body.innerHTML.replace(/(\d+\s+\w+(?=\s+\d+))/g, '<span style="color:red">$1</span>'); void 0; 

은 Firefox를 제외한 모든 브라우저에서 작동합니다.

이 문제를 해결하려면 트릭이 있습니까?

는 (아니, 수동으로 innerHTML을 문자열을 구문 분석하지 않고, 아니, 그것은 하나 jQuery를 작동하지 않습니다.)

+0

DOM은 HTML과 XML에서 작동하도록 설계되었습니다. 텍스트 문서도 아닙니다. http://en.wikipedia.org/wiki/Document_Object_Model 임의의 HTML 태그가 몇 개있는 텍스트 문서는 여전히 텍스트 문서입니다. – Calvin

답변

1

나는 작동하는 해결책을 찾았습니다. 우선, 질문에 대해 더 자세히 설명하겠습니다.

문제는 : 파이어 폭스는

[some wrapper] 
+---document 
    +---<html>[=documentElement] 
     +---<body> 
      +---<head/> 
      +---<pre> 
       +---[actual plain text contents] 

같은 것을 만들지 만, 랩 문서 객체가 제대로 innerHTML을 설정을 지원하지 않습니다. 따라서 기본 아이디어는 완전한 innerHTML을 지원하는 새로운 문서 객체를 만드는 것입니다. 작동 방식은 다음과 같습니다

var setInnerHTML = function(el, string) { 
    if (typeof window.supportsInnerHTML == 'undefined') { 
     var testParent = document.createElement('div'); 
     testParent.innerHTML = '<br/>'; 
     window.supportsInnerHTML = (testParent.firstChild.nodeType == 1); 
    } 
    if (window.supportsInnerHTML) { 
     el.innerHTML = string; 
    } else { 
     if (!window.cleanDocumentObject) { 
      /* this is where we get a 'clean' document object */ 
      var f = document.createElement('iframe'); 
      f.style.setProperty('display', 'none', 'important'); 
      f.src = 'data:text/html,<!DOCTYPE html><html><title></title></html>'; 
      document.body.appendChild(f); /* <- this is where FF creates f.contentDocument */ 
      window.cleanDocumentObject = f.contentDocument; 
      document.body.removeChild(f); 
     } 

     /* let browser do the parsing */ 
     var div = window.cleanDocumentObject.createElement('div'); 
     div.innerHTML = string; /* this does work */ 

     /* copy childNodes */ 
     while(el.firstChild) { 
      el.removeChild(el.firstChild); /* cleanup */ 
     } 
     for (var i = 0; i < div.childNodes.length; i++) { 
      el.appendChild(div.childNodes[i].cloneNode(true)); 
     } 
     delete div; 
    } 
} 

편집 :

이 버전은 더 빠르고, iFrame 대신 XSLTProcessor를 사용합니다.

var setInnerHTML = function(el, string) { 
    // element.innerHTML does not work on plain text files in FF; this restriction is similar to 
    // http://groups.google.com/group/mozilla.dev.extensions/t/55662db3ea44a198 
    var self = arguments.callee; 
    if (typeof self.supportsInnerHTML == 'undefined') { 
     var testParent = document.createElement('div'); 
     testParent.innerHTML = '<p/>'; 
     self.supportsInnerHTML = (testParent.firstChild.nodeType == 1); 
    } 
    if (self.supportsInnerHTML) { 
     el.innerHTML = string; 
     return el; 
    } else if (typeof XSLTProcessor == 'undefined') { 
     return undefined; 
    } else { 
     if (typeof self.cleanDocument == 'undefined') 
      self.cleanDocument = createHTMLDocument(); 

     if (el.parentNode) { 
      var cleanEl = self.cleanDocument.importNode(el, false); 
      cleanEl.innerHTML = string; 
      el.parentNode.replaceChild(document.adoptNode(cleanEl), el); 
     } else { 
      var cleanEl = self.cleanDocument.adoptNode(el); 
      cleanEl.innerHTML = string; 
      el = document.adoptNode(cleanEl); 
     } 

     return el; 
    } 

    function createHTMLDocument() { 
     // Firefox does not support document.implementation.createHTMLDocument() 
     // cf. http://www.quirksmode.org/dom/w3c_html.html#t12 
     // the following is taken from http://gist.github.com/49453 
     var xmlDoc = document.implementation.createDocument('', 'fooblar', null); 
     var templ = '<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">' 
       + '<xsl:output method="html"/><xsl:template match="/">' 
       + '<html><title/><body/></html>' 
       + '</xsl:template></xsl:stylesheet>'; 
     var proc = new XSLTProcessor(); 
     proc.importStylesheet(new DOMParser().parseFromString(templ,'text/xml')); 
     return proc.transformToDocument(xmlDoc); 
    } 
}; 
0

사용 Greasemonkey와

1

body이 없기 때문에 그것은 실패 - 당신이 링크 한 파일조차도 시체가없는 텍스트 파일 일뿐입니다 (아마도 당신은 방화 녀 (firebug)에서 그것을보고있는 것입니까?).

텍스트로 작업 할 때 가장 좋은 방법은 정규식 대체 일 것입니다.

0

그것은 당신이 innerText와에 할당하는 것처럼 모든 노드 역할의 innerHTML을 할당, 파이어 폭스 3에서 텍스트 문서에 보인다 (와 "< HTML> < 몸> < 사전>"앞에 추가).

(비 XML/HTML 문서에 대한 DOM 스크립팅이 완전히 정의되지 때문에,이 작업을 수행 할 수있는 파이어 폭스의 권한 내에서 확실히이다;.이 HTML 페이지에 텍스트 파일을 표시하는 빠른 해킹 것으로 보인다)

따라서 Firefox에서 innerHTML을 사용할 수는 없지만 다른 DOM 메소드가 작동합니다.

var span= createElement('span'); 
span.style.color= 'red'; 
span.appendChild(document.createTextNode(match)); 
+0

오른쪽. 문제는 파서가 필요하다는 것입니다. - 느리고 부피가 큰 JavaScript (예 : http://ejohn.org/blog/pure-javascript-html-parser/)로 작성된 것을 사용하거나 - Firefox에서 구문 분석을 수행하는 방법을 찾으십시오. , 어느 쪽이 좋을까 – user123444555621

+0

실제로, 텍스트 노드 데이터를 검색하고 splitText()를 사용하여 찾은 각 일치 항목을 분리하고 위의 span 요소를 삽입 할 수 있습니다. 파싱이 필요 없습니다. – bobince

관련 문제