Вы замечаете ошибку, когда Gecko / Firefox и Presto / Opera неправильно выбирают узел, в котором щелкнул курсор мыши, хотя и не выбрали. Чего ждать? Случается так, что если щелчок регистрируется меньше, чем ПОЛОВИНА символа (хотя больше, чем 0 пикселей), он ВИЗУАЛЬНО не выбирается ОДНАКО Firefox и Opera по-прежнему выбирают сам узел! Trident / IE и WebKit (Chrome / Safari) этого не делают.
Я некоторое время боролся с этой ошибкой, подал ошибку в Mozilla (не помню, делал ли я это с Opera, так как это было в прошлом году), и сегодня, наконец, написал напрямую редакторам спецификации DOM4, спрашивая их реализовать разъяснение EXPLICIT для поставщиков браузеров о том, как определить startContainer
.
Возможно адаптировать код, чтобы справиться с этим, однако у меня нет времени выписать весь код для вас.
Вот список методов, которые мы будем использовать ...
window.getSelection().getRangeAt(0).startContainer;
window.getSelection().anchorNode
window.getSelection().focusNode
ОЧЕНЬ важно помнить, что anchorNode - это НЕ ТОЛЬКО левая начальная позиция, хотя НАЧАЛЬНЫЙ ЩЕЛЧОК. Если пользователь щелкает по правой стороне текста и перетаскивает мышь влево, якорь заканчивается в правой части диапазона. Если пользователь нажимает на левую часть текста, а затем перетаскивает мышь вправо, якорь находится в левой части диапазона.
По сути, вы можете попытаться увидеть, не соответствует ли ни anchorNode, ни focusNode
EXPLICITLY startContainer
.
var sc = window.getSelection().getRangeAt(0).startContainer;
var an = window.getSelection().anchorNode
var fn = window.getSelection().focusNode
if (sc!==an && sc!==fn) {alert('startContainer bug encountered!');}
Даже если вам не нужен startContainer
во ВСЕХ ситуациях, вы все равно будете в конечном итоге ссылаться на него, поэтому лучше использовать объект для представления startContainer
, будь то если браузер правильно с первого раза (Trident / WebKit) или вы должны исправить его (Gecko / Presto).
Здесь немного сложно, особенно потому, что у разных людей разные цели и подходы, поэтому я постараюсь сделать следующее как можно более общим.
Либо вы можете определить правильные startContainer
, используя anchorNode
или focusNode
методы, либо вы можете использовать обнаружение объектов и методы, совместимые с W3C. Эти другие методы включают ....
window.getSelection().getRangeAt(0).startContainer
window.getSelection().getRangeAt(0).startContainer.parentNode
window.getSelection().getRangeAt(0).startContainer.previousSibling
window.getSelection().getRangeAt(0).startContainer.nextSibling
window.getSelection().getRangeAt(0).startContainer.childNodes[]
При работе с такими элементами стиля, как s
(удар), strong
, em
(выделение) и т. Д., Вы можете получить доступ к textNode с помощью firstChild
, если вокруг текста не заключено несколько элементов стиля. .
.nextSibling.firstChild
.nextSibling.firstChild.nodeValue
<em>textNode here</em>
Если вам сложно определить, какие методы доступны и в каких частях я рекомендую использовать оператор in
. В пример ...
for (i in window.getSelection())
{
document.getElementById('textarea_example').value = document.getElementById('textarea_example').value+'\n'+i;
}
... имейте в виду, что если вы находитесь внутри цикла, он может повторять параметры в вашем элементе textarea, поэтому CTRL + f для первого метода и стирайте его второй экземпляр вниз, чтобы сохранить только соответствующие методы.
Не забудьте использовать оповещение, и я часто использую несколько строк, чтобы показать несколько фрагментов информации одновременно, чтобы помочь мне определить, что у меня есть. В пример ...
var e1 = scp.nodeName;
if (scp.nextSibling) {var e2 = scp.nextSibling.nodeName;} else {var e2 = 'null';}
var e3 = sc.nodeName;
if (sc.nextSibling) {var e4 = sc.nextSibling.nodeName;} else {var e4 = 'null';}
alert(
'startContainer = '+window.getSelection().getRangeAt(0).startContainer.nodeName
+'\n\n'+
'startContainer = '+window.getSelection().getRangeAt(0).startContainer.nodeValue
+'\n\n'+
e1
+'\n\n'+
e2
+'\n\n'+
e3
+'\n\n'+
e4
+'\n\nanchorNode = '+
window.getSelection().anchorNode.nodeName
+'\n\n'+
window.getSelection().anchorNode.nodeValue
+'\n\nfocusNode = '+
window.getSelection().focusNode.nodeName
+'\n\n'+
window.getSelection().focusNode.nodeValue
);
if (e2=='#text') {alert('e2 = '+scp.nextSibling.nodeValue);}
if (e4=='#text') {alert('e4 = '+scp.nextSibling.nodeValue);}