Метод выбора IE TextRange, не работающий правильно

На самом деле здесь есть два вложенных iframe. Это, в сочетании с некоторыми WebDriverWait, позволило мне прийти к следующему решению. Здесь я нахожу поле «Инструмент» и вводю в него текст:

from selenium import webdriver
from selenium.webdriver.chrome.options import Options
from selenium.webdriver.common.by import By
from selenium.webdriver.support import expected_conditions as ec
from selenium.webdriver.support.wait import WebDriverWait

options = Options()
options.add_argument("--headless")

driver = webdriver.Chrome(
    options=options, executable_path=r"C:\chromedriver\chromedriver.exe"
)
driver.implicitly_wait(10)

try:
    driver.get(
        "https://www.dukascopy.com/trading-tools/widgets/quotes/historical_data_feed"
    )

    driver.switch_to.frame(driver.find_element(By.ID, "widget-container"))
    driver.switch_to.frame(driver.find_element(By.TAG_NAME, "iframe"))

    # Wait for "Loading" overlay to disappear
    WebDriverWait(driver, 10).until(
        ec.invisibility_of_element_located((By.CLASS_NAME, "d-e-r-k-n"))
    )

    # Click "Instrument"
    driver.find_element(By.CLASS_NAME, "d-oh-i-ph-qh-rh-m").click()
    # Enter text into now-visible instrument field
    driver.find_element(By.CLASS_NAME, "d-e-Xg").send_keys("metlife")
finally:
    driver.quit()
7
задан Douglas Mayle 5 May 2009 в 21:12
поделиться

4 ответа

Я разобрался с несколькими методами для работы с диапазонами IE, подобными этим.

Если все, что вы хотите сделать, это сохранить то, где находится курсор, а затем восстановить его, вы можете использовать метод pasteHTML для вставки пустого диапазона в текущую позицию курсора, а затем с помощью метода moveToElementText, чтобы снова вернуть его в эту позицию:

// Save position of cursor
range.pasteHTML('<span id="caret"></span>')

...

// Create new cursor and put it in the old position
var caretSpan = iframe.contentWindow.document.getElementById("caret");
var selection = iframe.contentWindow.document.selection;
newRange = selection.createRange();
newRange.moveToElementText(caretSpan);

Кроме того, вы можете подсчитать, сколько символов предшествует текущей позиции курсора, и сохранить его. число:

var selection = iframe.contentWindow.document.selection;
var range = selection.createRange().duplicate();
range.moveStart('sentence', -1000000);
var cursorPosition = range.text.length;

Чтобы восстановить курсор, установите его в начало, а затем переместите на это количество символов:

var newRange = selection.createRange();
newRange.move('sentence', -1000000);
newRange.move('character', cursorPosition);

Надеюсь, это поможет.

12
ответ дан 6 December 2019 в 19:44
поделиться

Я недавно работал на сайте, который использовал Microsoft CMS с "MSIB + пакет" средств управления, которые включали WYSIWYG-редактор, который работал в Internet Explorer.

Я, кажется, помню некоторые комментарии в редакторе клиентский JavaScript, которые были конкретно связаны с этой ошибкой в IE и Диапазоне. Выберите () метод.

К сожалению, я не работаю там еще, таким образом, я не могу получить доступ к файлам JavaScript, но возможно Вы можете получать их откуда-либо?

Удачи

0
ответ дан 6 December 2019 в 19:44
поделиться

Я немного покопался и, к сожалению, не могу см. обходной путь ... Хотя одну вещь я заметил при отладке javascript, похоже, что проблема на самом деле связана с самим объектом диапазона, а не с последующим range.select () . Если вы посмотрите на значения в объекте диапазона, который возвращает selection.createRange () , да, родительский объект dom может быть правильным, но информация о позиционировании уже относится к началу следующей строки (например, offsetLeft / Top, boundingLeft / Top и т. Д. Уже неверны).

Судя по информации здесь , здесь и здесь , я думаю, что вы вышли удачи с IE, поскольку у вас есть доступ только к объекту Microsoft TextRange, который, похоже, не работает. Исходя из моих экспериментов, вы можете перемещать диапазон и позиционировать его точно там, где он должен быть, но как только вы это сделаете, объект диапазона автоматически перейдет на следующую строку еще до того, как вы попытались .select () ит. Например, вы можете увидеть проблему, поместив этот код между шагами 1 и 2:

if (range.boundingWidth == 0)
{
    //looks like its already at the start of the next line down...
    alert('default position: ' + range.offsetLeft + ', ' + range.offsetTop);
    //lets move the start of the range one character back
    //(i.e. select the last char on the line)
    range.moveStart("character", -1);
    //now the range looks good (except that its width will be one char);
    alert('one char back: ' + range.offsetLeft + ', ' + range.offsetTop);
    //calculate the true end of the line...
    var left = range.offsetLeft + range.boundingWidth;
    var top = range.offsetTop;
    //now we can collapse back down to 0 width range
    range.collapse();
    //the position looks right
    alert('moving to: ' + left + ', ' + top);
    //move there.
    range.moveToPoint(left, top);
    //oops... on the next line again... stupid IE.
    alert('moved to: ' + range.offsetLeft + ', ' + range.offsetTop);
}

Итак, к сожалению, не похоже, что есть какой-либо способ гарантировать, что диапазон находится в правильном месте, когда вы его выбираете снова.

Очевидно, есть тривиальное исправление в вашем коде выше, изменив Шаг 2 на это:

// Step 2 Restore the selection
if (range.select) {
    if (range.boundingWidth > 0) {
        range.select();
    }
} else {
    selection.removeAllRanges();
    selection.addRange(range);
    doc.body.focus();
}

Но, по-видимому, вы действительно хотите сделать что-то между Шагом 1 и Шагом 2 в вашем фактическом, что включает перемещение выделения, отсюда и необходимость его переустановить. Но на всякий случай. :)

Таким образом,

1
ответ дан 6 December 2019 в 19:44
поделиться

Возможно, я неправильно понял, но если я щелкну справа от этой первой строки, мой курсор сразу же появится в начале второй строки, так что это не проблема TextRange, верно?

Добавление doctype, чтобы тестовая страница отображалась в стандартном режиме вместо режима quirks, исправляет это для меня.

И я не могу воспроизвести то, что делает ваша функция myhandler, потому что нажатие этой кнопки перемещает фокус на кнопку, поэтому я не может больше видеть курсор и не может вернуть его. Поиск позиции курсора в contentEditable области кажется совершенно другой проблемой .

0
ответ дан 6 December 2019 в 19:44
поделиться
Другие вопросы по тегам:

Похожие вопросы: