клик() со ссылками

У меня есть страница с несколькими ссылками, которые выглядят так:

<a href="/" class="answer-item" rel="0">10</a>

Я хотел бы использовать функцию click() для имитации щелчка пользователя по одному из них, но, похоже, в моих тестах это не работает.

//Evaluate a mathematical expression from another part of the page
var numberAnswer = eval(document.getElementById("question-title").getElementsByTagName("b")[0].innerHTML);

//Builds an array with the links that may match the expression
var choices = document.getElementsByClassName('answer-item');

//Iterates through array to find a match then clicks it
for(var i in choices){
    if(choices[i].innerHTML == numberAnswer){
        choices[i].click();
        break;
    }
}

Я уверен, что choices[i] - правильный элемент.

Firefox ничего не делает, Opera ничего не делает, а click() недоступен в Chrome (я думаю).

Кроме того, я пытался использовать dispatchEvent() в этой форме:

var evt = document.createEvent('MouseEvents');
evt.initMouseEvent("click", true, true, window, 0, 0, 0, 0, 0, false, false, false, false, 0, null);
choices[i].dispatchEvent(evt);

Очевидно, это вернуло true в Firefox и Chrome, но ничего не изменило.

Самое неприятное то, что ссылка только с атрибутом href прекрасно работает с .click().


person MarkM    schedule 03.04.2012    source источник


Ответы (2)


ИЗМЕНИТЬ

Судя по обсуждению в области комментариев, кажется, что поведение, используемое в этом ответе, нестандартно или, по крайней мере, несовместимо между пользовательскими агентами. Я исследую этот вопрос дальше; если вы используете информацию в этом ответе, внимательно проверьте свой код во всех браузерах, чтобы убедиться, что он работает должным образом.


ИЗМЕНИТЬ 2

Согласно комментарию ОП, здесь сработает подход «просто сделай это». У него есть некоторые недостатки, а именно то, что ваши связанные события не могут вызывать preventDefault - этот метод не будет его учитывать. Вы можете создать какую-то оболочку событий, которая сможет справиться с этим... в любом случае, вот код и скрипка:

HTML:

<br><br>
<!-- I am totally misusing this API! -->
<a href="http://jsfiddle.net/echo/js/?delay=0&js=The link was followed;" id="progra_link">Some link with an event that uses preventDefault()</a>
<br><br>
<button id="doit_btn">Programmatically click the link</button>

Скрипт:

function do_program_click () {
    var lnk = document.getElementById('progra_link');
    var loc = lnk.href;
    if (!loc)
        return false;            
    // call this to fire events
    lnk.click();

    // then follow the link
    document.location = loc;
    return;
};
function addEvent(element, evnt, funct){
  if (element.attachEvent)
   return element.attachEvent('on'+evnt, funct);
  else
   return element.addEventListener(evnt, funct, false);
}

// bind an event to the link to test force event trigger
addEvent(
    document.getElementById('progra_link'),
    'click',
    function (e) {
        e.preventDefault();
        alert('Testing element click event, default action should have been stopped');
        return false;
    }
);
// bind event to the leeroy button
addEvent(
    document.getElementById('doit_btn'),
    'click',
    do_program_click
);

jsFiddle: http://jsfiddle.net/CHMLh/


Исходный ответ

Ваш образец кода неполный. Если я возьму только основы, он работает правильно:

<script>
   var lnk = document.getElementById('test');
   lnk.click();
</script>
<a id="test" href="/" class="answer-item" rel="0">test link</a>

jsFiddle: http://jsfiddle.net/cgejS/

Я бы пересмотрел ваши предположения о том, что вы имеете дело с правильным элементом dom.

На несвязанной ноте это:

var numberAnswer = eval(document.getElementById("question-title").getElementsByTagName("b")[0].innerHTML);

... какие? eval — это зло. Если вы когда-либо используете его по какой-либо причине, спросите себя, правильный ли у вас подход. Вы пытаетесь получить целое число из строки? См. parseInt (документы), подходящий инструмент для этой работы:

// this line is still failure-prone...
var ele = document.getElementById("question-title").getElementsByTagName("b")[0];
var numberAnswer = 0;
if (ele)
   numberAnswer = parseInt(ele.innerHTML);
person Chris Baker    schedule 03.04.2012
comment
Не уверен, какой браузер вы используете, но в Chrome ваш код ничего не делает (даже с чем-то другим, кроме / в качестве URL-адреса) - person Chris Laplante; 04.04.2012
comment
jsFiddle, который я разместил в Firefox, перемещает панель результатов на домашнюю страницу jsFiddle - он следует URL-адресу /, как и ожидалось. Буду тестировать в Chrome и обновлять здесь. - person Chris Baker; 04.04.2012
comment
Подтвердите - это не работает в Chrome. Буду редактировать, спасибо за информацию. - person Chris Baker; 04.04.2012
comment
Не проблема. Я отозвал свой отрицательный голос в ожидании вашего редактирования. - person Chris Laplante; 04.04.2012
comment
Хорошо, похоже, это работает во всех браузерах, кроме Chrome. Это вина Chrome, а не вашего кода. Я нашел несколько статей, в которых упоминался этот факт. Так что +1 :) - person Chris Laplante; 04.04.2012
comment
Хех, а у вас есть такие статьи? Забавно то, что... Мне трудно объяснить, почему это ДЕЙСТВИТЕЛЬНО работает в Firefox, по всем признакам это не должно. w3.org/TR/DOM-Level- 2-HTML/html.html#ID-2651361 говорит мне, что только кнопка отправки формы должна отвечать действием браузера по умолчанию при вызове click(). Я начал думать, что это несоответствующее поведение или даже ошибка ... но если вы скажете, что все остальные делают это, КРОМЕ Chrome, это поднимает совершенно новый вопрос! Угадайте, кто будет писать об этом на wc3\public-html сегодня вечером :) - person Chris Baker; 04.04.2012
comment
Хотя я согласен с тем, что eval — это зло, я думаю, что в этом контексте он хорошо работает, потому что он вычисляет математическое выражение. - person MarkM; 04.04.2012
comment
Ах, достаточно справедливо. Если вы [оцениваете] математические выражения, то это один из редких случаев, когда eval является инструментом для работы. Я бы по-прежнему задавался вопросом, быстрее и безопаснее ли определить ответ на стороне сервера, но вы знаете свой вариант использования лучше, чем я. :) Я все еще изучаю вопрос о том, click() следует работать или нет, я не нахожу никаких убедительных доказательств того, что это должно быть. Таким образом, мой ответ здесь не выглядит лучшим подходом. - person Chris Baker; 04.04.2012
comment
Я только что искал это в Google. Вот одна статья: unitstep.net/blog /2010/04/12/ (согласно этому, ни один браузер не поддерживает его, но, как вы обнаружили, некоторые на самом деле поддерживают) - person Chris Laplante; 04.04.2012
comment
Из обсуждения кажется, что ответ click() для этого не подойдет. Я уверен, что есть другой способ сделать это, даже если это потребует больше усилий. А пока это ответ. - person MarkM; 04.04.2012
comment
Посмотрите второе редактирование, @MarkM - jsfiddle.net/CHMLh имеет решение, которое выполняет эту работу. . грязный - person Chris Baker; 05.04.2012
comment
@Chris О боже, это довольно уродливо (конечно, не в обиду вашим отличным навыкам кодирования). К счастью, мне удалось решить мою проблему с помощью совершенно не связанного с этим метода, который позволил мне вообще избежать имитации клика. Тем не менее, я благодарю вас за постоянную помощь. - person MarkM; 05.04.2012

Легкий.

HTML (обратите внимание, что я добавил тег «id»):

<a id="answer-item" href="/" class="answer-item" rel="0">10</a>

JS:

document.getElementById('answer-item').click();
person mukama    schedule 03.04.2012
comment
Примечание. Это не работает в Chrome, но это ограничение самого браузера. - person Chris Laplante; 04.04.2012
comment
Добавление идентификатора и использование getElementById() не сработало, но можете ли вы объяснить, почему? Мой код уже получает правильный элемент. - person MarkM; 04.04.2012
comment
Это не просто - проблема сложнее. Пожалуйста, смотрите обсуждение комментариев к моему ответу для получения дополнительной информации. По сути, я пришел к выводу, что click() НЕ должен работать в этом случае, тот факт, что он работает, является нестандартным и / или ошибкой. - person Chris Baker; 04.04.2012
comment
Кроме того, поскольку OP вычисляет значение, а затем перебирает ссылки для поиска совпадающего значения, использование getElementById не является стартовым без возврата к решению на стороне сервера, которое может создавать уникальные совпадающие значения id, которые будут использоваться как document.getElementById('answernumber'+numberAnswer) - person Stephen P; 04.04.2012