Модераторы: Sardar, Aliance
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Теряется пользовательское выделение в Gecko&Opera 
:(
    Опции темы
Burrr
Дата 19.10.2006, 15:43 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 459
Регистрация: 4.9.2005

Репутация: 10
Всего: 20



Моя цель, аккуратно превратить такую ноду:
<p id="cost">It's first</br> row</p>
в такую:
<p id="cost"><span>It's first</span></br> row</p>
При этом не должно теряться пользовательское выделение (что к сожалению происходит при использовании innerHTML)!!!
Это только примерный код, на самом деле с нодами может происходит что-угодно (удаление, замена, добавление), НО количество текста приэтом НЕ МЕНЯЕТСЯ!
Теперь код:
Код

<body>
<script type="text/javascript">
if (window.HTMLElement) {
    if (!HTMLElement.prototype.removeNode) {
        HTMLElement.prototype.removeNode = function(bool) {
            var p = this.parentNode;
            if (!bool) while(this.childNodes.length > 0) p.insertBefore(this.firstChild, this);
            p.removeChild(this);
        }
    }
}
var flag = false;
function test() {
    if (flag) return;
    var parent, left, br, right, r, span, sel, rng;
    parent = document.getElementById("cost");
    left = parent.childNodes[0];
    br = parent.childNodes[1];
    right = parent.childNodes[2];
    // ------------ get selection --------------
    if (document.selection) { // IE
        rng = document.selection.createRange();
    } else { // Gecko & Opera
        sel = window.getSelection();
        rng = (sel.length > 0) ? sel.getRangeAt(sel.rangeCount - 1) : null;
    }
    // ------------- set range -------------
    if (document.createRange) { // Gecko & Opera
        span = document.createElement("SPAN");
        r = document.createRange();
        r.selectNode(left);
    } else { // IE
        r = document.body.createTextRange();
        r.moveToElementText(parent);
        r.findText(left.nodeValue);
    }
    flag = true;
    (r.pasteHTML) ? r.pasteHTML("<SPAN>" + r.text + "</SPAN>") : r.surroundContents(span);
}
function getCode() {
    alert(document.getElementById("container").innerHTML);
}
</script>
<div id="container">
    <p id="cost">It's first</br> row</p>
</div>
<br>
<input type="button" value="Over here!" onmouseover="test()">&nbsp;&nbsp;&nbsp;<input type="button" value="Get code!" onclick="getCode()">
</body>

В ИЕ всё в порядке, пользовательское выделение (то что он выделил мышью и просто поставил фокус) остается на своем месте, а вот в Гекко и Опере оно теряется smile
Как это побороть?
 smile 
P.S.: почему-то не получается запостить в форум "JavaScript", кидаю сюда.

Если есть способ, как сохранить пользовательское выделение использую innerHTML - это будет просто замечательно!

Это сообщение отредактировал(а) Burrr - 19.10.2006, 16:11


--------------------
PM MAIL ICQ   Вверх
katka
Дата 19.10.2006, 15:52 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 164
Регистрация: 19.7.2004

Репутация: нет
Всего: 6



</br> это как?
--------------------
если с другом буду я, если с другом буду я, а медведь — без друга
PM MAIL WWW ICQ   Вверх
Burrr
Дата 19.10.2006, 15:56 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 459
Регистрация: 4.9.2005

Репутация: 10
Всего: 20



Цитата
</br> это как?

Это нормально ;).
<br> не является контейнером, поэтому его можно писать как в виде открывающего тэга - <br>
так и в виде закрывающего - </br>
Прошу дальше в этой теме это не обсуждать - offtopic.


--------------------
PM MAIL ICQ   Вверх
Nicholas_S
Дата 19.10.2006, 17:37 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 486
Регистрация: 12.10.2006
Где: Санкт-Петербург

Репутация: 5
Всего: 19



Привожу код для Firefox. Код не оптимален, можно чуток подсократить (например использовать метод cloneRange()).

Код

function test() {
    if (flag) return;
    var span, parent,  br, right, r, sel, rng, rngS=0, rngE=0;
    parent = document.getElementById("cost");
    left   = parent.childNodes[0];
    br     = parent.childNodes[1];
    right  = parent.childNodes[2];

    // ------------ get selection --------------
    if (document.selection)  // IE
        rng = document.selection.createRange();
    else  // Gecko & Opera
    { 
        sel = window.getSelection();
        rng = sel.rangeCount ? sel.getRangeAt(sel.rangeCount - 1) : null;
        if (rng)
        {
           rngS = rng.startOffset;
           rngE = rng.endOffset;
        }
    }

    // ------------- set range -------------
    if (document.createRange)  // Gecko & Opera
    { 
        span = document.createElement('SPAN');
        r = document.createRange();
        r.selectNode(left);
    } else  // IE
    { 
        r = document.body.createTextRange();
        r.moveToElementText(parent);
        r.findText(left.nodeValue);
    }

    flag = true;
    if (r.pasteHTML)
        r.pasteHTML("<SPAN>" + r.text + "</SPAN>");
    else
    {
        r.surroundContents(span);
        left = span.childNodes[0];
        s = window.getSelection();
        rng = document.createRange();
        rng.selectNode(left);
        rng.setStart(left, rngS);
        rng.setEnd(left, rngE);
        s.addRange(rng);    
    }
}

Кстати, в твоем коде у IE выделение теряется если из текста выделен только кусок. Посмотри.


--------------------
...все в мире относительно
PM   Вверх
12345c
Дата 19.10.2006, 18:49 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Круглый
****


Профиль
Группа: Vingrad developer
Сообщений: 2018
Регистрация: 26.12.2005
Где: наша не пропадала ?

Репутация: 57
Всего: 101



Действительно, выделение в IE имеет расширенные функции, но имеет мелкие недостатки, устранить которые можно через снятие положений границ с последующим их восстановлением по своей логике. Код резко увеличивается, что видно на примере работы с textarea при вставке bb-кодов.
PM WWW   Вверх
Burrr
Дата 20.10.2006, 11:22 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 459
Регистрация: 4.9.2005

Репутация: 10
Всего: 20



Nicholas_S, спасибо, +1
Не нашел в мане описание ф-ии addRange, можешь поделиться?

И как же всё-таки пофиксить это в Опере, кто-нибудь может кинуть код, который бы работал в ИЕ, Гекко, Опера 9+ ?


--------------------
PM MAIL ICQ   Вверх
Nicholas_S
Дата 20.10.2006, 11:36 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 486
Регистрация: 12.10.2006
Где: Санкт-Петербург

Репутация: 5
Всего: 19



Burrr, посмотри ресурс http://developer.mozilla.org/en/docs/DOM:Selection:addRange.
Вообще на нем много интересного, посещай по мере необходимости.  smile

Добавлено @ 11:44 
Burrr, нет проблем, амиго! Всего лишь 1 строку поправить для идентификации Оперы:
Код

function test() {
    if (flag) return;
    var span, parent,  br, right, r, sel, rng, rngS=0, rngE=0;
    parent = document.getElementById("cost");
    left   = parent.childNodes[0];
    br     = parent.childNodes[1];
    right  = parent.childNodes[2];
    // ------------ get selection --------------

    bOP = navigator.userAgent.toLowerCase().indexOf('opera')!=-1;

    if (document.selection && !bOP)  // IE
        rng = document.selection.createRange();
    else  // Gecko & Opera
    {
        sel = window.getSelection();
        rng = sel.rangeCount ? sel.getRangeAt(sel.rangeCount - 1) : null;
        if (rng)
        {
           rngS = rng.startOffset;
           rngE = rng.endOffset;
        }
    }
    // ------------- set range -------------
    if (document.createRange)  // Gecko & Opera
    {
        span = document.createElement('SPAN');
        r = document.createRange();
        r.selectNode(left);
    } else  // IE
    {
        r = document.body.createTextRange();
        r.moveToElementText(parent);
        r.findText(left.nodeValue);
    }
    flag = true;
    if (r.pasteHTML)
        r.pasteHTML("<SPAN>" + r.text + "</SPAN>");
    else
    {
        r.surroundContents(span);
        left = span.childNodes[0];
        s = window.getSelection();
        rng = document.createRange();
        rng.setStart(left, rngS);
        rng.setEnd(left, rngE);
        s.addRange(rng);
        rng.selectNode(left);
    }
}



--------------------
...все в мире относительно
PM   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Форум для вопросов, которые имеются в справочниках, но их поиск вызвал затруднения, или для разработчика требуется совет или просьба отыскать ошибку. Напоминаем: 1) чётко формулируйте вопрос, 2) приведите пример того, что уже сделано, 3) укажите явно, нужен работающий пример или подсказка о том, где найти информацию.
 
1 Пользователей читают эту тему (1 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | JavaScript: Общие вопросы | Следующая тема »


 




[ Время генерации скрипта: 0.1013 ]   [ Использовано запросов: 21 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.