Выделение: Range, TextRange и Selection

На этой странице помещена информация об объектах Range, TextRange и Selection. Информация была позаимствована у learn.javascript.ru, www.webmaster.ee, habrahabr.ru, developer.mozilla.org.

Range – это объект, соответствующий фрагменту документа, который может включать узлы и участки текста из этого документа. Наиболее подробно объект Range описан в спецификации DOM Range.

Чтобы понять о чем речь, обратимся к самому простому случаю Range, который будет подробно рассмотрен ниже – к выделениям. В приводимом ниже примере выделите несколько слов в предложении. Будет выводиться текстовое содержимое выделяемой области:

Соберем микс из жирности, курсива и ссылки и повыделяем здесь.

Но такие области можно создавать не только с помощью пользовательского выделения, но и из JavaScript-сценария, выполняя с ними определенные манипуляции. Однако, написать простой иллюстрирующий код сразу не выйдет, т.к. есть одно НО – Internet Explorer до версии 9. В Microsoft создали собственную реализацию – объект TextRange. Разберём каждую реализацию по-отдельности.

Range

Range состоит из двух граничных точек (boundary-points), соответствующих началу и концу области. Позиция любой граничной точки определяется в документе с помощью двух свойств: узел (node) и смещение (offset).

Контейнером (container) называют узел, содержащий граничную точку. Сам контейнер и все его предки называются родительскими контейнерами (ancestor containers) для граничной точки. Родительский контейнер, включающий обе граничные точки, называют корневым контейнером (root container).

На изображении выше граничные точки выделения лежат в текстовых узлах (#text1 и #text2), которые являются контейнерами. Для левой границы родительскими контейнерами являются #text1, H1, BODY, для правой – #text2, P, BODY. Общий родитель для обоих граничных точек – BODY, этот элемент является корневым контейнером.

Если контейнер является текстовым узлом, то смещение определяется в символах от начала DOM-узла. Если контейнер является элементом (Document, DocumentFragment, Element…), то смещение определяется в дочерних узлах.

Смотрим на иллюстрацию:

Пример Range

Граничные точки объекта Range s1 лежат в текстовых узлах, поэтому смещение задается в символах от начала узла. Для s2 граничные точки расставлены так, что включают весь абзац <p>Blah xyz</p>, поэтому контейнером является элемент BODY, и смещение считается в позициях дочерних узлов.

Объекты Range создаются с помощью вызова

document.createRange()

Объект при этом создается пустой, и граничные точки нужно задать далее его методами setStart и setEnd. Смотрим пример.

<div id="ex2" style="border:1px dashed #999; color:#666; background:#EEE; padding:2px 5px; margin:10px 0;">
 <h2 style="color:#333; margin:0; padding:0 0 7px 0; font:bold 15px Arial;">Соз|даем Range-объект</h2>
 <p style="color:#333; margin:0; font:13px Arial;">
От третье|го символа заголовка до десятого символа это абзаца.
</p>
</div>

<button onclick="alert1(domRangeCreate())"> 
 Создать Range и вывести его текст 
</button>
<p id="demo"></p>
<script>
function alert1(x) 
 {document.getElementById('demo').innerHTML = x.replace(/[\r\n]+/g,'<br>');}
function domRangeCreate() {
 // Найдем корневой контейнер
 var root = document.getElementById('ex2');
 // Найдем контейнеры граничных точек (в данном случае тестовые)
 var start = root.getElementsByTagName('h2')[0].firstChild;
 var end = root.getElementsByTagName('p')[0].firstChild;
 if (document.createRange) {
   // Создаем Range
    var rng = document.createRange();
  // Задаем верхнюю граничную точку, передав контейнер и смещение
    rng.setStart(start, 3);
  // Аналогично для нижней границы
   rng.setEnd(end, 10);
  // Теперь мы можем вернуть текст, который содержится в полученной области
   return rng.toString();
  } else { return 'Вероятно, у вас IE8-';  }
 }
</script>

свойства и методы Range

collapsed

Свойство collapsed вернет true, если граничные точки имеют одинаковые контейнеры и смещение (false в противном случае).

Синтаксис

// boolean, чтение и изменение

rng.collapsed [ = true|false ]

commonAncestorContainer

Свойство commonAncestorContainer возвращает ссылку на узел в дереве документа, в котором расположены начальная и конечная точка диапазона. Нередко получается, что начальная точка области находится в одном узле, а конечная - в другом- В этом случае обобщённый узел в большинстве случаев состоит из обоих узлов (в некоторых случаях это узел document.body). В спецификации W3C DOM разделяемый обобщенный узел называется корневым узлом области (термин, который предоставляет больше информации).

Синтаксис

// ссылка на объект узла,  чтение и изменение

rng.commonAncestorContainer [ = ссылкаНаОбъектУзла ]

startContainer, endContainer

Свойства startContainer и endContainer возвращают ссылку на узел дерева иерархической структуры документа, содержащим начальную и конечную точку области, соответственно.

Синтаксис

// ссылка на объект узла,  чтение и изменение

rng.startContainer [ = ссылкаНаОбъектУзла ]

rng.endContainer   [ = ссылкаНаОбъектУзла ]

Комментарии

Имейте в виду, объектная модель автоматически рассчитывает размер контейнера, сам же контейнер может и не соответствовать необходимой ссылке, используемой для установки начальной и конечной точек области. Например, при использовании метода selectNode() для установки начальной и конечной точки области, окружающей необходимый узел, контейнеры конечных точек наиболее вероятно будут попадать в следующие по уровню узлы. Таким образом, если сначала необходимо расширить область для включения в нее узла, содержащего текущую начальную точку, необходимо использовать значение, возвращаемое свойством startContainer, в качестве параметра метода setStartBefore():

rng.setStartBefore(rng.startContainer)

startOffset, endOffset

Свойства startOffset и endOffset возвращают целочисленное значение количества символов или узлов, которое определяет расположение начальной и конечной точки области, соответственно. Эти смещения указаны для узлов, выполняющих роли контейнеров для области.

Синтаксис

// Целое число,  чтение и изменение

rng.startOffset [ = смещение ]

rng.endOffset   [ = смещение ]

Описание, комментарии, примеры

Когда граница области находится на границе узла (или лучше сказать между узлами), возвращаемое целое число задает количество узлов (отсчет начинается с нуля от граничного контейнера). Однако, когда граница области находится посредине текстового узла, возвращаемое целое число представляет собой индекс символа внутри этого узла. Тот факт, что каждая граница имеют свою систему измерения (символы или узлы, в зависимости от используемых контейнеров), может привести к путанице, если не быть достаточно внимательным. При этом возвращаемое целое число для конечной точки может быть меньшим, нежели значение для начальной точки. Давайте рассмотрим следующие вложенные элементы:

<P> This paragraph has an emphasized segment.</P>

Следующий оператор устанавливает значение начальной точки области внутри первого узла, а конечную точку области в закрывающем элементе ем узла:

var rng = document.createRange()
rng.setStart(document.getElementById("myP").firstChild, 19);
rng.setEndAfter(document.getElementById("myEM"));

Используя полужирный шрифт для представления текста области и символ вертикальной черты ( | ) для определения границ в пределах узлов, можно достаточно просто представить, как выполняется описанный выше сценарий:

<P ID="myP"> This paragraph has |an emphasized segment.</P>

Поскольку начало области находится в текстовом узле (первый дочерний узел элемента Р), значение startOffset равно 19; оно определяет расположение символа а относительно an относительно начала узла, его содержащего. Однако конечная точка находится в конце элемента ЕМ. Сценарий распознает эту точку как границу узла и поэтому осуществляет подсчет значения endOffset внутри содержимого внешнего контейнера- элемента Р. Значение endOffset равно 2 (текстовый узел элемента Р имеет индекс 0; элемент ем имеет индекс 1; конечная точка находится в начале последнего текстового узла элемента Р, имеющего индекс 2).

При создании сценариев используются значения endOffset и startOffset достаточно часто; также часто используются свойства endContainer и startContainer для получения целочисленных значений смещения

setStart(), setEnd()

Методы setStart() и setEnd()) задают контейнер (ссылка на узел) и смещение (целочисленное значение) для соответствующих граничных точек.

Синтаксис

rng.setStart (ссылкаНаУзел, смещение)

rng.setEnd   (ссылкаНаУзел, смещение)

Параметры

ссылкаНаУзел
 Ссылка на узел. Эта ссылка может указывать на элемент или текстовый узел.
смещение
Если первый параметр является узлом элемента, смещение подсчитывается как приращение дочерних узлов внутри определенного элемента узла. Однако, если первый параметр представляет собой текстовый узел, то смещение подсчитывается как приращение Символов внутри текстового узла.

Комментарии

При определении начальной и конечной точек области с помощью этих методов не накладываются никакие ограничения на симметричность границ области. Одна из границ может быть определена относительно текстовое узла, а другая - относительно узла элемента, или наоборот, Для задания конечной точки области, равной последнему узлу или символу внутри текстового узла (в зависимости от единиц измерения параметра смещения), используйте свойство length. Например:
var nodeRef = document.getElementById("myP").lastChild;
rng.setEnd(nodeRef.nodeValue.length);

setStartBefore(), setStartAfter(), setEndBefore(), setEndAfter()

Методы setStartBefore(), setStartAfter(), setEndBefore(), setEndAfter() принимают в качестве единственного аргумента ссылку на узел и устанавливают граничные точки в соответствии с естественной границей переданного узла.

Синтаксис

rng.setStartAfter  (ссылкаНаУзел)

rng.serStartBefore (ссылкаНаУзел)

rng.setEndAfter    (ссылкаНаУзел)

rng.setEndBefore   (ссылкаНаУзел)

Комментарии

Начальную и конечную точки текстовой области можно задавать в соответствии с существующими границами узла с помощью этих четырех методов. Ключевые слова before и after в названиях методов используются для того, чтобы определить, какую из границ узла необходимо использовать в качестве границы области- Например, применение методов setStartBefore() и setEndAfter() для одного и того же узла элемента в качестве параметра аналогично использованию метода selectNode() для того же элемента. В качестве параметра любого из этих методов можно определить текстовый узел. Однако поскольку эти методы оперируют границами исключительно узлов, значения смещения всегда определяются с учетом расположения узла, а не символа.

Возьмите на заметку, что границы области необязательно должны быть симметричными, другими словами, одна граница может располагаться внутри одного узла, а другая-внутри другого.

Пример

<span id="s1">First</span>
<span id="s2">Second</span>
var rng = document.createRange();
// Установит верхнюю граничную точку по левой границе спана #s1
rng.setStartBefore(document.getElementById('s1'));
// Установит нижнюю граничную точку по правой границе спана #s2
rng.setEndAfter(document.getElementById('s2'));

selectNode(), selectNodeContents()

Методы selectNode() и selectNodeContents() позволяют создать объект Range по границам узла, ссылку на который они принимают в качестве единственного аргумента.

Синтаксис

rng.selectNode  (ссылкаНаУзел)

rng.selectNodeContents (ссылкаНаУзел)

Комментарии

Методы selectNode() и selectNodeContents() - это наиболее удобные методы для задания начальной и конечной точек, между которыми размещается узел или его содержимое. Тип узла, который применяемся в качестве параметра в обоих методах (текстовый узел или узел элемента), зависит от контейнера области и единиц измерения смещения точек.

При использовании selectNode передаваемый узел также войдет в Range, в то время как selectNodeContents создаст объект только из содержимого узла:

collapse()

Метод collapse() объединяет граничные точки объекта Range. В качестве единственного аргумента принимает булево значение (true – для объединения в верхней точке, false – в нижней). По-умолчанию true.

Синтаксис

rng.collapse ( [ true|false ] )

toString()

Метод toString() вернет текстовое содержимое объекта Range.

Синтаксис

rng.toString ()

Возвращаемое значение

Строка, представляющая текстовое содержимое объекта Range.

cloneContents()

Метод cloneContents() вернет копию содержимого объекта Range в виде фрагмента документа.

Синтаксис

rng.cloneContents ()

cloneRange()

Метод cloneRange() вернет копию самого объекта Range.

Синтаксис

rng.cloneRange ()

deleteContents()

Метод deleteContents() удаляет всё содержимое объекта Range.

Синтаксис

rng.deleteContents ()

detach()

Метод detach() извлекает текущий объект из DOM, так что на него больше нельзя сослаться.

Синтаксис

rng.detach ()

insertNode()

Метод insertNode() принимает в качестве единственного аргумента ссылку на узел (или фрагмент документа) и вставляет его в содержимое объекта Range в начальной точке.

Синтаксис

rng.insertNode (ссылкаНаУзел)

extractContents()

Методы extractContents() вырезает содержимое объекта Range и возвращает ссылку на полученный фрагмент документа.

Синтаксис

rng.extractContents ()

Возвращаемое значение

ссылка на узел documentFragment

surroundContents()

Метод surroundContents помещает всё содержимое текущего объекта Range в новый родительский элемент, ссылка на который принимается в качестве единственного аргумента.

Синтаксис

rng.surroundContents (ссылкаНаУзел)

Пример

Для примера решим небольшую задачку. Найдём в текстовом узле фразу и подсветим её голубым фоном.

<div id="ex3" style="border:1px dashed #999; color:#666; background:#EEE; padding:2px 5px; margin:10px 0;">
    Найдем в этом тексте слово "Abuela" и подсветим его синим фоном
</div>
<div>
  <input onclick="domRangehighlight('Abuela'); this.style.display = 'none';" type="button" value="Найти!">
</div>
<script>
function domRangehighlight(text) {
 var root = document.getElementById('ex3').firstChild;
 var content = root.nodeValue;
 if (~content.indexOf(text)) {
   if (document.createRange) {
     var rng = document.createRange();
     rng.setStart(root, content.indexOf(text));
     rng.setEnd(root, content.indexOf(text) + text.length);
     var highlightDiv = document.createElement('span');
     highlightDiv.style.backgroundColor = '#00ffff';
     rng.surroundContents(highlightDiv);
   } else alert('Вероятно, у вас IE8-');
 } else alert('Совпадений не найдено');   }
</script>

TextRange

Объект TextRange в реализации MSIE – это текстовый диапазон нулевой и более длины. У данного диапазона также есть свои границы, «перемещать» которые можно на целое число текстовых единиц: character(символ), word (слово), sentence (предложение). То есть можно взять и сдвинуть границу на 2(5, 8 и т.д.) слова (символа, предложения) вправо (влево). При этом у объекта сохраняются данные о HTML-содержимом диапазона и есть методы взаимодействия с DOM.

Объект TextRange создается с помощью метода createTextRange, который можно вызывать в контексте элементов BODY, BUTTON, INPUT (большинство типов), TEXTAREA.

Рассмотрим свойства и методы объекта TextRange (не все, только самые необходимые):

Также к TextRange применимы команды метода execCommand, который умеет делать текст жирным, курсивным, копировать его в буфер обмена (только IE) и т.п.

Для закрепления сделаем задачку по поиску текстового содержимого, аналогичную той, что была выше:

<div id="ex4" style="border:1px dashed #999; color:#666; background:#EEE; padding:2px 5px; margin:10px 0;">
 Найдем в этом тексте слово "Abuela" и подсветим его голубым фоном
</div>
<div>
  <input onclick="ieTextRangeHighlight('Abuela'); this.style.display = 'none';" type="button" value="Найти!">
</div>
<script>
function ieTextRangeHighlight(text) {
 var root = document.getElementById('ex4');
 var content = root.firstChild.nodeValue;
 if (~content.indexOf(text)) {
   if (document.body.createTextRange) {
     var rng = document.body.createTextRange();
     rng.moveToElementText(root);
     if (rng.findText(text))
       rng.pasteHTML('<span style="background:#00ffff;">' + text + '</span>');
   } else alert('Вероятно, у вас не IE, смотрите реализацию Range выше');
 } else alert('Совпадений не найдено');  }
</script>

Selection

Всем знакомо выделение элементов на странице, когда, зажав левую кнопку мыши и передвигая курсор, мы выделяем нужный фрагмент. Или зажимаем Shift и жмём на стрелочки клавиатуры. Или еще как-то, неважно. В данной части статьи мы кроссбраузерно научимся решать две задачи: получать пользовательское выделение и устанавливать собственное.

Получаем пользовательское выделение

Эту задачу мы уже решали в самом начале статьи в примере с миксом. Теперь рассмотрим код:

<div id="demoMix" onmouseup="alert(FgetText())" 
        style="border:1px dashed #999; color:#666; background:#EEE; padding:2px 5px; margin:10px 0;">
Соберем микс из <b>жирности</b>, <em>курсива</em> и <a href="javascript:void(0)">ссылки</a> и повыделяем здесь.
</div>
<script>
function FgetText() {
  var txt = '';
  if (txt = window.getSelection) { // Не IE, используем метод getSelection
    txt = window.getSelection().toString();
  } else { // IE, используем объект selection
    txt = document.selection.createRange().text;
  }
  return txt; }
</script>

Все браузеры, кроме IE8- поддерживают метод window.getSelection() , который возвращает объект Selection, схожий с рассмотренным ранее Range. У этого объекта есть точка начала выделения (anchor) и фокусная точка окончания (focus). Точки могут совпадать. Рассмотрим свойства и методы объекта Selection:

IE предоставляет собственный интерфейс взаимодействия с выделениями – объект selection в контексте document. Для работы с этим объектом используются следующие методы:

Установка собственного выделения

Допустим, вам хочется, чтобы какой-то текстовый фрагмент на странице был выделен, как пользовательское выделение. Это нужно при клиентской реализации поиска по странице и некоторых других задач.

Проще всего решить эту задачу следующим образом:

  1. Создать объект Range (TextRange для IE8-).
  2. Перевести полученный объект в выделение.

Смотрим реализацию:

<div id="ex5" style="border:1px dashed #999; color:#666; background:#EEE; padding:2px 5px; margin:10px 0;">
  Снова будем выделять <span>Abuela</span>, на этот раз без поиска.
</div>
<div>
  <input onclick="setSelection()" type="button" value=" Выделить «Abuela» ">
  <input onclick="clearSelection()" type="button" value=" Снять выделение ">
</div>
<script>
function setSelection() {  // Выделить
  var target = document.getElementById('ex5').getElementsByTagName('span')[0];
  var rng, sel;
  if (document.createRange)
   { rng = document.createRange();
     rng.selectNode(target)
     sel = window.getSelection();
     sel.removeAllRanges();
     sel.addRange(rng);
    } else
   { var rng = document.body.createTextRange();
     rng.moveToElementText(target);
     rng.select();
   }      }

function clearSelection() { // Снять выделение
  try {
    // современный объект Selection
    window.getSelection().removeAllRanges();
  } catch (e) {
    // для IE8-
    document.selection.empty();
  }  }
</script>

Совместимость

Есть библиотеки, которые «исправляют» объект TextRange, добавляя ему нужные свойства из Range.

Здесь предлагается маленькая библиотека fixIERangeObject.js.

<script src="fixIERangeObject.js"></script>
<script>
 function test() 
  { var range = getRangeObject();
    if (range) 
     { var t = "<em>range</em>: «" + range + '»<br>' +
       "<em>startContainer</em>: " + range.startContainer.nodeValue + '<br>' +
       "<em>startOffset</em>: " + range.startOffset + '<br>' +
       "<em>endOffset</em>: " + range.endOffset;
      document.getElementById('demo').innerHTML = t;
      } else { alert('Сначала выделите текст'); }
    }
  </script>

<p>Выделите текст:</p>
<pre>
Библиотека fixIERangeObject "исправляет" объект TextRange,
добавляя ему нужные свойства из Range.</pre>
<input type="button" value=" Вывести выделение и свойства startContainer, startOffset, endOffset " onclick="test();" />
<p id="demo"></p>

Вырезать и копировать в буффер обмена

Начиная с IE10 добавлена поддержка команд «Копировать» и «Вырезать» с помощью метода Document.execCommand().

Любой текст выделенный в браузере при выполнении одной из этих команд будет скопирован или вырезан в буфер обмена пользователя. Это позволяет предложить пользователю простой метод выделить часть текста и скопировать в буфер обмена.

Примеры

Для примера, давайте добавим кнопку которая скопирует email адрес в буфер обмена.
Мы добавим email адрес, в наш HTML, с кнопкой клик по которой будет инициировать копирование email.

Добавим обработчик клика по кнопке, который выделит email из содержимого ссылки js-emaillink, выполнит команду копирования, так что бы адрес электронной почты оказался в буфере пользователя и после этого снять выделение с электронной почты, так что пользователь даже не увидит выделение.

В этом примере используется метод document.queryCommandEnabled(), который проверяет возможность выполнения определенной команды.

<p>Мой E-Mail: <a class="js-emaillink" href="mailto:matt@example.co.uk">matt@example.co.uk</a></p>

<p><button  class="js-emailcopybtn"> Скопировать email-адрес в буфер обмена </button></p>
<input id="demo" type="hidden" size='40' placeholder="Скопировать из буфера обмена (Ctrl+V) ">
<script>
var demo = document.getElementById('demo');
var copyEmailBtn = document.querySelector('.js-emailcopybtn'); 
try { copyEmailBtn.disabled = !document.queryCommandSupported('copy'); }
catch(err) { copyEmailBtn.disabled = true;}
if (!copyEmailBtn.disabled) {
 copyEmailBtn.addEventListener('click', function(event) {  
  // Выборка ссылки с электронной почтой 
  var emailLink = document.querySelector('.js-emaillink');  
  var range = document.createRange();  
  range.selectNode(emailLink);  
  window.getSelection().addRange(range);  
  // Теперь, когда мы выбрали текст ссылки, выполним команду копирования
  if (document.execCommand('copy')) 
     {demo.type="text"; demo.focus();}; 
    
  // Снятие выделения - ВНИМАНИЕ: вы должны использовать
  // removeRange(range) когда это возможно
  window.getSelection().removeAllRanges();
}); }
</script>

Здесь используется метод window.getSelection(), что бы программно выделить текст внутри ссылки, который мы хотим скопировать в буфер обмена пользователя. После вызова document.execCommand() мы можем снять выделение с помощью window.getSelection().removeAllRanges().

Если вы хотите проверить что все прошло успешно, то вы можете рассмотреть результат возвращаемый функцией document.execCommand(). Результат будет false если функция не поддерживается или отключена.





Команда «вырезать» (cut) может быть использована для текстовых полей ввода, там, где вы хотите удалить текст и поместить этот текст в буфер обмена.

Использование textarea и кнопки:

<p><textarea class="js-cuttextarea" cols='80' rows='4'>
 Команда «вырезать» может быть использована для текстовых полей ввода, там,
 где вы хотите удалить текст и поместить этот текст в буфер обмена.
</textarea></p>
  
<p><button class="js-textareacutbtn"> 
 Вырезать  Textarea и скопировать в буФер обмена. 
</button></p>
<textarea id="demo" style="display:none" cols='80'  rows='4' 
   placeholder="Скопировать из буфера обмена (Ctrl+V) ">
</textarea>
<script>
var demo = document.getElementById('demo');
var cutTextareaBtn = document.querySelector('.js-textareacutbtn');
try { cutTextareaBtn.disabled = !document.queryCommandSupported('cut'); }
catch(err) { cutTextareaBtn.disabled = true;}
if (!cutTextareaBtn.disabled) {
cutTextareaBtn.addEventListener('click', function(event) {  
  var cutTextarea = document.querySelector('.js-cuttextarea');  
  cutTextarea.select();
  if ( document.execCommand('cut') )
    { demo.style.display = ''; demo.focus(); }
}); }
</script>

execCommand()

Метод execCommand() выполняет одну из предопределённых операций над документом.

Синтаксис

document.execCommand ("aCommandName", aShowDefaultUI, aValueArgument)

Параметры

aCommandName

Наименование одной из комманд метода execCommand()
aShowDefaultUI

Необязательный. Логическое значение (true или false), определяющее, поддерживает ли комманда элементы пользовательского интерфейса
aValueArgument

Параметр комманды, если требуется.

Возвращаемое значение

true при успешном выполнении комманды; false в обратном случае.

queryCommandSupported()

Метод определяет, поддерживается ли комманда execCommand.

Синтаксис

document.queryCommandSupported ("aCommandName")

Параметры

aCommandName
  Наименование одной из комманд метода execCommand()

Возвращаемое значение

true если требуемая комманда может быть выполнена; false в обратном случае.

Комментарии

Перед вызовом document.execCommand() необходимо убедиться что эти API поддерживаются с помощью queryCommandSupported(). В примерах выше, по результатам проверки совместимости блокируется кнопка.

queryCommandEnabled()

Метод определяет, может ли комманда execCommand быть успешно выполнена при текущем состоянии документа.

Синтаксис

document.queryCommandEnabled ("aCommandName")

Параметры

aCommandName
  Наименование одной из комманд метода execCommand()

Возвращаемое значение

true если требуемая комманда может быть выполнена; false в обратном случае.

Комментарии

Отличие между queryCommandSupported() и queryCommandEnabled() в том, что команды «копировать» и «вырезать» могут поддерживаться браузером, но если текст не выделен, то они не будут доступны. Это удобно в том случае если вы не выбрали фрагмент текста программно и хотите что бы команда отработала ожидаемо, в противном случае показать сообщение пользователю.

Команды execCommand

Команды, которые поддерживаются Вашим браузером, выделены шрифтом.

2D-PositionКомманда, позволяющая пользователю передвигать абсолютно позиционированные элементы.
AbsolutePositionКомманда, устанавливающая свойство position данного элемента в значение "absolute".
backColorИзменить цвет фона документа. В режиме styleWithCss командой устанавливается цвет фона родительского блока. Необходима передача строкового значения цвета в качестве аргумента. (Internet Explorer таким образом устанавливает цвет фона текста.)
boldВключает/отключает выделение жирным bold отмеченного текста или начиная с места ввода тескта. (Internet Explorer ипсользует тег <strong>> вместо <b>.)
contentReadOnlyДелает содержимое документа либо неизменяемым либо редактируемым. Требуется передача булевого true/false в качестве аргумента. (Не поддерживается Internet Explorer.)
copyКопирует выделенное в буфер обмена. Возможность такого поведения отличается от браузера к браузеру и расширяется со временем. Следует проверить таблицу совместимости, чтобы убедиться в возможности использования.
createBookmarkКомманда, создающая "якорь" из выделенного фрагмента текста или возвращает имя "якоря" для выделенного фрагмента текста.
createLinkСоздает ссылку из выделения, если таковое имеется. Необходима передача HREF URI в качестве аргумента. URI должен содержать как минимум один символ, допускается пробельный. (Internet Explorer создаст ccылку и без URI.)
cutВырезает выделенное и помещает его в буфер обмена. Возможность такого поведения отличается от браузера к браузеру и расширяется со временем. Следует проверить таблицу совместимости, чтобы убедиться в возможности использования.
deleteУдаляет выделенное.
enableInlineTableEditingВключает/выключает возможность вставки и удаления строк/столбцов таблицы. (Не поддерживается Internet Explorer.)
enableObjectResizingВключает/выключает возможность изменения размера картинок и других объектов. (Не поддерживается Internet Explorer.)
fontNameИзменяет название шрифта для выделенного текста или с меств ввода текста. Требует передачи в качестве аргумента наименования шрифта (напр., "Arial") 
fontSizeИзменяет размер шрифта выделенного текста или с места ввода текста. Требует передачи в качестве аргумента размера шрифта (1-7).
foreColorИзменяет цвет шрифта выделенного текста или с места ввода текста. Требует передачи в качестве аргумента наименования шрифта.
formatBlockДобавляет тег HTML-блока вокруг строк, содержащих в себе выделенный текст, заменяя блочный элемент, содержащий такие строки если он существует (в Firefox, BLOCKQUOTE  является исключением - он обернет любой блочный элемент). Требует передачи в качестве аргумента наименования Тега. Теоретически может использоваться любой блочный тег (напр., "H1", "P", "DL", "BLOCKQUOTE"). (Internet Explorer поддерживает только теги заголовков H1 - H6, ADDRESS и PRE, которые должны также быть заключены в символы < >, как например: "<H1>".)
forwardDeleteУдаляет символ справа от курсора, так же как при нажатии на клавишу delete.
headingДобавляет тег заголовка вокруг выделенного текста либо в месте где установлен курсор.
Требует передачи строки имени тега в качестве аргумента. (то есть "H1", "H6"). (Не поддерживается в Internet Explorer и Safari)
hiliteColorИзменяет цвет фона для выделенного текста либо в месте где установлен курсор. Требует передачи цвета в качестве аргумента. UseCSS должен быть включен для работы этой функции. (Не поддерживается в Internet Explorer)
increaseFontSizeДобавляет тег BIG вокруг выделенного текста или на месте курсора. (Не поддерживается в Internet Explorer)
indentДобавляет отступ в строку в которой расположен курсор (или что-то выделено). В Firefox, если выделение охватывает несколько строк с разными уровнями отступа, будут сдвинуты только строки с наименьшим отступом.
insertBrOnReturnДобавляет тег :<br> или разбивает текущий эелемент на два блока. Не работает в Internet Explorer
insertButtonКомманда, вставляющая в документ кнопку(<BUTTON>).
insertHorizontalRuleВставляет горизонтальную линию на месте курсора (удаляет выделение).
insertHTMLВставляет HTML текст на месте курсора (удаляет выделенный текст). Требует передачи правильной HTML строки как аргумент. (Не поддерживается в Internet Explorer)
insertIFrameКомманда, вставляющая в документ "плавающий" фрейм.
insertImageВставляет изображение на место курсора (удаляет выделенный текст). Необходимо указывать ссылку на изображение в параметре "aValueArgument".  (Internet Explorer может создавать изображения с пустым SRC)
insertInputButtonКомманда, вставляющая в документ командную кнопку.
insertInputCheckboxКомманда, вставляющая в документ кнопку-"флажок".
insertInputFileUploadКомманда, вставляющая в документ элемент управления для отправки файла на сервер.
insertInputHiddenКомманда, вставляющая в документ скрытое поле.
insertInputImageКомманда, вставляющая в документ изображение как элемент управления.
insertInputPasswordКомманда, вставляющая в документ поле ввода пароля.
insertInputRadioКомманда, вставляющая в документ радиокнопку.
insertInputResetКомманда, вставляющая в документ кнопку сброса данных формы.
insertInputSubmitКомманда, вставляющая в документ кнопку отправки данных из формы на сервер.
insertInputTextКомманда, вставляющая в документ поле ввода текста.
insertMarqueeКомманда, вставляющая в документ прокручивающийся текст.
insertOrderedListКомманда, вставляющая в документ нумерованный список.
insertOrderedListСоздает пронумерованный список из выбранного или на месте курсора.
insertParagraphВставляет параграф вокруг выделения или для текущей строки. (Internet Explorer вставляет параграф в месте курсора и удалаяет выделенный текст)
insertSelectDropdownКомманда, вставляющая в документ выпадающий список.
insertSelectListboxКомманда, вставляющая в документ список.
insertTextВставляет простой текст в месте курсора или выделения (выделенный текст будет заменен).
insertTextAreaКомманда, вставляющая в документ область редактирования текста.
insertUnorderedListСоздает список из выбранного или на месте курсора.
italicПереключает курсив в месте курсора или выделения. (Internet Explorer использует теги <em> вместо <i>.)
justifyCenterЦентрирует строку в которой есть выделение или установлен курсор.
justifyFullВыравнивает строку в которой есть выделение или установлен курсор по ширине.
justifyLeftВыравнивает строку в которой есть выделение или установлен курсор по левому краю.
justifyRightВыравнивает строку в которой есть выделение или установлен курсор по правому краю.
liveResizeКомманда, включающая или выключающая режим мгновенного("живого") отображения размеров или местоположения элементов страницы во время изменения размеров последней.
multipleSelectionКомманда, позволяющая или запрещающая выделение сразу нескольких элементов web-строницы.
outdentДобавляет выступ для строки в которой расположен курсор (или что-то выделено).
overWriteКомманда, переключающая режим ввода текста между вставкой и заменой.
pasteВставляет данные из буфера обмена в место курсора или выделения (последнее заменяется). Доступ к буферу обмена должен быть включен в файле user.js
printКомманда, открывающая диалоговое окно "Печать".
redoПовтор последнего действия. (Если было отменено с помощью undo или ctrl+z)
refreshКомманда, перезагружающая данный документ с сервера.
removeFormatОчищает форматирование для выделенного.
saveAsКомманда, сохраняющая текущую web-страницу в файл.
selectAllВыделяет всё в редактируемом документе.
strikeThroughПереключает зачеркивание текста для выделенния или на месте курсора.
styleWithCSSПереключает режим стилизации HTML и CSS для генерируемой разметки. Может принимать только булевые значения true/false, т.е. true модифицирует/генерирует атрибуты стиля в разметке, false генерирует элементы форматирования.
subscriptПереключает нижний индекс для выбранного или на месте курсора.
superscriptПереключает верхний индекс для выбранного или на месте курсора.
unBookmarkКомманда, удаляющая элемент закладки из текущего фрагмента выделенного текста.
underlineПереключает подчёркивание для выбранного или на месте курсора.
undoОтмена последнего действия.
unlinkУдаляет ссылку или якорь для выбранной ссылки/якоря
unselectКомманда, очищающая данный фрагмент выделенного текста.