简体   繁体   English

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

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

EDIT: 编辑:

I've made the changes Matthew and Yossi suggested and it still doesn't seem to work. 我已经做出了Matthew和Yossi建议的更改,但似乎仍然没有用。 Those changes I've edited in the post below too. 我也在以下帖子中编辑的那些更改。

It now works! 现在可以使用了! Thank you guys! 感谢大伙们!


I have a question for a particular problem I can't solve. 我有一个无法解决的特定问题。 If you know this question has been answered please send me the link as an answer. 如果您知道此问题已得到解答,请给我链接作为答案。 I'm trying not to use a framework in this case, but can use jQuery if necessary. 在这种情况下,我尝试不使用框架,但如有必要,可以使用jQuery。

I have found answers on how to attach listeners via functions but I need something so as I wouldn't have to refactor all the code I already have. 我已经找到了有关如何通过函数附加侦听器的答案,但是我需要一些东西,因为我不必重构已经拥有的所有代码。 I'm a freelancer and am working on somebody else's code. 我是一名自由职业者,正在开发其他人的代码。

What happens is that I want to detect a touch event for a touch device. 发生的事情是我想检测触摸设备的触摸事件。 This code should work for a PC too so I need to detect clicks. 该代码也适用于PC,因此我需要检测点击。 There's this DIV which is created programatically to which I need to add the click or touch, depending on the device. 这个DIV是通过程序创建的,我需要在其中添加单击或触摸,具体取决于设备。 Originally the function was called from an onmousedown event like this: 最初,该函数是从如下onmousedown事件调用的:

arrDivAnswers[c].onmousedown = onQuestionDown;

And this is the function it calls: 这是它调用的函数:

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;
}

This was working fine. 一切正常。 Now I've made this one which would try and slect the correct event for a click or touch (I need a function because I have to use this more than once - and the isTouchDevice is working fine. I use that on some other apps so that code is pretty short and has been tested): 现在,我制作了一个可以尝试为单击或触摸选择正确事件的控件(我需要一个功能,因为我必须多次使用此功能-isTouchDevice可以正常工作。我在其他一些应用程序上使用了该功能,因此该代码很短,并且已经过测试):

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

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

The DIV element gets created like this on some loop: 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]);

And then the events get attached to it like this (the older method has been commented out): 然后将事件附加到它上面(旧方法已被注释掉):

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;
        }
[...]

The debugger is throwing this error: Uncaught TypeError: Object [object DOMWindow] has no method 'getAttribute' 调试器抛出此错误: Uncaught TypeError: Object [object DOMWindow] has no method 'getAttribute'

I'm sure I'm messing up the " this " because I'm not calling the function properly. 我确定我搞砸了“ this ”,因为我没有正确调用该函数。 Thanks in advance. 提前致谢。

I agree the "this" variable is getting messed up. 我同意“ this”变量变得混乱。 The problem is that you are attaching an anonymous function as the callback that then calls eval on another method. 问题是您要附加一个匿名函数作为回调,然后在另一个方法上调用eval。 This seems unnecessary. 这似乎不必要。

Could you just do this: 您能这样做吗?

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

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

And then when you attach the event just do: 然后,当您附加事件时,只需执行以下操作:

detectEventClickOrTouch(arrDivAnswers[c], onQuestionDown);

Since you now call the onQuestionDown function indirectly by the eval the this context seen by the onQuestionDown is the global namespace and not the the element which fired the event. 由于您现在通过eval间接调用onQuestionDown函数,因此onQuestionDown看到的此上下文是全局名称空间,而不是引发事件的元素。

You don't need the eval anyway... you can pass the function it self 无论如何,您都不需要评估...您可以自行传递函数

 detectEventClickOrTouch(arrDivAnswers[c], onQuestionDown);

and: 和:

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

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

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