美文网首页
js找弟弟

js找弟弟

作者: CeaCrab | 来源:发表于2018-03-10 16:16 被阅读0次

    hover之后动画效果

    我们可以在需要hover的元素hover之后用::after {content:''; display:block;}添加一个伪div。

    ul li a:hover::after{
      content: '';
      display: block;
      position: absolute;
      top: 100%;
      left: 0;
      width: 100%;
      height:3px;
      background: red;
      animation: huadong 0.5s;
    }
    @keyframes huadong{
      0%{
        width: 0;
      }
      100%{
        width: 100%;
      }
    }
    

    下拉列表

    • html
        <div class="nav">
            <ul>
                <li><a href="#">导航1</a></li>
                <li>
                    <a class="menuTagger" href="#">导航2</a>
                    <ul class="menu">
                        <li>1</li>
                        <li>2</li>
                        <li>3</li>
                    </ul>
                </li>
                <li>
                    <a class="menuTagger" href="#">导航3</a>
                    <ul class="menu">
                        <li>1</li>
                        <li>2</li>
                        <li>3</li>
                    </ul>
                </li>
                <li><a href="#">导航4</a></li>
                <li><a href="#">导航5</a></li>
                <li><a href="#">导航6</a></li>
                <li><a href="#">导航7</a></li>
            </ul>
        </div>
    
    • 获取我们需要监听的元素
    //通过className获取多个a标签aTags,aTags包装成了一个hash
        <script>
            let aTags = document.getElementsByClassName('menuTagger')
            console.log(aTags)
        </script>
    
    • 遍历监听的元素
        <script>
            let aTags = document.getElementsByClassName('menuTagger')
            for(let i=0; i<aTags.length; i++){  //遍历我们监听的元素
                aTags[i].onmouseenter = function(x){
                    console.log(x.currentTarget)//监听的元素
                    // console.log(x.target) //用户操作的元素
                    //监听的元素和用户操作的元素可能不是一个元素,如果我们遍历的两个a标签中有个span标签,我们监听的是a标签,很可能用户操作的是span标签。由于onmouseenter比较特殊(onclick可以测试)
                    
                    //此时我们需要我们监听的元素,所以需要x.currentTarget
                    
                }
            }
        </script>
    
    • js找弟弟
      我们给x.currentTarget这个变量定义个变量名,然后找到我们的下拉菜单,也就是监听元素a标签的弟弟。nextSibling --下一个元素(弟弟元素),因为两个元素之间有空格,用nextSibling很有可能找到的是一个文本,不是我们需要的元素,通过继续nextSibling,终于找到了ul。
      找到了一个文本,不是我们需要的
      继续找 找到了ul,这才是我们需要的
      假如中间有很多空格,我们怎么才能确定我们找到的是文本还是节点呢?我们可以递归用while循环来判断我们找到的是文本还是节点,一直寻找到节点。
      弟弟元素的语法和一些值 我们需要记住的是1表示节点,3表示文本
        <script>
            let aTags = document.getElementsByClassName('menuTagger')
            for(let i=0; i<aTags.length; i++){  
                aTags[i].onmouseenter = function(x){
                    let a = x.currentTarget
                    let brother = a.nextSibling //定义当前弟弟元素为a标签的弟弟元素
                    //如果当前弟弟元素的节点类型是3(文本类型),当前弟弟元素为下一个弟弟的弟弟…不停的找,找到类型不为3为1(节点类型)为止。
                    while(brother.nodeType === 3){//1是节点类型,3是文本类型
                        brother = brother.nextSibling 
                    }
                    console.log(brother)
                }
            }
        </script>
    
    while循环递归寻找节点

    如果一个元素后边有很多弟弟元素(节点),怎么确认找到的是我们需要的节点呢,很简单,borther.tag !=='UL'时,一直寻找找到为UL为止。然后给这个弟弟元素添加一个class,达到我们需要的效果。当鼠标移除时,不需要active这个效果,就移除它。

        <script>
            let aTags = document.getElementsByClassName('menuTagger')
            //添加active
            for(let i=0; i<aTags.length; i++){  
                aTags[i].onmouseenter = function(x){
                    let a = x.currentTarget
                    let brother = a.nextSibling //定义当前弟弟元素为a标签的弟弟元素
                    //如果当前弟弟元素的节点类型不是UL,当前弟弟元素为下一个弟弟的弟弟…不停的找,找到为止。
                    while(brother.tagName !== 'UL'){//如果弟弟元素的tagName不是‘UL’ tagName返回是大写的,ul必须是大写,一定要用小写的:brother.tagName.toLowe !== 'UL' === brother.tagName !== 'UL'
                        brother = brother.nextSibling 
                    brother.classList.add('active')
                    }
                }
            //移除active
            for(let i=0; i<aTags.length; i++){  
                aTags[i].onmouseleave = function(x){
                    let a = x.currentTarget
                    let brother = a.nextSibling //定义当前弟弟元素为a标签的弟弟元素
                    //如果当前弟弟元素的节点类型不是UL,当前弟弟元素为下一个弟弟的弟弟…不停的找,找到为止。
                    while(brother.tagName !== 'UL'){//如果弟弟元素的tagName不是‘UL’ tagName返回是大写的,ul必须是大写,一定要用小写的:brother.tagName.toLowe !== 'UL' === brother.tagName !== 'UL'
                        brother = brother.nextSibling 
                    brother.classList.remove('active')
                    }
                }
            }
        </script>
    
    • BUG1
      鼠标移到监听的a元素上,监听的下拉菜单被触发,这时我们鼠标移动开A标签,查看下拉菜单,发现消失了,因为a和下拉菜单是兄弟关系,是两个元素,应该监听他们的父级元素li标签。
        <script>
            let liTags = document.getElementsByClassName('menuTagger')
            //添加active
            for(let i=0; i<liTags.length; i++){  
                liTags[i].onmouseenter = function(x){
                    let li = x.currentTarget
                    let brother = li.getElementsByTagName('ul')[0] //getElements【s】 li下有多个子元素,虽然UL只有一项,也必须加上[0]
                    brother.classList.add('active')
                }
    
            //移除active
                liTags[i].onmouseleave = function(x){
                    let li = x.currentTarget
                    let brother = li.getElementsByTagName('ul')[0]
                    brother.classList.remove('active')
                }
            }    
        </script>
    
    • BUG2
      a标签hover之后,ul是active状态,当鼠标移动到下拉菜单时,hover效果消失了,ul还是active状态,a和li都是active状态,直接把active加到li上边,此时就不需要找a元素的弟弟ul了,当鼠标移入li,有active状态,鼠标移出,active状态消失。
    <script>
            let liTags = document.getElementsByClassName('menuTagger')
            //添加active
            for(let i=0; i<liTags.length; i++){  
                liTags[i].onmouseenter = function(x){
                    x.currentTarget.classList.add('active')             
                }
    
            //移除active
                liTags[i].onmouseleave = function(x){
                    x.currentTarget.classList.remove('active')  
                }
            }    
        </script>
    

    JS只负责切换状态,至于效果就有css来控制


    深度截图_选择区域_20180310154533.png
    • BUG3
      由于现在js切换的active状态是监听的那些,所以一些未监听的a元素没有active状态。我们可以给父级元素添加class,监听所有父级元素下有所的ul下的li。
      深度截图_选择区域_20180310161349.png

    相关文章

      网友评论

          本文标题:js找弟弟

          本文链接:https://www.haomeiwen.com/subject/jrrmfftx.html