|
Тупой обход всех 1000 узлов HTML документа занимает 400мс | ☑ | ||
---|---|---|---|---|
0
TormozIT
гуру
12.09.22
✎
18:55
|
Изначальная задача у меня - получить количество символов текста от начала документа позиции каретки.
В IE был быстрый способ получить ответ ТекущееВыделение = ДокументHtml.Selection.createRange(); Диапазон = ТелоДокумента.createTextRange(); Диапазон.setEndPoint("EndToStart", ТекущееВыделение); ВыделениеВТексте.Вставить("Начало", СтрДлина(Диапазон.Text)); Но с приходом webKit этот способ исчез. Я нашел только способ путем перебора всех улов и сложения длин их текстов. Однако меня ждала большая плата по скорости - Тупой обход всех 1000 узлов HTML документа занимает 400мс https://i.imgur.com/MD3Ynfu.png Функция ТекстовыеУзлыHTMLВнутриЛкс(Узел, ТекстовыеУзлы = Неопределено) Экспорт Если ТекстовыеУзлы = Неопределено Тогда ТекстовыеУзлы = Новый Массив; КонецЕсли; Если Узел.nodeType = 3 Тогда ТекстовыеУзлы.Добавить(Узел); Иначе Потомки = Узел.childNodes; Для Каждого Потомок Из Потомки Цикл ТекстовыеУзлыHTMLВнутриЛкс(Потомок, ТекстовыеУзлы); КонецЦикла; КонецЕсли; Возврат ТекстовыеУзлы; КонецФункции 1. Подскажите почему обхов всех узлов занимает так много времени? 2. Есть ли какой то еще способ решить изначальную задачу подсчета количества символов в тексте документа до позиции каретки? |
|||
2
TormozIT
гуру
12.09.22
✎
19:07
|
(1) Зато createTextRange() куда то делась
|
|||
4
TormozIT
гуру
12.09.22
✎
19:09
|
(3) Не могу. А ты можешь?
|
|||
5
H A D G E H O G s
12.09.22
✎
19:11
|
(0) Вынеси во внешнюю компоненту
|
|||
6
Злопчинский
12.09.22
✎
19:16
|
(5) неспортивно
|
|||
8
TormozIT
гуру
12.09.22
✎
19:30
|
(7) Ловко ты ушел от ответа.
|
|||
10
TormozIT
гуру
12.09.22
✎
19:48
|
(9) Получается ты тоже не можешь как. Даже на чистом JavaScript пример не показал. Так что твои "отцовские" поучения выглядят слабенько.
|
|||
11
Garykom
гуру
12.09.22
✎
20:52
|
Функцию JS вставить и выполнить.
|
|||
12
Garykom
гуру
12.09.22
✎
20:57
|
||||
13
TormozIT
гуру
12.09.22
✎
21:06
|
Получить с применением cloneContents()
ТекущееВыделение = ДокументHtml.getSelection(); Диапазон = ДокументHtml.createRange(); Диапазон.setEnd(ТекущееВыделение.focusNode, ТекущееВыделение.focusOffset); ТекстовыйУзел = Диапазон.cloneContents(); Начало = СтрДлина(ТекстовыйУзел.textContent); Диапазон = ДокументHtml.createRange(); Диапазон.setStart(ТекущееВыделение.anchorNode, ТекущееВыделение.anchorOffset); Диапазон.setEnd(ТекущееВыделение.focusNode, ТекущееВыделение.focusOffset); ТекстовыйУзел = Диапазон.cloneContents(); Конец = Начало + СтрДлина(ТекстовыйУзел.textContent); ТекстВыделения = ТекстовыйУзел.textContent; |
|||
14
TormozIT
гуру
12.09.22
✎
21:15
|
Теперь более сложная задача. Нужно восстановить выделение в документе по полученным в (13) смещениям.
|
|||
15
TormozIT
гуру
12.09.22
✎
21:30
|
(13) Немного попутал в 3-й строке
ТекущееВыделение = ДокументHtml.getSelection(); Диапазон = ДокументHtml.createRange(); Диапазон.setEnd(ТекущееВыделение.anchorNode, ТекущееВыделение.anchorOffset); // Тут неверный узел был в старой версии ТекстовыйУзел = Диапазон.cloneContents(); ТекстВыделения = ТекстовыйУзел.textContent; Начало = СтрДлина(ТекстВыделения); Диапазон = ДокументHtml.createRange(); Диапазон.setStart(ТекущееВыделение.anchorNode, ТекущееВыделение.anchorOffset); Диапазон.setEnd(ТекущееВыделение.focusNode, ТекущееВыделение.focusOffset); ТекстовыйУзел = Диапазон.cloneContents(); ТекстВыделения = ТекстовыйУзел.textContent; Конец = Начало + СтрДлина(ТекстВыделения); |
|||
16
TormozIT
гуру
12.09.22
✎
23:43
|
(12) Спасибо. Полезная статья.
Еще поймал беду. Оказалось, что объект Range сразу после создания может началом указывать на какие то мусорные данные (перед началом body). Такое случалось у меня только в одном месте. Поэтому я все таки добавил setStart на начало body. Еще удалил вызовы cloneContents(), т.к. выяснил что toString() у меня не работал из-за ошибки в тесте, а я думал что это просто ограниченная реализация в 1С. В итоге проверил уже в 2-х формах ТекущееВыделение = ДокументHtml.getSelection(); Диапазон = ДокументHtml.createRange(); Диапазон.setStart(ДокументHtml.body, 0); // !!! Без этой строки начало диапазона может захватывать какой то мусор Диапазон.setEnd(ТекущееВыделение.anchorNode, ТекущееВыделение.anchorOffset); ТекстВыделения = Диапазон.toString(); Начало = СтрДлина(ТекстВыделения); Диапазон = ДокументHtml.createRange(); Диапазон.setStart(ТекущееВыделение.anchorNode, ТекущееВыделение.anchorOffset); Диапазон.setEnd(ТекущееВыделение.focusNode, ТекущееВыделение.focusOffset); ТекстВыделения = Диапазон.toString(); Конец = Начало + СтрДлина(ТекстВыделения); |
|||
17
Garykom
гуру
12.09.22
✎
23:44
|
Бывает более интересна задача которая простым способом не решается.
Например получить слово под курсором мышки. Суть в том что некоторые задачи без модификации HTML страниц никак. В некоторых случаях требуется модификация браузера. |
|||
18
Garykom
гуру
12.09.22
✎
23:46
|
(16) Лучше не использовать подобный извращенный код.
Не надо мешать французский с нижегородским. Делай цельные функции на JS, вставляй их в страницу и вызывай. В этом случае намного легче будет в будущем с переиспользованием кода. |
|||
19
Asmody
12.09.22
✎
23:49
|
(18) я так понимаю, ему надо без модификации исходной страницы
|
|||
20
Garykom
гуру
12.09.22
✎
23:49
|
(18)+ И работать будет намного быстрее.
А то вот от этого
Плакать хочется. В JS есть Диапазон.toString().length |
|||
21
Garykom
гуру
12.09.22
✎
23:49
|
(19) Эээ это же html! Там нет проблем с модификациями.
|
|||
22
TormozIT
гуру
12.09.22
✎
23:51
|
Проблему скорости выполнения я решил. Дальше ускорять в ущерб удобству сопровождения - мне не нужно.
А вот (14) было бы интересно решить. |
|||
23
Garykom
гуру
12.09.22
✎
23:53
|
(22) Смотри.
Когда у тебя отдельные законченные функции на одном ЯП их может в будущем сопровождать один спец по одному этому ЯП. А вот в случае подобного междукода любые доработки или исправления это мрак. Особенно для новых прогов. Ладно еще когда через COM в 1С извращаются, хотя это тоже не але но там хотя бы один ЯП! |
|||
24
TormozIT
гуру
12.09.22
✎
23:55
|
(20) Мне нужна длина такая, как ее считает 1С. JS и 1С вполне могут заковыристые и непечатные символы считать по-разному. Поверить в обратное можно только проведя тщательное тестирование или набрав приличный опыт, которого у меня в JS нет.
Опять же не вижу смысла вносить лишнюю ненадежность в код. |
|||
25
Garykom
гуру
12.09.22
✎
23:56
|
Это примерно как "Ъ" не взлетело от Serginio1
Где такая же хрень со смешением разных ЯП Ибо намного проще на чистом C# писать, компилить и запускать/вызывать из 1С |
|||
26
Garykom
гуру
12.09.22
✎
23:58
|
(24) У тебя код изначально ненадежен.
Ибо любые изменения в 1с или в браузере ie->webkit->... и с этим индусским кодом будет ахтунг |
|||
27
dmpl
13.09.22
✎
08:08
|
(26) Со сторонними html в принципе ненадежно работать: на той стороне что-то поменяют - у тебя всё полетит.
|
|||
28
Garykom
гуру
13.09.22
✎
08:12
|
(27) Так и я о чем.
Но можно уменьшить проблемы если правильно делать отдельными JS-функциями. |
Форум | Правила | Описание | Объявления | Секции | Поиск | Книга знаний | Вики-миста |