IE 7 ошибка - встроенный белый удаляется, когда текст помещается в innerHTML - PullRequest
0 голосов
/ 13 марта 2012

Кажется, что встроенные пробелы удалены из текста, который я вставил в innerHTML. Есть ли работа вокруг?

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">

<html>
    <head>
        <meta http-equiv="X-UA-Compatible" content="IE=EmulateIE7"/>
        <script>
            function copydiv()
            {
                var text = document.getElementById("copyfrom").innerHTML;
                //In real life "text" is from a AJAX call to a server.
                var temp = document.createElement( "TD" );
                temp.innerHTML = text
                var tr = document.getElementById("copyto");
                tr.appendChild(temp);
            }

        </script>
    <head>
    <body>
        <table>
            <tr id="copyto">
                <td id="copyfrom">
                    <a style="white-space: pre;">A               Z</a>
                </td>
            </tr>
        </table>
        <button type="button" onclick="copydiv();">Test</button>
    </body>
</html>

Спасибо, Grae

PS: Извините за интервал.

Ответы [ 2 ]

1 голос
/ 13 марта 2012

// В реальной жизни «текст» - это вызов AJAX на сервер.

В основном вам нужно обернуть строку html в элемент <pre> и затем удалить ее.

// a container
var div = document.createElement('div');
// wrap the text in a <pre>-element
div.innerHTML = '<pre>' + text + '<\/pre>';
var frag = document.createDocumentFragment(),
    pre = div.firstChild;
// move all childnodes from the <pre>-element to the DocumentFragment
while(pre.firstChild) {
    frag.appendChild(pre.firstChild);
}
// frag now holds the DOM nodes. Add it to the DOM with node.appendChild or
// simliar methods.

Полный пример

<!DOCTYPE HTML PUBLIC '-//W3C//DTD HTML 4.01//EN'
    'http://www.w3.org/TR/html4/strict.dtd'>
<html>
<head>
    <title></title>
    <meta http-equiv='X-UA-Compatible' content='IE=EmulateIE7'>
</head>
<body>
    <div>
        <textarea id='copy-area' cols='20' rows='2'>
            &lt;span style="white-space: pre"&gt;|       |&lt;/span&gt;
        </textarea>
        <div id='paste-area'></div>
        <button id='add-html'>Add HTML</button>
        <button id='alert-innerhtml'>Alert innerHTML</button>
    </div>
    <script type='text/javascript'>
'use strict';

function addEvent(node, evtType, callback) {
    if('addEventListener' in node) {
        node.addEventListener(evtType, callback, false);
    } else {
        node.attachEvent('on' + evtType, callback);
    }
}

var copyArea = document.getElementById('copy-area'),
    pasteArea = document.getElementById('paste-area');

addEvent(document.getElementById('add-html'), 'click', (function() {
    var div = document.createElement('div');
    div.innerHTML = '|  |';
    var useWorkaround = div.innerHTML.length !== 4;
    return function(e) {
        var text = copyArea.value;
        var container;
        if(useWorkaround) {
            div.innerHTML = '<pre>' + text + '<\/pre>';
            container = div.firstChild;
        } else {
            div.innerHTML = text;
            container = div;
        }
        var frag = document.createDocumentFragment();
        while(container.firstChild) {
            frag.appendChild(container.firstChild);
        }
        pasteArea.appendChild(frag);
    }
})());

addEvent(document.getElementById('alert-innerhtml'), 'click', function(e) {
    alert(pasteArea.innerHTML);
});
    </script>
</body>
</html>

Еще один обходной путь с IFrame

Эта версия учитываетwhite-space: pre и ведет себя лучше с символами новой строки.

<!DOCTYPE HTML PUBLIC '-//W3C//DTD HTML 4.01//EN'
    'http://www.w3.org/TR/html4/strict.dtd'>
<html>
<head>
    <title></title>
    <meta http-equiv='X-UA-Compatible' content='IE=EmulateIE7'>
</head>
<body>
    <div>
        <textarea id='copy-area' cols='20' rows='2'>
            &lt;span style="white-space: pre"&gt;|       |&lt;/span&gt;
        </textarea>
        <div id='paste-area'></div>
        <button id='add-html'>Add HTML</button>
        <button id='alert-innerhtml'>Alert innerHTML</button>
    </div>
    <script type='text/javascript'>
'use strict';
function addEvent(node, type, callback) {
    if('addEventListener' in node) {
        node.addEventListener(type, callback, false);
    } else {
        node.attachEvent('on' + type, callback);
    }
}

addEvent(document.getElementById('add-html'), 'click', (function() {
    var copyArea = document.getElementById('copy-area'),
        pasteArea = document.getElementById('paste-area'),
        div = document.createElement('div');

    function createFilledFragment(container) {
        var frag = document.createDocumentFragment();
        while(container.firstChild) {
            frag.appendChild(container.firstChild);
        }
        return frag;
    }

    div.innerHTML = '|  |';
    var getFilledFragment = div.innerHTML.length === 4 ?
        // Firefox, ...
        function(text) {
            div.innerHTML = text;
            return createFilledFragment(div);
        } :
        // Workaround IE 7, IE 8, ...
        (function() {
            var iframe = document.createElement('iframe');
            iframe.style.display = 'none';
            var body = document.body;
            return function(text) {
                body.appendChild(iframe);
                var iframeDoc = iframe.contentWindow.document;
                iframeDoc.write(text);
                var frag = createFilledFragment(iframeDoc.body);
                body.removeChild(iframe);
                return frag;
            }
        })();

    return function(e) {
        pasteArea.appendChild(getFilledFragment(copyArea.value));
    };
})());

addEvent(document.getElementById('alert-innerhtml'), 'click', (function() {
    var pasteArea = document.getElementById('paste-area');
    return function(e) {
        alert(pasteArea.innerHTML);
    }
})());
    </script>
</body>
</html>

Old

Используйте cloneNode и избегайте этого неприятного свойства innerHTML:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html>
    <head>
        <meta http-equiv="X-UA-Compatible" content="IE=EmulateIE7"/>
        <script>
function copydiv() {
    var node = document.getElementById("copyfrom").cloneNode(true);
    node.removeAttribute('id');
    document.getElementById("copyto").appendChild(node);
}
        </script>
    <head>
    <body>
        <table>
            <tr id="copyto">
                <td id="copyfrom">
                    <a style="white-space: pre;">A               Z</a>
                </td>
            </tr>
        </table>
        <button type="button" onclick="copydiv();">Test</button>
    </body>
</html>

Все равно должно быть быстрее.

0 голосов
/ 13 марта 2012

У меня сейчас только IE8 с эмуляцией IE7, но я уверен, что white-space не работает, потому что ваш документ в quirksmode.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...