使用javascript将焦点事件添加到元素时出现问题

使用javascript将焦点事件添加到元素时出现问题,javascript,html,arrays,dom-events,Javascript,Html,Arrays,Dom Events,我只是在学习Javascript(非常开始),当焦点应用于元素时,试图使隐藏的“子导航”菜单出现时,我遇到了一个问题。我认为这是非常基本的 这个想法与在鼠标悬停时显示隐藏的“子导航”菜单相同。当用户选项卡指向元素并应用焦点时,菜单将显示,菜单中的链接将变为焦点。当用户从菜单上取下标签时,菜单将再次隐藏。我希望这发生在任何数量的导航元素 HTML: <nav role="navigation"> <ul> <li><a href="#"&

我只是在学习Javascript(非常开始),当焦点应用于元素时,试图使隐藏的“子导航”菜单出现时,我遇到了一个问题。我认为这是非常基本的

这个想法与在鼠标悬停时显示隐藏的“子导航”菜单相同。当用户选项卡指向元素并应用焦点时,菜单将显示,菜单中的链接将变为焦点。当用户从菜单上取下标签时,菜单将再次隐藏。我希望这发生在任何数量的导航元素

HTML:

<nav role="navigation">
   <ul>
      <li><a href="#">Link 1</a></li>
      <li><a href="#" class="has-dropdown">Link 2</a>
         <ul class="dropdown">
            <li><a href="#">Link 2a</a></li>
            <li><a href="#">Link 2b longer</a></li>
            <li><a href="#">Link 2c longest text</a></li>
         </ul>
      </li>
      <li><a href="#">Link 3</a></li>
      <li><a href="#">Link 4</a></li>
   </ul>
</nav>
Javascript:

var topLevel = document.getElementsByClassName("has-dropdown");

for (var i = 0; i < topLevel.length; i++) {
   topLevel[i].onfocus = function() {
      console.log("you have activated the dropdown");
      topLevel.nextElementSibling.className = "active";
   }
}
var topLevel=document.getElementsByClassName(“has下拉菜单”);
对于(变量i=0;i
当我点击触发此操作的链接时,我会在任何有子菜单但子菜单不显示的链接上正确获取日志消息。当我从控制台运行时,会出现以下错误:

无法设置未定义的属性“className”

我相信这与作为数组的变量有关,因为如果我设置topLevel的索引,比如topLevel[0],它就可以完美地工作

我想用香草JS。没有JQuery

我已经搜索过类似的问题,但找不到任何超出我头脑的答案,或者只给出JQuery解决方案

我看过:


-->这一次让我的大脑流血。



答案可能隐藏在上面的帖子中,但如果是,我就找不到了

我在我的项目中遇到了同样的问题

基本上,我所做的是定义一个函数
add_listeners\u all
(如果只做一次,您可能不需要这样的函数)

这是密码

function add_listeners_all( selector, fun ) {
    Array.prototype.slice.apply(document.querySelectorAll(selector)).forEach(el) {
        el.addEventListener('click', fun);
    });
});
我不记得我是如何让它做到这一点的,但它工作得非常完美,正如您在实时演示中所看到的(正在开发中,不要期望它能工作)

如您所见,您可以将
document.querySelectorAll(selector)
替换为
toplevel
数组,并为您的函数替换
fun


再一次,这段记忆对我来说非常模糊,所以这可能不起作用。如果它不起作用,请随意否决并向我发泄你的愤怒。

我在我的项目中遇到了同样的问题

基本上,我所做的是定义一个函数
add_listeners\u all
(如果只做一次,您可能不需要这样的函数)

这是密码

function add_listeners_all( selector, fun ) {
    Array.prototype.slice.apply(document.querySelectorAll(selector)).forEach(el) {
        el.addEventListener('click', fun);
    });
});
我不记得我是如何让它做到这一点的,但它工作得非常完美,正如您在实时演示中所看到的(正在开发中,不要期望它能工作)

如您所见,您可以将
document.querySelectorAll(selector)
替换为
toplevel
数组,并为您的函数替换
fun


再一次,这段记忆对我来说非常模糊,所以这可能不起作用。如果它不起作用,请随意否决并向我发泄愤怒。

在现代浏览器中,您应该添加一个侦听器:

var topLevel = document.getElementsByClassName("has-dropdown");

for (var i = 0; i < topLevel.length; i++) {
   topLevel[i].addEventListener('focus',function(event) {
      console.log("you have activated the dropdown");
     event.currentTarget.nextElementSibling.className  = "active";
   },false);
}
var topLevel=document.getElementsByClassName(“has下拉菜单”);
对于(变量i=0;i
参考:

旧浏览器

var topLevel = document.getElementsByClassName("has-dropdown");

for (var i = 0; i < topLevel.length; i++) {
    if (topLevel[i].addEventListener) {
          topLevel[i].addEventListener('focus',function(event) {
          console.log("you have activated the dropdown");
          event.currentTarget.nextElementSibling.className  = "active";
       },false);
    }
    else {
        topLevel[i].attachEvent("focus", function(event) {
        console.log("you have activated the dropdown");
        event.currentTarget.nextElementSibling.className  = "active";
   });
}
var topLevel=document.getElementsByClassName(“has下拉菜单”);
对于(变量i=0;i
在现代浏览器中,您应该添加一个侦听器:

var topLevel = document.getElementsByClassName("has-dropdown");

for (var i = 0; i < topLevel.length; i++) {
   topLevel[i].addEventListener('focus',function(event) {
      console.log("you have activated the dropdown");
     event.currentTarget.nextElementSibling.className  = "active";
   },false);
}
var topLevel=document.getElementsByClassName(“has下拉菜单”);
对于(变量i=0;i
参考:

旧浏览器

var topLevel = document.getElementsByClassName("has-dropdown");

for (var i = 0; i < topLevel.length; i++) {
    if (topLevel[i].addEventListener) {
          topLevel[i].addEventListener('focus',function(event) {
          console.log("you have activated the dropdown");
          event.currentTarget.nextElementSibling.className  = "active";
       },false);
    }
    else {
        topLevel[i].attachEvent("focus", function(event) {
        console.log("you have activated the dropdown");
        event.currentTarget.nextElementSibling.className  = "active";
   });
}
var topLevel=document.getElementsByClassName(“has下拉菜单”);
对于(变量i=0;i
我在JSFIDLE上试用了你的代码,效果如预期。看:我看了看你的小提琴,它在那里不起作用。当link2聚焦时,子菜单不出现。我想这是浏览器,对不起。我试用了Chrome。我在JSFIDLE上试用了你的代码,效果如预期。看:我看了看你的小提琴,它在那里不起作用。当ink2获得了焦点,子菜单没有出现。我想这是浏览器,很抱歉。我尝试使用Chrome。不确定这是如何应用的。您声明“我不记得我是如何让它做到这一点的,但它工作得很好,正如您在实时演示中看到的那样”但“然后声明”(正在开发中,不要期望它能工作)。我点击了你的项目和链接,但没有看到任何与我的问题相关的内容。也许我错过了。你能进一步解释一下吗?正如我所说,我刚开始学习,可能没有正确地连接点。对不起。我处理给予元素的方式