繁体   English   中英

如何从函数中调用动态生成的元素的触摸或单击事件

[英]How to call touch or click event from a function for an element which was generated dynamically

编辑:

我已经做出了Matthew和Yossi建议的更改,但似乎仍然没有用。 我也在以下帖子中编辑的那些更改。

现在可以使用了! 感谢大伙们!


我有一个无法解决的特定问题。 如果您知道此问题已得到解答,请给我链接作为答案。 在这种情况下,我尝试不使用框架,但如有必要,可以使用jQuery。

我已经找到了有关如何通过函数附加侦听器的答案,但是我需要一些东西,因为我不必重构已经拥有的所有代码。 我是一名自由职业者,正在开发其他人的代码。

发生的事情是我想检测触摸设备的触摸事件。 该代码也适用于PC,因此我需要检测点击。 这个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 ”,因为我没有正确调用该函数。 提前致谢。

我同意“ 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);

由于您现在通过eval间接调用onQuestionDown函数,因此onQuestionDown看到的此上下文是全局名称空间,而不是引发事件的元素。

无论如何,您都不需要评估...您可以自行传递函数

 detectEventClickOrTouch(arrDivAnswers[c], onQuestionDown);

和:

element.addEventListener("touchend", functionToCall, false);

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM