许新江 發表於 2023-7-10 00:00:00

WordPress导航菜单的滚动和淡入淡出效果的实现要点

<p>
<strong>滚动导航菜单</strong><br>
滚动菜单, 顾名思义是以滚动的方式显示和隐藏菜单的. 其实跟淡入淡出菜单和滚动菜单的原理是一样的, 前者是在触发事件的时候改变菜单的透明度, 而后者则是改变菜单的高度. 那为什么后者的处理难度会比前者高呢? 这正因为菜单高度的处理比透明度有更高的技巧要求. 下面我们就讨论一下该如何处理, 并难在什么地方.</p>
<p>
初期化处理<br>
为了处理更加灵活, 我们需要为它定义一个作为参数的滑动速度, 也就是每一个单位时间间隔, 菜单高度的改变幅度. 另外, 我们需要将菜单的初始高度定为 0.</p>
<div>
<div>
<div id="highlighter_313929">
<div>
<span>?</span>
</div>
<table border="0" cellpadding="0" cellspacing="0"><tbody><tr>
<td>
<div>
1</div>
<div>
2</div>
<div>
3</div>
<div>
4</div>
</td>
<td>
<div>
<div>
<code>// 速度来自参数, 默认没个时间单位移动 10px</code>
</div>
<div>
<code>this.speed = speed || 10;</code>
</div>
<div>
<code>// 设定初始化高度</code>
</div>
<div>
<code>this.util.setStyle(this.body, </code><code>'height'</code><code>, </code><code>'0'</code><code>);</code>
</div>
</div>
</td>
</tr></tbody></table>
</div>
</div>
<div id="codetool">
<div>
<textarea></textarea>
</div>
</div>
</div>
<p>
展开和折叠<br>
展开和折叠的方法对应淡入淡出菜单的加强和减小不透明度, 只是处理对象不一样, 原理是一样的. 要注意将获取的高度转为整型再进行计算.</p>
<div>
<div>
<div id="highlighter_192827">
<div>
<span>?</span>
</div>
<table border="0" cellpadding="0" cellspacing="0"><tbody><tr>
<td>
<div>
1</div>
<div>
2</div>
<div>
3</div>
<div>
4</div>
<div>
5</div>
<div>
6</div>
<div>
7</div>
<div>
8</div>
<div>
9</div>
<div>
10</div>
<div>
11</div>
<div>
12</div>
<div>
13</div>
<div>
14</div>
<div>
15</div>
<div>
16</div>
<div>
17</div>
<div>
18</div>
<div>
19</div>
<div>
20</div>
<div>
21</div>
<div>
22</div>
<div>
23</div>
<div>
24</div>
<div>
25</div>
<div>
26</div>
<div>
27</div>
<div>
28</div>
<div>
29</div>
<div>
30</div>
<div>
31</div>
<div>
32</div>
</td>
<td>
<div>
<div>
<code>expand: </code><code>function</code><code>() {</code>
</div>
<div>
<code> </code><code>// 获取当前高度, 并整型化</code>
</div>
<div>
<code> </code><code>var</code> <code>height = parseInt(this.util.getStyle(this.body, </code><code>'height'</code><code>));</code>
</div>
<div>
<code> </code><code>// 在时间单位内加上速度, 直到高度等于或超过最大高度</code>
</div>
<div>
<code> </code><code>height += this.speed;</code>
</div>
<div>
<code> </code><code>if</code><code>(height &gt;= this.height) {</code>
</div>
<div>
<code> </code><code>height = this.height;</code>
</div>
<div>
<code> </code><code>// 取消循环调用</code>
</div>
<div>
<code> </code><code>clearTimeout(this.tid);</code>
</div>
<div>
<code> </code><code>}</code>
</div>
<div>
<code> </code><code>// 重新设定菜单高度</code>
</div>
<div>
<code> </code><code>this.util.setStyle(this.body, </code><code>'height'</code><code>, height + </code><code>'px'</code><code>);</code>
</div>
<div>
<code>}</code>
</div>
<div>
<code> </code>
</div>
<div>
<code>/**</code>
</div>
<div>
<code> </code><code>* 折叠菜单, 直到高度为 1 时隐藏菜单</code>
</div>
<div>
<code> </code><code>*/</code>
</div>
<div>
<code>collapse:</code><code>function</code><code>() {</code>
</div>
<div>
<code> </code><code>// 获取当前高度, 并整型化</code>
</div>
<div>
<code> </code><code>var</code> <code>height = parseInt(this.util.getStyle(this.body, </code><code>'height'</code><code>));</code>
</div>
<div>
<code> </code><code>// 在时间单位内减去速度, 直到高度等于或小于 1</code>
</div>
<div>
<code> </code><code>height -= this.speed;</code>
</div>
<div>
<code> </code><code>if</code><code>(height &lt;= 1) {</code>
</div>
<div>
<code> </code><code>height = 1;</code>
</div>
<div>
<code> </code><code>// 隐藏菜单</code>
</div>
<div>
<code> </code><code>this.util.setStyle(this.body, </code><code>'visibility'</code><code>, </code><code>'hidden'</code><code>);</code>
</div>
<div>
<code> </code><code>// 取消循环调用</code>
</div>
<div>
<code> </code><code>clearTimeout(this.tid);</code>
</div>
<div>
<code> </code><code>}</code>
</div>
<div>
<code> </code><code>// 重新设定菜单高度</code>
</div>
<div>
<code> </code><code>this.util.setStyle(this.body, </code><code>'height'</code><code>, height + </code><code>'px'</code><code>);</code>
</div>
<div>
<code>}</code>
</div>
</div>
</td>
</tr></tbody></table>
</div>
</div>
<div id="codetool">
<div>
<textarea></textarea>
</div>
</div>
</div>
<p>
激活菜单的瞬间<br>
十分十分十分重要, 滚动菜单中最具技巧, 也最有意思的一部分.<br>
本程序中, 我对获取高度的方法进行了封装, 获取高度其实是返回元素的 offsetHeight. 按我的理解 (不知道是否正确), offsetHeight 会优先去获取 CSS 样式中的高度并返回, 当样式为空时才会去获取元素的实际高度. 所以有以下代码:</p>
<div>
<div>
<div id="highlighter_661307">
<div>
<span>?</span>
</div>
<table border="0" cellpadding="0" cellspacing="0"><tbody><tr>
<td>
<div>
1</div>
<div>
2</div>
<div>
3</div>
<div>
4</div>
<div>
5</div>
<div>
6</div>
<div>
7</div>
</td>
<td>
<div>
<div>
<code>// 获得初始高度, 当鼠标在菜单标题上时获得展开时的初始高度, 当鼠标在菜单体上时取得菜单的实际高度</code>
</div>
<div>
<code>var</code> <code>initHeight = this.util.getStyle(this.body, </code><code>'height'</code><code>);</code>
</div>
<div>
<code>// 获得实际高度, 必须先清空样式的高度, 否则只会得到样式中的高度</code>
</div>
<div>
<code>this.util.setStyle(this.body, </code><code>'height'</code><code>, </code><code>''</code><code>);</code>
</div>
<div>
<code>this.height = this.util.getHeight(this.body);</code>
</div>
<div>
<code>// 重新设定初始高度</code>
</div>
<div>
<code>this.util.setStyle(this.body, </code><code>'height'</code><code>, initHeight);</code>
</div>
</div>
</td>
</tr></tbody></table>
</div>
</div>
<div id="codetool">
<div>
<textarea></textarea>
</div>
</div>
</div>
<p>
<strong>淡出淡入导航菜单</strong><br>
实施操作</p>
<p>
前面的分析说得有点啰嗦了, 还是看看代码吧. :) 为了突出改动的部分, 我在代码中加入了一些 Log.</p>
<p>
初始化<br>
初始不透明度为 0, 而最大不透明度为被设定值或者 1.</p>
<div>
<div>
<div id="highlighter_352896">
<div>
<span>?</span>
</div>
<table border="0" cellpadding="0" cellspacing="0"><tbody><tr>
<td>
<div>
1</div>
<div>
2</div>
<div>
3</div>
</td>
<td>
<div>
<div>
<code>// 定义透明度, 默认透明</code>
</div>
<div>
<code>this.opacity = 0;</code>
</div>
<div>
<code>this.maxopacity = opacity || 1;</code>
</div>
</div>
</td>
</tr></tbody></table>
</div>
</div>
<div id="codetool">
<div>
<textarea></textarea>
</div>
</div>
</div>
<p>
激活<br>
先进行前期处理, 再对菜单的透明度进行处理.</p>
<div>
<div>
<div id="highlighter_861055">
<div>
<span>?</span>
</div>
<table border="0" cellpadding="0" cellspacing="0"><tbody><tr>
<td>
<div>
1</div>
<div>
2</div>
<div>
3</div>
<div>
4</div>
<div>
5</div>
<div>
6</div>
<div>
7</div>
<div>
8</div>
<div>
9</div>
<div>
10</div>
<div>
11</div>
<div>
12</div>
<div>
13</div>
<div>
14</div>
<div>
15</div>
<div>
16</div>
<div>
17</div>
<div>
18</div>
<div>
19</div>
<div>
20</div>
<div>
21</div>
<div>
22</div>
<div>
23</div>
</td>
<td>
<div>
<div>
<code>/**</code>
</div>
<div>
<code> </code><code>* 激活方法</code>
</div>
<div>
<code> </code><code>* 当鼠标移动到菜单标题是激活</code>
</div>
<div>
<code> </code><code>*/</code>
</div>
<div>
<code>activate: </code><code>function</code><code>() {</code>
</div>
<div>
<code> </code><code>// 获取当前菜单体的位置</code>
</div>
<div>
<code> </code><code>var</code> <code>pos = this.util.cumulativeOffset(this.title);</code>
</div>
<div>
<code> </code><code>var</code> <code>left = pos;</code>
</div>
<div>
<code> </code><code>var</code> <code>top = pos + this.util.getHeight(this.title);</code>
</div>
<div>
<code> </code>
</div>
<div>
<code> </code><code>// 定义激活时样式</code>
</div>
<div>
<code> </code><code>this.util.setStyle(this.body, </code><code>'left'</code><code>, left + </code><code>'px'</code><code>);</code>
</div>
<div>
<code> </code><code>this.util.setStyle(this.body, </code><code>'top'</code><code>, top + </code><code>'px'</code><code>);</code>
</div>
<div>
<code> </code><code>this.util.setStyle(this.body, </code><code>'visibility'</code><code>, </code><code>'visible'</code><code>);</code>
</div>
<div>
<code> </code><code>this.util.setStyle(this.body, </code><code>'opacity'</code><code>, this.opacity);</code>
</div>
<div>
<code> </code><code>this.util.setStyle(this.body, </code><code>'filter'</code><code>, </code><code>'alpha(opacity='</code> <code>+ this.opacity * 100 + </code><code>')'</code><code>);</code>
</div>
<div>
<code> </code>
</div>
<div>
<code> </code><code>if</code><code>(this.tid) {</code>
</div>
<div>
<code> </code><code>clearTimeout(this.tid);</code>
</div>
<div>
<code> </code><code>}</code>
</div>
<div>
<code> </code><code>// 不断加强菜单的不透明度</code>
</div>
<div>
<code> </code><code>this.tid = setInterval(this.util.bind(this, this.appear), 30);</code>
</div>
<div>
<code>}</code>
</div>
</div>
</td>
</tr></tbody></table>
</div>
</div>
<div id="codetool">
<div>
<textarea></textarea>
</div>
</div>
</div>
<p>
加强菜单的不透明度, 直到透明度到达最大不透明度.</p>
<div>
<div>
<div id="highlighter_201832">
<div>
<span>?</span>
</div>
<table border="0" cellpadding="0" cellspacing="0"><tbody><tr>
<td>
<div>
1</div>
<div>
2</div>
<div>
3</div>
<div>
4</div>
<div>
5</div>
<div>
6</div>
<div>
7</div>
<div>
8</div>
<div>
9</div>
<div>
10</div>
<div>
11</div>
<div>
12</div>
<div>
13</div>
<div>
14</div>
</td>
<td>
<div>
<div>
<code>/**</code>
</div>
<div>
<code> </code><code>* 加强不透明度, 直到最大不透明度</code>
</div>
<div>
<code> </code><code>*/</code>
</div>
<div>
<code>appear: </code><code>function</code><code>() {</code>
</div>
<div>
<code> </code><code>this.opacity += 0.1;</code>
</div>
<div>
<code> </code><code>if</code><code>(this.opacity &gt;= this.maxopacity) {</code>
</div>
<div>
<code> </code><code>this.opacity = this.maxopacity;</code>
</div>
<div>
<code> </code><code>// 取消循环调用</code>
</div>
<div>
<code> </code><code>clearTimeout(this.tid);</code>
</div>
<div>
<code> </code><code>}</code>
</div>
<div>
<code> </code><code>// 重新设定透明度</code>
</div>
<div>
<code> </code><code>this.util.setStyle(this.body, </code><code>'opacity'</code><code>, this.opacity);</code>
</div>
<div>
<code> </code><code>this.util.setStyle(this.body, </code><code>'filter'</code><code>, </code><code>'alpha(opacity='</code> <code>+ this.opacity * 100 + </code><code>')'</code><code>);</code>
</div>
<div>
<code>}</code>
</div>
</div>
</td>
</tr></tbody></table>
</div>
</div>
<div id="codetool">
<div>
<textarea></textarea>
</div>
</div>
</div>
<p>
解除<br>
对菜单的透明度进行处理.</p>
<div>
<div>
<div id="highlighter_42793">
<div>
<span>?</span>
</div>
<table border="0" cellpadding="0" cellspacing="0"><tbody><tr>
<td>
<div>
1</div>
<div>
2</div>
<div>
3</div>
<div>
4</div>
<div>
5</div>
<div>
6</div>
<div>
7</div>
<div>
8</div>
<div>
9</div>
<div>
10</div>
<div>
11</div>
</td>
<td>
<div>
<div>
<code>/**</code>
</div>
<div>
<code> </code><code>* 解除方法</code>
</div>
<div>
<code> </code><code>* 当鼠标移动出菜单标题是激活</code>
</div>
<div>
<code> </code><code>*/</code>
</div>
<div>
<code>deactivate: </code><code>function</code><code>(){</code>
</div>
<div>
<code> </code><code>if</code><code>(this.tid) {</code>
</div>
<div>
<code> </code><code>clearTimeout(this.tid);</code>
</div>
<div>
<code> </code><code>}</code>
</div>
<div>
<code> </code><code>// 不断减弱菜单的不透明度</code>
</div>
<div>
<code> </code><code>this.tid = setInterval(this.util.bind(this, this.fade), 30);</code>
</div>
<div>
<code>}</code>
</div>
</div>
</td>
</tr></tbody></table>
</div>
</div>
<div id="codetool">
<div>
<textarea></textarea>
</div>
</div>
</div>
<p>
减弱菜单的不透明度, 直到透明度为 0 并隐藏菜单.</p>
<div>
<div>
<div id="highlighter_610960">
<div>
<span>?</span>
</div>
<table border="0" cellpadding="0" cellspacing="0"><tbody><tr>
<td>
<div>
1</div>
<div>
2</div>
<div>
3</div>
<div>
4</div>
<div>
5</div>
<div>
6</div>
<div>
7</div>
<div>
8</div>
<div>
9</div>
<div>
10</div>
<div>
11</div>
<div>
12</div>
<div>
13</div>
<div>
14</div>
<div>
15</div>
<div>
16</div>
</td>
<td>
<div>
<div>
<code>/**</code>
</div>
<div>
<code> </code><code>* 减小不透明度, 直到完全透明隐藏菜单</code>
</div>
<div>
<code> </code><code>*/</code>
</div>
<div>
<code>fade:</code><code>function</code><code>() {</code>
</div>
<div>
<code> </code><code>this.opacity -= 0.1;</code>
</div>
<div>
<code> </code><code>if</code><code>(this.opacity &lt;= 0) {</code>
</div>
<div>
<code> </code><code>this.opacity = 0;</code>
</div>
<div>
<code> </code><code>// 隐藏菜单</code>
</div>
<div>
<code> </code><code>this.util.setStyle(this.body, </code><code>'visibility'</code><code>, </code><code>'hidden'</code><code>);</code>
</div>
<div>
<code> </code><code>// 取消循环调用</code>
</div>
<div>
<code> </code><code>clearTimeout(this.tid);</code>
</div>
<div>
<code> </code><code>}</code>
</div>
<div>
<code> </code><code>// 重新设定透明度</code>
</div>
<div>
<code> </code><code>this.util.setStyle(this.body, </code><code>'opacity'</code><code>, this.opacity);</code>
</div>
<div>
<code> </code><code>this.util.setStyle(this.body, </code><code>'filter'</code><code>, </code><code>'alpha(opacity='</code> <code>+ this.opacity * 100 + </code><code>')'</code><code>);</code>
</div>
<div>
<code>}</code>
</div>
</div>
</td>
</tr></tbody></table>
</div>
</div>
<div id="codetool">
<div>
<textarea></textarea>
</div>
</div>
</div>
頁: [1]
查看完整版本: WordPress导航菜单的滚动和淡入淡出效果的实现要点