Javascript.RU

Создать новую тему Ответ
 
Опции темы Искать в теме
  #1 (permalink)  
Старый 30.09.2015, 22:01
Профессор
Отправить личное сообщение для ТОТ_САМЫЙ Посмотреть профиль Найти все сообщения от ТОТ_САМЫЙ
 
Регистрация: 10.09.2015
Сообщений: 184

Выделение в браузерах
Ребят это баг или у меня руки кривые?

Задача:

1) сохранить выделение.
2) изменить значение текстовой ноды(эта процедура заставляет браузер сбросить выделение).
3) восстановить выделение.


Вот класс отвечающий за сохранение и восстановление выделения:

class Selection

	constructor: ->
		@ranges = []


	clear: ->
		@ranges = []


	save: ->
		@clear()
		selection = window.getSelection()
		for i in [0...selection.rangeCount]
			range = selection.getRangeAt(i)
			@ranges.push
				'startContainer': range.startContainer
				'startOffset': range.startOffset
				'endContainer': range.endContainer
				'endOffset': range.endOffset
		return


	restore: ->
		selection = window.getSelection()
		selection.removeAllRanges()
		for rangeData in @ranges
			range = document.createRange()
			range.setStart(rangeData.startContainer, rangeData.startOffset)
			range.setEnd(rangeData.endContainer, rangeData.endOffset)
			selection.addRange(range)
		return


Написал скрипт который меняет значение текстовой ноды каждые 300 миллисекунд, и пытаюсь до изменеиня делать сейв выделения, после изменения ноды делать рестор, в хроме и лисе все работает, в ишаке все работает.

А тепрь пытаюсь делать вот что, начинаю делать выделение мышкой и не отпускаю кнопку, дожидаюсь пока значение ноды изменится, иииии... О ЧУДО, после рестора, в хроме и лисе все работает, а в ишаке процесс выделения прерывается, и при дальнейшем движении мышки выделение остается на том же месте где мы рестор сделали.

И второй косяк, это когда мы в хроме ведем выделение в обратную сторону, то есть мышкой с конца текста вначало, и делаем сейв и рестор, тооо, выделение сбрасывается. Это вобще што за баги? неужели поведение этого API не описано в стандарте?

Так же основной собственно вопрос, существует ли какая-то возможность определить направление выделения? Чтобы хотя бы в хроме и лисе знать в какую сторону рестор делать чтобы он выделение не сбрасывал. Дело в том что при сейве у них стартОффсет и ендОффсет расположены всегда в одинаковом порядке, старт всегда меньше енд, несзависимо оттого в какую сторону мы мышкой ведем.

Последний раз редактировалось ТОТ_САМЫЙ, 30.09.2015 в 22:55.
Ответить с цитированием
  #2 (permalink)  
Старый 30.09.2015, 22:27
Профессор
Отправить личное сообщение для ТОТ_САМЫЙ Посмотреть профиль Найти все сообщения от ТОТ_САМЫЙ
 
Регистрация: 10.09.2015
Сообщений: 184

Оу, ну в общем как получить выделение в браузерах я нашел, то где кончается выделение показывается не в ренджах, а в селекшене

а именно

selection = getSelection()

// начало выделения
selection.anchorNode // нода 
selection.anchorOffset // символ

// конец выделения
selection.focusNode // нода 
selection.focusOffset // символ

Последний раз редактировалось ТОТ_САМЫЙ, 30.09.2015 в 23:56.
Ответить с цитированием
  #3 (permalink)  
Старый 30.09.2015, 23:59
Профессор
Отправить личное сообщение для ТОТ_САМЫЙ Посмотреть профиль Найти все сообщения от ТОТ_САМЫЙ
 
Регистрация: 10.09.2015
Сообщений: 184

В итоге я написал работающий класс который сохраняет как обычное так и реверсивное выделение:

class Selection

	constructor: ->
		@anchorNode = null
		@anchorOffset = null
		@focusNode = null
		@focusOffset = null


	clear: ->
		@anchorNode = null
		@anchorOffset = null
		@focusNode = null
		@focusOffset = null


	save: ->
		selection = window.getSelection()
		@anchorNode = selection.anchorNode
		@anchorOffset = selection.anchorOffset
		@focusNode = selection.focusNode
		@focusOffset = selection.focusOffset
		return


	restore: ->
		selection = window.getSelection()
		selection.removeAllRanges()
		unless @anchorNode then return
		range = document.createRange()
		range.setStart(@anchorNode, @anchorOffset)
		selection.addRange(range)
		selection.extend(@focusNode, @focusOffset)
		return


В итоге мы ренджи не трогаем, мы у селекшена запоминаем стартовую и конечную точки, а потом при ресторе, мы создаем коллапсовый замкнутый рендж задавая ему лишь стартовую точку, и продолжаем (extend) его в нужном направлении до конечной точки, подобное extend заставляет нам сохранить направление выделения. И выделение под курсором не обрывается ^_^

Еще один момент в EDGE такое выделение сбрасывается при любой активности мышкой, по этому щас я добавлю проверку на то нажата ли клафиша мышки или отпущена. И если нажата то буду думать что делать

Последний раз редактировалось ТОТ_САМЫЙ, 01.10.2015 в 00:06.
Ответить с цитированием
  #4 (permalink)  
Старый 01.10.2015, 00:50
Профессор
Отправить личное сообщение для ТОТ_САМЫЙ Посмотреть профиль Найти все сообщения от ТОТ_САМЫЙ
 
Регистрация: 10.09.2015
Сообщений: 184

Вот готовое решение:

class SelectionSaver


  isMs = /edge|msie|trident/i.test(navigator.userAgent)
  isInteractive = off

  if isMs
    addEventListener 'mousedown', =>
        isInteractive = on
    , on

    addEventListener 'mouseup', =>
        isInteractive = off
    , on


  constructor: ->
    @selection = getSelection()
    @anchorNode = null
    @anchorOffset = null
    @focusNode = null
    @focusOffset = null
    return


  clear: ->
    @anchorNode = null
    @anchorOffset = null
    @focusNode = null
    @focusOffset = null
    return


  save: ->
    @anchorNode = @selection.anchorNode
    @anchorOffset = @selection.anchorOffset
    @focusNode = @selection.focusNode
    @focusOffset = @selection.focusOffset
    return


  restore: ->
    if isMs and isInteractive then return
    @selection.removeAllRanges()
    unless @anchorNode then return
    range = document.createRange()
    range.setStart(@anchorNode, Math.min(@anchorOffset, @anchorNode.length))
    @selection.addRange(range)
    @selection.extend(@focusNode, Math.min(@focusOffset, @focusNode.length))
    return

Последний раз редактировалось ТОТ_САМЫЙ, 02.10.2015 в 01:43.
Ответить с цитированием
  #5 (permalink)  
Старый 01.10.2015, 01:12
Профессор
Отправить личное сообщение для ТОТ_САМЫЙ Посмотреть профиль Найти все сообщения от ТОТ_САМЫЙ
 
Регистрация: 10.09.2015
Сообщений: 184

тадаам, ставим звезды https://github.com/Maxmaxmaximus/SelectionSaver
Ответить с цитированием
Ответ



Опции темы Искать в теме
Искать в теме:

Расширенный поиск


Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Проблема метода indexOf() в разных браузерах! Rodger1956629 Javascript под браузер 7 31.07.2013 02:54
не работает в ie и в старых браузерах uzer Internet Explorer 0 14.07.2011 11:35
Некорректная работа скрипта в разных браузерах en-k Общие вопросы Javascript 2 15.03.2011 14:54
Выделение текста в текстовом поле. Как снять выделение с пробела вконце? Roman Koff Events/DOM/Window 10 01.07.2010 16:48
Выделение одиночных тэгов Pattern Events/DOM/Window 7 26.05.2009 23:29