Как вызвать событие touch или click из функции для элемента, который был сгенерирован динамически - PullRequest
1 голос
/ 15 июня 2011

РЕДАКТИРОВАТЬ:

Я внес изменения, предложенные Мэтью и Йосси, и, похоже, все еще не работает.Те изменения, которые я редактировал в посте ниже.

Теперь это работает!Спасибо, ребята!


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

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

В результате я хочу обнаружить сенсорное событие для сенсорного устройства.Этот код должен работать и на ПК, поэтому мне нужно определять щелчкиЕсть этот DIV, который создается программно, к которому мне нужно добавить щелчок или касание, в зависимости от устройства.Первоначально функция была вызвана из события onmousedown, подобного этому:

arrDivAnswers[c].onmousedown = onQuestionDown;

И это функция, которую она вызывает:

function onQuestionDown(e)
{
    if(!itemSelected)
    {
        if(this.getAttribute('data-isCorrect') == 'true')
            setStyleQCorrect(this, true);
        else
            setStyleQIncorrect(this);

        this.querySelector('.answerText').style.color = '#ffffff';
        this.querySelector('.isCorrect').style.visibility = 'visible';
    }

    itemSelected = true;
}

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

function detectEventClickOrTouch(element, functionToCall){
  //detectEventClickOrTouch(arrDivAnswers[c], 'onQuestionDown');

  if(isTouchDevice()){
    element.addEventListener("touchend", functionToCall, false);
  } else{
    element.addEventListener("click", functionToCall, false);
  }
}

Элемент DIV создается следующим образом в некотором цикле:

    arrDivAnswers[c] = document.createElement('div');
    console.log( "Answer object #" + c + " = " + arrDivAnswers[c] );
    arrDivAnswers[c].className = 'autosize';
    arrDivAnswers[c].style.textAlign = 'left';
    arrDivAnswers[c].setAttribute('data-isCorrect',false);
    arrDivAnswers[c].setAttribute('data-isSelected',false);
    divAnswerContainer.appendChild(arrDivAnswers[c]);

И затем к нему присоединяются события вот так(старый метод был закомментирован):

for(c;c < arrQuestions[index].arrAnswers.length;c++)
        {
            var curAnswer = arrQuestions[index].arrAnswers[c];
            arrDivAnswers[c].onmouseover = function (e){setStyleQHover(e.currentTarget)};
            arrDivAnswers[c].onmouseout = function (e){setStyleQUp(e.currentTarget)};


            // Detect touch here *************************
            detectEventClickOrTouch(arrDivAnswers[c], onQuestionDown);
            //arrDivAnswers[c].onmousedown = onQuestionDown;
            // Detect touch here *************************

            arrDivAnswers[c].style.visibility = 'visible';
            arrDivAnswers[c].querySelector('.answerText').innerHTML = curAnswer.strAnswer;
            arrDivAnswers[c].setAttribute('data-isCorrect',curAnswer.isCorrect);
            if(curAnswer.isCorrect)
            {
                //arrDivAnswers[c].classList.add("correctAnswer");
                arrDivAnswers[c].className = "correctAnswer";
            }
            else
            {
                //arrDivAnswers[c].classList.remove("correctAnswer");
                arrDivAnswers[c].className = "autosize";
            }
            arrDivAnswers[c].setAttribute('data-isSelected',false);
            setStyleQUp(arrDivAnswers[c]);
            itemSelected = false;
        }
[...]

Отладчик выдает эту ошибку: Uncaught TypeError: Object [object DOMWindow] has no method 'getAttribute'

Я уверен, что я испортил "this"потому что я не вызываю функцию должным образом.Заранее спасибо.

Ответы [ 2 ]

4 голосов
/ 15 июня 2011

Я согласен, что переменная this перепутана. Проблема в том, что вы присоединяете анонимную функцию в качестве обратного вызова, которая затем вызывает eval для другого метода. Это кажется ненужным.

Не могли бы вы просто сделать это:

function detectEventClickOrTouch(element, functionToCall){
  //detectEventClickOrTouch(arrDivAnswers[c], 'onQuestionDown');

  if(isTouchDevice()){
    element.addEventListener("touchend", functionToCall, false);
  } else{
    element.addEventListener("click", functionToCall, false);
  }
}

А потом, когда вы прикрепляете событие, просто выполните:

detectEventClickOrTouch(arrDivAnswers[c], onQuestionDown);
3 голосов
/ 15 июня 2011

Так как вы теперь вызываете функцию onQuestionDown косвенно eval, этот контекст, видимый onQuestionDown, является глобальным пространством имен, а не элементом, вызвавшим событие.

В любом случае вам не нужно eval ... вы можете передать функцию самостоятельно

 detectEventClickOrTouch(arrDivAnswers[c], onQuestionDown);

и

element.addEventListener("touchend", functionToCall, false);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...