javascript - 在多个元素上使用 addEventListener,避免在未找到特定元素时出现 TypeError

标签 javascript typeerror addeventlistener bodymovin

我分别使用了两个简单的 addEventListener mouseenter 和 mouseleave 函数来播放和停止动画(Bodymovin/SVG 动画,尽管我怀疑这无关紧要)。

因此,以下工作正常:

document.getElementById('animationDiv').addEventListener('mouseenter', function(){ 
    animation.play(); 
}) 

(HTML 再简单不过了:相关部分只是一个由脚本填充的空 div 占位符 - 即 <div id="animationDiv"></div>

我可以将它放在与运行动画代码的文件相同的文件中,或者我可以将它放在单独的“触发器”文件中,将两个文件(以及处理所需的其他其他文件)都加载到站点页脚中。

当我需要能够为给定页面上可能出现或不出现的多个类似动画中的任何一个设置触发器时,就会出现问题。

如果页面上只有两个可动画元素之一,则两组触发器中的一个将引发错误。如果两个此类触发器中的第一个不存在,则不会处理第二个,这意味着动画将失败。或者至少在我看来这就是正在发生的事情。

因此,为了清楚起见,如果我为同一页面添加以下两个触发器,并且以下两个元素中的第一个存在,那么动画将在 mouseenter 上播放。如果只有第二个存在,它的动画将不会被触发,显然是因为第一个抛出的错误。
document.getElementById('firstAnimationDiv').addEventListener('mouseenter', function(){ 
    firstAnimation.play(); 
})
document.getElementById('secondAnimationDiv').addEventListener('mouseenter', function(){ 
    secondAnimation.play(); 
})

目前我可以通过创建多个触发器文件来解决这个问题,每个动画一个,并将它们设置为仅在我知道可动画元素将存在时才加载,但是当我使用多个动画时,这种方法会变得越来越低效页面,在其内容可能被更改的页面上。

我已经查看了 try/catch 方法以及事件委托(delegate)方法,但到目前为止,如果适当的话,它们对于处理这个简单的问题似乎有点复杂。

是否有一种有效且灵活的标准方法来防止或正确处理未找到元素的错误,从而仍然可以处理后续功能?还是我错过了其他东西或以某种方式误读了我遇到的错误和功能失败?

为什么我选择了我所做的答案(加上工作代码)

我很容易就可以通过 Baoo 做出简单、直接响应的答案。

我无法通过 Patrick Roberts 和 Crazy Train 给出以下答案,尽管毫无疑问,我未开发的 js 技能完全是错误的。当我有时间,或者当我在更复杂的实现中遇到下一个问题时(可能很快!),我会再看看他们的解决方案,看看我是否可以让它们工作或者我是否可以制定一个更好的问题,需要解决完全成熟的编码示例。

最后,为了让那些可能正在寻找关于 Bodymovin 动画的答案并且其 js 甚至比我的更弱的人清楚,以下是工作代码,所有代码都添加到同一个文件中,其中包含更大的 Bodymovin 动画集构造,让我无需创建单独的触发器文件,并防止 TypeErrors 和功能受损。
//There are three "lets_talk" animations that can play - "home," "snug," and "fixed"
//and three types of buttons needing enter and leave play and stop triggers
let home = document.getElementById('myBtn_bm_home');

if (home) home.addEventListener('mouseenter', function() { 
             lets_talk_home.play(); 
});
if (home) home.addEventListener('mouseleave', function() { 
             lets_talk_home.stop(); 
});

let snug = document.getElementById('myBtn_bm_snug');

if (snug) snug.addEventListener('mouseenter', function() { 
             lets_talk_snug.play(); 
});
if (snug) snug.addEventListener('mouseleave', function() { 
             lets_talk_snug.stop(); 
});

let fixed = document.getElementById('myBtn_bm_fixed');

if (fixed) fixed.addEventListener('mouseenter', function() { 
             lets_talk_fixed.play(); 
});
if (fixed) fixed.addEventListener('mouseleave', function() { 
             lets_talk_fixed.stop(); 
});

在典型的底层 HTML 中(它是由考虑其他条件的 PHP 函数生成的,因此每个按钮都不相同),目前看起来像这样 - 尽管我将削减数据属性和类,因为我'我目前也没有使用。如果有人在那里看到重要或有用的东西,我会提供它。
<div id="letsTalk" class="lets-talk">
    <a id="myBtn" href="#"><!-- a default-prevented link to a pop-up modal --> 
        <div class="bm-button" id="myBtn_bm_snug" data-animation="snug"></div><!-- "snug" (vs "fixed" or "home" is in both instances added by PHP -->
    </a>
</div>

显然,可以——而且可能应该——写出更简洁和灵活的答案。关于这一点,在单个条件中正确组合播放和停止监听器显然是第一步,但我太喜欢 js 了,甚至在第一次或第二次尝试时都无法做到这一点。也许以后/下一次!

再次感谢所有提供答案的人。我不会要求您尝试将工作解决方案压缩到您建议的框架中 - 但我也不会要求您不要...

最佳答案

只需检查 if 即可编写代码,以便在元素不存在时不会引发错误元素存在。

let first = document.getElementById('firstAnimationDiv');
if (first) first.addEventListener('mouseenter', function() {firstAnimation.play();});

关于javascript - 在多个元素上使用 addEventListener,避免在未找到特定元素时出现 TypeError,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50192772/

相关文章:

python - TypeError: 'list' 不支持缓冲区接口(interface)

javascript - 如何使用 Javascript 代码通过按钮在两个图像之间切换?

javascript - 使用 Angular 5 的 EventListener 不会更新 DOM

javascript - html 日期输入中的最大属性在 Firefox 中不起作用

javascript - 定义要作为参数传递的函数

javascript - 将 ng-repeat 中的值设置为另一个值一次(仅在页面加载时)

python - 求和函数概率类型错误: unsupported operand type(s) for +: 'int' and 'str'

javascript - 使用 jquery 时出现控制台错误 - 未捕获的 TypeError : Object #<HTMLElement> has no method

javascript - 将 eventListener 添加到按钮以更改类 onmouseup/down

javascript - React组件方法执行顺序