Javascript задейства две събития - onkeypress и onclick

Проблемът е, че когато натисна клавиш над бутон за избор, елемент MyFunc се задейства два пъти - веднъж за събитие onkeypress, друг път за събитие щракване.

Въпрос Защо? Трябва да се справя с това по два различни начина, но сега не мога да разпозная какво е първоначалното събитие. Когато щракна с мишка, тя се задейства само за събитие с щракване.

<ul>
    <li>
        <input type="radio" onkeypress="MyFunc(event, this)" onclick="MyFunc(event, this)" name="myList" id="MyId_1" />Topic 1
        <input type="radio" onkeypress="MyFunc(event, this)" onclick="MyFunc(event, this)" name="myList" id="MyId_2" />Topic 2
    </li>
</ul>

function MyFunc(e, obj) {
    alert(e.type); // alerts "keypress" and then "click"
    // Do my stuff
}

person podeig    schedule 02.03.2010    source източник


Отговори (7)


Ако 2 събития се задействат по време на натискане на клавиш, тогава проверете свойството event.detail във функцията onClick. ако event.detail = 0, това означава, че мишката не е щракната върху този елемент и можем да го игнорираме. event.detail

person pooja sharma    schedule 13.02.2016

Може да се направи и без да се прибягва до рамки, които винаги са обемисти и бавни. Номерът е да запишете кое събитие се е случило в кой момент от време и след това да работите в рамките на времева рамка. Когато задействате събитието keypress, събитието click се задейства веднага след това, ето списък колко бързо се задейства събитието click след събитието keypress...

Chrome 39.0: 0 мсек

Firefox 31.0 ESR: 18~20ms

IE 11: 2~4 ms

Opera 12.1: 0 мсек

Chrome и (истинската) Opera не чакат, IE е сравнително бърз и Firefox отнема време, така да се каже; диапазонът за работа (поне на моята система) е 0~20 ms. Програмно ще задам ограничението до 50 милисекунди за хора, които все още използват вредни компютри, които са твърде заети със 150 безполезни процеса във фонов режим.

Имайте предвид, че ще трябва да използвате събитията на глобално ниво window, въпреки че това изглежда работи надеждно за мен във всички браузъри, които споменах.

var option = new function() {this.name = '';}


window.onclick = function(event)
{
 option.clickDate = new Date().getTime();
}


window.onkeypress = function(event)
{
 option.keyCode = event.keyCode;
 option.keyCodeDate = new Date().getTime();
}


function MyFunc(e,obj)
{
 if (option.keyCodeDate && option.clickDate && 
 (
  (option.clickDate - option.keyCodeDate)>=0 && 
  (option.clickDate - option.keyCodeDate)<51)
 {alert('keypress event');}
 else {alert('click event');}
}
person John    schedule 19.01.2015

Събитието onclick се задейства, когато бъде избран радиобутонът. Тъй като го избирате чрез натискане на клавиш, и двете събития ще се задействат. Първо събитието onkeypress и след това събитието onclick.

person Aurril    schedule 02.03.2010
comment
Но как да предотвратите това? - person Todd Moses; 02.03.2010
comment
Не можете да предотвратите това поведение, доколкото знам. - person Aurril; 02.03.2010
comment
Много е странно. Какъв е смисълът да се справяме заедно с тези събития? :-/ - person podeig; 04.03.2010

можете да добавите трети параметър към вашата функция

function MyFunc(e, obj, click) {
    if (click) { } // do stuff
    else { } // do other stuff
}

Сега добавете bool към вашите събития...

<input type="radio" onkeypress="MyFunc(event, this, false)" onclick="MyFunc(event, this, true)" name="myList" id="MyId_1" />Topic 1
<input type="radio" onkeypress="MyFunc(event, this, false)" onclick="MyFunc(event, this, true)" name="myList" id="MyId_2" />Topic 2
person hunter    schedule 02.03.2010
comment
Проблемът е, че те стрелят едновременно. Мога да разпозная върху какво е щракнато с помощта на свойството e.type. Връща натискане на клавиш или щракване. - person podeig; 04.03.2010

Бих създал два отделни манипулатора: един за събитието щракване и един за натискане на клавиш.

Тогава вашите манипулатори могат да извлекат каквото ви трябва от събитието и да извикат трета функция, която има общата логика.

Вашето натискане на клавиша ще трябва да игнорира събитието за клавишите за интервал и въвеждане. Не разбирам обаче защо слушате събитието за натискане на клавиш. Бихте ли уточнили? Ако обясниш какво ще правиш, може би ще сме по-полезни.

person Juan Mendes    schedule 10.03.2010

Ключово събитие е за потребителите само на клавиатурата да активират бутон, но ако използвате бутон, „щракването“ трябва да е единственото необходимо събитие, тъй като се задейства при натискане на ИНТЕРВАЛ. Ако имате събития на персонализирана контрола, събитието „ключ“ и „щракването“ могат да се използват и двете и няма да се задействат заедно.

person Vincent Young    schedule 04.02.2017

Използвайте onMouseDown вместо onclick в рамките на JavaScript и за последователност добавете събитието onKeyPress и тук - изваждайки събитието от HTML тага.

Судо код:

var myRadioButton = document.getElementById('radio');

myRadioButton.addListener("radioClick",onMouseDown);
myRadioButton.addListener("radioKey",onKeyPress);

radioClick()
{
 //code to do stuff
}

Разгледайте jQuery: http://jquery.com/ за действителния код и лесен начин да напишете своя JavaScript.

person Todd Moses    schedule 02.03.2010
comment
ще го пробвам Мисля, че опитах onMouseDown, но работих като OnClick. Може би addListener помага. Ще се върне скоро с резултати. - person podeig; 04.03.2010
comment

Основната версия на NHibernate.Search се изгражда срещу NH2.1, за основна компилация на NH искате версията на клона NHibernate.Search-NH3.x

Току-що създадох това от текущия svn, като направих следното:

  • svn co NH багажника
  • изградете го с NAnt (резултантните сборки са в процес на изграждане)
  • svn co NHibernate.Search-NH3.x
  • изтрийте препратките към Iesi и NHibernate и ги заменете с прясно построените
  • извличане на сглобки log4net и Lucene от NHibernate.Search/lib в trunk
  • изграждане на NHibernate. Търсене с Visual Studio

Актуализация: NHSR-25 е приложен само към багажника. Ще трябва да добавите корекцията сами, използвайте по-малката от двете от JIRA.

- person podeig; 04.03.2010
comment
Страхотно, че споменахте последователност, но след това го бомбардирахте, като предложихте рамка. Ако бях търсил този проблем чрез Google, тази страница нямаше да се появи, защото аз -jquery, за да намеря отговори, а не да натоварвам потребителите с честотна лента. Моля, придържайте се към истински JavaScript. - person John; 19.01.2015