Javascript-форум (https://javascript.ru/forum/)
-   Общие вопросы Javascript (https://javascript.ru/forum/misc/)
-   -   Selection / Range (https://javascript.ru/forum/misc/27388-selection-range.html)

Антон Крамолов 11.04.2012 17:27

Selection / Range
 
function extend(obj, hash) {      
                for (var k in hash) {
                    if (hash.hasOwnProperty(k)) {
                        obj[k] = hash[k];
                    }
                }
            }
    
            function clone(obj) {
                return extend({}, obj);
            }
            
            function create(tag, props) {
                var el = document.createElement(tag);
                extend(el, props);
                return el;
            }
            
            document.onmouseup = function() {              
                var sel = window.getSelection();
                var txt = sel.toString();
                if (txt.trim()) {
                    var rng = sel.getRangeAt(0);                 
                    var el = create('strong', {innerHTML: txt});
                    rng.deleteContents();
                    rng.insertNode(el);                  
                    rng.selectNode(el);
                }
            }


Выделяешь текст, отпускаешь ЛКМ, текст становится жирным. Но! В браузере Opera выделяется не тот текст, в FF работает всё как надо, в Chrome ничего не выделяется вообще. Как сделать чтобы работало в этих трёх браузерах?

Живой пример

Octane 11.04.2012 18:15

selectNode не должен никак влиять на визуальное выделение, он устанавливает границы для конкретного range-объекта, для установки выделения в тесте используйте метод addRange объекта, который возвращает getSelection.

habrahabr.ru/post/55922/

Антон Крамолов 11.04.2012 18:33

function extend(obj, hash) {      
                for (var key in hash) {
                    if (hash.hasOwnProperty(key)) {
                        obj[key] = hash[key];
                    }
                }
            }
            
            function create(tag, props) {
                var el = document.createElement(tag);
                extend(el, props);
                return el;
            }
            
            function select(node) {
                var rng = document.createRange();
                rng.selectNode(node);
                var sel = window.getSelection();
                sel.addRange(rng);
            }
            
            document.onmouseup = function() {              
                var sel = window.getSelection();
                var txt = sel.toString();
                if (txt.trim()) {
                    var rng = sel.getRangeAt(0);                 
                    var el = create('strong', {innerHTML: txt});
                    rng.deleteContents();
                    rng.insertNode(el); // добавил ноду
                    sel.removeRange(rng); // удалил range
                    select(el); // выбрал ноду
                }
            }


http://pastehtml.com/view/buev3zsg0.html не работает в опере и безногом. в фуфлофоксе все ок, как и раньше. что не так?

Octane 11.04.2012 18:42

Не могу сейчас сам попробовать. Может быть зря removeAllRanges убрали или попробуйте отдельно установить начало и конец range-объекта. Или, наверное, выделение сбрасывается, потому что за mouseup следует click.

Антон Крамолов 11.04.2012 18:43

Кстати гавнохром вообще не запоминает выделения

Антон Крамолов 11.04.2012 18:45

Они сбрасываются только в хроме, в опере выделяет неправельно, в лисе работает

Антон Крамолов 11.04.2012 18:55

// так убирает выделение в Opere, в безногом ублюдке вообще выделение всегда пропадает
          document.onmouseup = function() {              
                var sel = window.getSelection();
                var txt = sel.toString();
                if (txt.trim()) {
                    var rng = sel.getRangeAt(0);
                    sel.removeAllRanges();
                }
            }

            // а так нет(Опера)
            document.onmouseup = function() {              
                var sel = window.getSelection();
                var txt = sel.toString();
                if (txt.trim()) {
                    var rng = sel.getRangeAt(0);
                    var el = create('strong', {innerHTML: txt});
                    rng.deleteContents();
                    rng.insertNode(el);
                    sel.removeAllRanges();
                }
            }

Octane 11.04.2012 19:02

Попробуйте получать selection по mouseup и выделять range по onclick.

Антон Крамолов 11.04.2012 19:55

document.onmouseup = function() {              
    var sel = window.getSelection();
    var txt = sel + '';
    if (txt.trim()) {
        var rng = sel.getRangeAt(0);
        var el = create('strong');
        sel.removeAllRanges(); // Так убирает выделенное, но где логика?
        el.appendChild(rng.extractContents());
        rng.insertNode(el);
        // А после - нет.
        // sel.removeAllRanges();
    }
}

Антон Крамолов 11.04.2012 20:11

<!DOCTYPE html>
<html>
    <head>
        <meta charset="utf-8" />
        <title></title>
        <script type="text/javascript">
            
            function extend(obj, hash) {      
                for (var key in hash) {
                    if (hash.hasOwnProperty(key)) {
                        obj[key] = hash[key];
                    }
                }
            }
            
            function create(tag, props) {
                var el = document.createElement(tag);
                extend(el, props);
                return el;
            }
                      
            document.onmouseup = function() {              
                var sel = window.getSelection();
                var txt = sel + '';
                if (txt.trim()) {
                    var rng = sel.getRangeAt(0);
                    var node = create('span');
                    node.style.cssText = 'font-weight: bold';
                    sel.removeAllRanges();
                    node.appendChild(rng.extractContents());
                    rng.insertNode(node);
                    rng.selectNode(node);
                    sel.addRange(rng);
                }
            }
            
        </script>
    </head>
    <body>
        <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod <em>tempor</em> incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</p>
    </body>
</html>


Вот так работает в FF, Chrom'е. В Oper'е выделяет неправильно.

Антон Крамолов 11.04.2012 20:22

Странный баг Оперы выделяет не все оставляет несколько символов невыделенными

В ФФ все нормально

Антон Крамолов 11.04.2012 20:24

// Если же вызвать алерт, то все правильно выделять начинает
            document.onmouseup = function() {              
                var sel = window.getSelection();
                if ((sel + '').trim()) {
                    alert(1);
                    var rng = sel.getRangeAt(0);
                    var node = create('span');
                    node.style.cssText = 'font-weight: bold';
                    sel.removeAllRanges();
                    node.appendChild(rng.extractContents());
                    rng.insertNode(node);
                    rng.selectNode(node);
                    sel.addRange(rng);
                }
            }


Как решить подобную проблему?


Часовой пояс GMT +3, время: 04:27.