jquery hover最后解决 - 不再疑惑 - 例子在这里

时间:2022-04-20 21:39:10
  1. hover具有动画累计的bug, 可以使用 stop 或 filter(:not(:animated))来消除, 但是, 即使这样, 当鼠标反复滑入或滑出的时候, 虽然没有动画累计的问题, 但是 下面的显示div仍然会 一上一下的, 但是, 这个没有什么影响. 因为, 很少会有这样的人来进行这样的操作的!

  2. 在做hover的时候, 上面的触发和下面的显示div, 因为触发显示后, 鼠标要 "移出" 整个区域(包括触发部分和下面的显示区域), 才会隐藏下面的显示区域 , 因此, 应该把 "触发+显示"作为 一个整体的 div来处理.

  3. 做hover 划过 展开层的 动画, 应该使用 SlideUp或者 slideDown (slideToggle), 而不要使用animate 来手动的操作height width, 因为这个heigth, width, position等的位置是 比较麻烦的, 并且有时候是在经常变化, 也是不精确的!

  4. 今后, 凡是看到 "多个并列" 的内容的时候, 不管是div 还是 img等, 都最好 , 首先考虑的就是 使用 ul> li 等, 水平方向上的布局, 尽量的首先考虑 脚手架grid 和 table, 而不使用 float.

  5. 要将ul和li看作是两个不同的部分, 要把 ul 看作是跟div table 一样的 容器, 不要忽略这个 ul, 在ul上可以有u很多 css和js操作的!

  6. 要实现 hover 的效果, 关键是: slideDown(), slideDown的作用 是 "通过高度的变化(向下增大) 来显示 隐藏的元素" 就是说, 如果原来的元素 是 "隐藏"的, 通过slideDown 是可以把 它显示出来的! 但是 这个只限于针对 css为: display:none的 情况, 而不适合 css为 visibility: hidden的情况.
    jquery hover最后解决 - 不再疑惑 - 例子在这里

  7. 注意 由于ul是块级 元素 , 所以要给ul 或li设定 宽度! 否则就会在整个行的宽度内 起效果...


今后编写这种hover的时候 步骤是: 首先, 把要显示的部分, 用 静态的 方法把它呈现出来, 然后才用 js 对要 有动画的 哪部分用 动画显示出来.

非常重要的两点! 是实现 hover的 关键点

  1. toggle方法函数: 它有两个方面的用法, 以前只是 提到了一个, 即: 一方面, toggle是在(当元素被多次 单击的时候! )多个 事件函数间 轮询, 遍历, 调用形式是: toggle(f1, f2, f3, ...). 第二方面, 是toggle 是在 元素的 显示/隐藏 之间 进行切换!(即在show/hide之间 切换, 同样的切换还有: slideUp, slideDown, slideToggle. 而show, hide之间的切换就不用 在toggle后面写 show/hide了, 直接是 toggle了 ).

  2. 关于元素的显示 和 隐藏效果的实现.
    在垂直方向上 的hover, 使用 slideup和 slidedown进行切换 这个是 好理解 的!
    而在水平方向上, 要实现 div内容的 水平方向上的 左右滑动 效果的动画, 这时, 只需要直接使用 show/hide 方法 就好了. 不需要 使用 animate("width": ...) show/hide([speed]) 就可以实现div在水平方向上的动画!

  3. 关于show 和hide的深入理解!
    show和hide的显示和隐藏, 可以是直接的, 生硬的方式;
    其实, show和hide还可以有动画方式的执行, 即以时间, 或关键字("fast, slow,normal")等的显示
    这两种方式都是 必要的 , 有的时候 就要 show/hide的方式, 这时就不会出现闪烁/晃动的现象;
    而有时候, 又需要有动画的形式.


对于多次使用的jquery对象变量, 可以将选择器的结果用 $var_name来表示, 这时的 jquery对象变量, 就像 php变量一样 使用方便!

javasript中的多选分支结构: 跟c语言中的switch分支结构一样, 同样是 switch...case..break; .default..., 注意default后面就没有 break了, 因为default后面就没有情况判断了, 直接就结束了...

javascript中 其实也是支持 多行字符串的! 可以使用: 多行字符串 相加 +, 使用行尾反斜线, 使用字符串数组.join('')等方法, 通常使用的是 第二种, 反斜线法, 注意 反斜线后不能再有 空格, 因为这里实际上 对 "回车/换行等" 符号进行 转义!

注意看问题的 灵活性和 一分为二! hover是 mouserover和 mouserout的结合体, 很多时候, 由于问题的复杂性, 可能再hover 中 不一定要同时把两个 行为函数都写上, 可能会让 某一个行为函数为空! 或者 , 不要固执地认为, 总是 使用 hover, 有时候, 由于问题的复杂性, 可能 考虑移入 移出 的对象/范围 是不同的! 所以 使用hover 可能就不合适, 那么就要针对 不同的对象, 分别写 mouseover 和 mouserout 行为函数

<nav class="navbar navbar-default" > 
    <ul class="nav navbar-nav" style="margin-left:100px;">
        <li id="lii">
        <a href="#">list1</a>    // 这个时触发 部分
        <table class="">         // 这个时显示  部分
            <tr id="all_area">     // 为了方便布局, 用table 形成 水平方向上并列的 两栏 结构
                <td > 
                    <ul class="list-group" id="ull">
                        <li class="list-group-item">listr11</li>
                        <li class="list-group-item">listr12</li>
                        <li class="list-group-item">listr13</li>
                        <li class="list-group-item">listr14</li>
                        <li class="list-group-item">listr15</li>
                    </ul>

                </td>
                <td style="border: 0px solid #2228f8; padding: 5px 0 0 30px;" id="content" valign="top">
                </td>
            </tr>
        </table>

        </li>
        <li><a href="#">list2</a></li>
        <li><a href="#">list3</a></li>
        <li><a href="#">list4</a></li>
    </ul>
</nav>


<script type="text/javascript" charset="utf-8">

// 这个是js的 多行字符串
var cont1=' <a href="#">cont1</a>\
          <a href="#">cont2</a>\
          <a href="#">cont3</a>\
          <a href="#">cont4</a> <br> <a href="#">cont01</a>\
          <a href="#">cont02</a>\
          <a href="#">cont03</a> ';


var cont2=' <a href="#">foo1</a> <a href="#">foo2</a> <a href="#">foo3</a> <a href="#">foo4</a> <br> <a href="#">foo01</a> <a href="#">foo02</a> <a href="#">foo03</a> ';

var cont3=' <p><a href="#">bar1</a>\
          <a href="#">bar2</a>\
          <a href="#">bar3</a>\
          <a href="#">bar4</a> </p><p> <a href="#">bar01</a>\
          <a href="#">bar02</a>\
          <a href="#">bar03</a> </p>';

$('#lii>a').click(function(){
        $('#lii>table').toggle();   // 这个就是 单击"触发"的时候, 切换显示/隐藏 "显示区"
        });

$('#ull li').each(function(index){

        var idx = index+1;

       $(this).hover(function(){  // 注意对象, 这里的hover 对象 只是针对 ul>li
                var $content = $('#content');
                switch(idx){
                case 1:
                console.log(cont1);
                $content.html(cont1);
                break;
                case 2:
                console.log(cont2);
                $content.html(cont2);
                break;
                case 3:
                console.log(cont3);
                $content.html(cont3);
                break;
                default:
                $content.html('content  content content'); // default后面不用 break;
                }

                $content.show();
        },

            function(){                //// 这里是重点, 也是所有的技巧! 使用 一个 "空的" function, 来对父元素tr#all_area的鼠标移出事件进行 "屏蔽"
                //$('#content').hide();     // 使得当鼠标移出"触发区" 的时候, 右边的 子级 菜单并不被 关闭!
            });


});
$('tr#all_area').hover(function(){},      // 注意这里的对象, 变了, 不再时ul>li, 而是整个tr区域了.

                                         // 同时, 注意, 移入时的函数代码 又为空了.

function(){   
        
        $('#content').hide();
        });

--------------------------------------



</script>

再写mouseover和mouseout的时候, 还要考虑 如果是 对父元素 进行 事件的 函数执行, 是会包含 并传递到 这个父元素所 包含的 所有子元素 的同样事件的. 比如: 写父元素的 mouseout事件时, 就包含了 其中包含的 子元素的 事件的 执行! 此时如果移出触发元素, 右边的显示区域也就隐藏了. 而实际上这样是不对的! 因此, 有时候, 还不能间单的写 mouseover/mouseout, 还得要使用 hover, 并且利用子元素 的两个 函数, 对 父元素的事件 进行 覆盖!!! 使 父元素中的事件 对其中的某一个 子元素的 同一事件 被 屏蔽!!

总之, 就是一句话, 只要明确了 各个元素 之间的 显示/隐藏, 触发关系, 明确了show/hide/toggle/ slideup/slidedown/slidetoggle动画, 和 hover/mouseover/mouseout事件等,, 就一定可以 根据要求来写动画的.

要 千万 消除 一旦是 鼠标滑动, 鼠标移入移出, 就是hover 这个是非常 片面的, 也是 很危险的 "思维 死胡同" . 应该考虑 作用的对象(作用的范围) 是否是 同一个, 如果是对同一个对象的移出/移入, 可以使用hover, 如果不是同一个对象, 就不能使用hover, 要分别写mouseover和mouseout. 当然还要考虑 父子 元素之间的事件 的冒泡和包含关系!! 以及使用子元素 对 父元素 的事件 的屏蔽!