Ошибка получения выделенного текста при использовании кнопки «sprited» и selection.createRange () в Internet Explorer - PullRequest
3 голосов
/ 26 января 2009

Я работаю над внедрением кнопок в любимом редакторе разметки WMD в Stackoverflow и столкнулся с странной ошибкой. Во всех версиях IE выделенный текст теряется при нажатии кнопки, поэтому, например, выделение блока текста и нажатие кнопки кода действует так, как если бы вы поместили курсор в конец выделения и нажали кнопку.

например. выделив это:

This
Is
Code

и нажав кнопку кода, вы получите:

This
Is
Code`enter code here`

Что действительно странно, так это то, что я оставил исходную панель без кнопок в , и она работает просто отлично. На самом деле ALL кнопки и код сочетаний клавиш используют один и тот же doClick(button) функционировать!

  • Неиспользованные кнопки в старом стиле: OK
  • Сочетания клавиш: ОК
  • Перекошенные кнопки в браузерах, отличных от IE: OK
  • Переброшенные кнопки в IE: WTF

Я изолировал проблему до вызова selection.createRange(), который ничего не находит только при нажатии на кнопку «sprited». Я попытался обойтись с помощью focus () и убедиться, что до doClick() произошло как можно меньше событий, но без радости. Сочетания клавиш, кажется, работают, потому что фокус никогда не теряется при вводе текстовой области. Кто-нибудь может подумать о взломе, который позволит мне каким-то образом собрать выделенный текст в IE?

Обработчик onclick выглядит так:

button.onmouseout = function(){
  this.style.backgroundPosition = this.XShift + " " + normalYShift;
};

button.onclick = function() {
  if (this.onmouseout) {
    this.onmouseout();
  }
  doClick(this);
}

Я пытался переместить вызов onmouseout после doClick на тот случай, если это привело к потере фокуса, но это не проблема.

EDIT:

Единственное, что кажется другим, - это то, что в исходном коде кнопки вы нажимаете на изображение. В коде sprited вы нажимаете на элемент списка <li> с установленным фоновым изображением. Возможно, он пытается выделить несуществующий текст в моем элементе списка?

/ EDIT

Фактический код находится в моем хранилище wmd на git в ветке button-cleanup.

Если вы вернетесь к фиксации 0d6d1b32bb42a6bd1d4ac4e409a19fdfe8f1ffcc, вы увидите обе панели кнопок. Верхняя часть взволнована и демонстрирует странное поведение. Нижняя содержит остатки оригинальной панели кнопок и работает нормально. Подозрительный код находится в функции setInputAreaSelectionStartEnd() в объекте TextareaState.

Еще одна вещь, которую я должен упомянуть, это то, что в настоящее время я пытаюсь сохранить элемент управления в чистом Javascript, поэтому я хотел бы избежать исправления этого с помощью внешней библиотеки, такой как jQuery, если это возможно.

Спасибо за вашу помощь!

Ответы [ 2 ]

4 голосов
/ 26 января 2009

Я знаю ответ на свой вопрос.

Кнопки с набранными ссылками реализованы с использованием списка HTML и CSS, где все элементы списка имеют фоновое изображение. Фоновое изображение перемещается с помощью CSS для отображения различных кнопок и состояний (например, выделения при наведении курсора мыши). Стандартные CSS-спрайты.

Это нормально работает в IE, за одним исключением: IE пытается выделить пустой текст списка, когда вы нажимаете кнопку «фон» на изображении. Выбор во входной текстовой области исчезает, и текущий выбор (который будет возвращен document.selection.createRange ()) перемещается в пустой текст в элементе списка.

Исправить это просто - я создал переменную для кэширования выделения и флага. В IE я кеширую выделение и устанавливаю флаг в обработчике mousedown. При обработке текста я проверяю наличие флага - если он установлен, я использую кэшированный диапазон вместо запроса document.selection.createRange ().

Вот некоторые фрагменты кода:

wmd.ieCachedRange = null;
wmd.ieRetardedClick = false;

if(global.isIE) {
  button.onmousedown =  function() { 
    wmd.ieRetardedClick = true;
    wmd.ieCachedRange = document.selection.createRange(); 
  };
}


var range;
if(wmd.ieRetardedClick && wmd.ieCachedRange) {
  range = wmd.ieCachedRange;
  wmd.ieRetardedClick = false;
}
else {
  range = doc.selection.createRange();
}

Решение состоит из нескольких строк кода и позволяет избежать возни с DOM и, возможно, создать проблемы с механизмом компоновки.

Спасибо за вашу помощь, Кристоф. Я придумал ответ, думая и гуглив о вашем ответе.

0 голосов
/ 26 января 2009

Вы должны blur() кнопку, прежде чем IE сможет выбрать что-либо еще на странице.

Можете ли вы предоставить минимальный пример (содержащий только соответствующий код), который воспроизводит ошибку?

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