javascript手工制作悬浮菜单_javascript技巧

有选择性的重复造一些轮子,未必是件坏事。Aaron的博客上加了一个悬浮菜单,貌似显得很高大上了。虽然这类小把戏也不是头一次见了,但是从未自己写过。今天就选择性的拿这个功能写一写。下面是这个轮子的开发过程,也可以当作是一篇需求文档的分析和实现过程。

演示地址:http://sandbox.runjs.cn/show/to8wdmuy

源码下载:https://github.com/bjtqti/floatmenu

第一步创建dom节构:

复制代码 代码如下:

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
    <title>AppCarrier</title>
    <link rel="stylesheet" href="menu.css">
</head>
<body>
    <div id="content">
              <h1 id="test1">test1</h1>
              <p>The past can hurt. But you can either run from it or learn from it</p>
              <p>过去是痛楚的,但你要么逃避,要么从中成长</p>
              <p>One meets his destiny on the road he takes to avoid it</p>
              <p>往往在逃避命运的路上,却与之不期而遇</p>
              <p>Rules are meant to be broken</p>
              <p>规则就该被打破。</p>
              <p>Years may wrinkle the skin, but to give up enthusiasm wrinkles the soul.</p>
              <p>岁月流逝只令容颜苍老,激情不再却使心灵枯萎。</p>
              <h1 id="test2">test2</h1>
              <p>只有不断地练习学到的知识,你才能真正掌握它。</p>
              <p>Live every day to the fullest.</p>
              <p>尽享每日。</p>
              <p>Keep your eyes on the stars, and your feet on the ground.</p>
              <p>志存高远,脚踏实地。</p>
              <p>Always be up for an unexpected adventure.</p>
              <p>随时准备开始一场意外冒险吧。</p>
              <p>Life is full of disappointment. You can't dwell on things. You have to move on.</p>
              <p>生活常不如意,别沉溺往事,要勇往直前。</p>
              <p>I'm a free spirit. I can't be caged.</p>
              <p>我的灵魂是自由的,不该被束缚。</p>
              <p>Sometimes the heart sees what is invisible to the eye.</p>
              <p>目不见者,心可感之</p>
              <p>The simple things are also the most extraordinary things, and only the wise can see them.</p>
              <p>最平凡的事也是最非凡的事,只有智者才明白。</p>
              <h1 id="test3">test3</h1>
              <p>how many xxxxxx</p>
              <p>how many xxxxxx</p>
              <p>how many xxxxxx</p>
              <p>how many xxxxxx</p>
              <p>how many xxxxxx</p>
              <p>how many xxxxxx</p>
              <p>how many xxxxxx</p>
              <p>how many xxxxxx</p>
              <p>how many xxxxxx</p>
              <p>how many xxxxxx</p>
              <p>how many xxxxxx</p>
              <p>how many xxxxxx</p>
              <p>how many xxxxxx</p>
              <p>how many xxxxxx</p>
              <p>how many xxxxxx</p>
              <p>how many xxxxxx</p>
              <h1 id="test4">test4</h1>
              <p>how many xxxxxx</p>
              <p>how many xxxxxx</p>
              <p>how many xxxxxx</p>
              <p>how many xxxxxx</p>
              <p>how many xxxxxx</p>
              <p>how many xxxxxx</p>
              <p>how many xxxxxx</p>
              <p>how many xxxxxx</p>
              <p>how many xxxxxx</p>
              <p>how many xxxxxx</p>
              <p>how many xxxxxx</p>
              <p>how many xxxxxx</p>
              <p>how many xxxxxx</p>
              <p>how many xxxxxx</p>
              <p>how many xxxxxx</p>
              <p>how many xxxxxx</p>
    </div>
    <div class="menu" id="menubar">
        <p class="static">隐藏</p>
        <ul>
            <li><a href="#test1">test1</a></li>
            <li><a href="#test2">test2</a></li>
            <li><a href="#test3">test3</a></li>
            <li><a href="#test4">test4</a></li>
        </ul>
    </div>
</body>
<script src="menu.js"></script>
</html>

第二步准备css文件:

复制代码 代码如下:

ul {
    list-style-type: none;
}
a {
    text-decoration: none;
}
/*文章内容区*/
#content {
    width:400px;
    margin: 0 auto;
    font-size: 2em;
}
/*悬浮菜单*/
.menu {
    position: fixed;
    top:20%;
    right: 0;
    width:200px;
    border: 1px solid gray;
    border-radius: 5px;
}
.menu li {
    height: 2em;
    line-height: 2em;
}
.red {
    color : red;
}
.hide {
    display: none;
}
/*隐藏悬浮菜单*/
.slideIn {
    transform : translate3d(202px, 0, 0);
    transition-duration : .5s;
}
/*显示悬浮菜单*/
.slideOut {
    transform : translate3d(0, 0, 0);
    transition-duration : .5s;
}
.static {
    color:#007aff;
    text-align: center;
}
/*显示悬浮球*/
.toShow {
    display: block;
        width: 4.8em;
        height: 2em;
        line-height: 2em;
        border-radius: .5em;
    border:1px solid gray;
    transform : translate3d(-5em, 0, 0);
    transition-duration : 1s;
}

第三步开始编写js代码:

复制代码 代码如下:

(function(doc){
    //收集各章节的链接位置
     var pos = [],
         //收集菜单上的项目
         links = doc.getElementsByTagName('a'),
         //收集章节的标题
         titles = doc.getElementsByTagName('h1'),
         //悬浮菜单
         menu = doc.getElementById('menubar'),
         //当前选择项
         currentItem=null;
     //添加红色样式
     var addClass = function (element){
             currentItem && currentItem.removeAttribute('class');
             element.setAttribute('class','red');
             currentItem = element;
         },
         //网页被卷去的高:
        getScrollTop = function (){
            return Math.ceil(document.body.scrollTop)+1;
        },
         //计算滚动位置
        startScroll = function (){
            var scrollTop = getScrollTop(),
                len = titles.length,
                i = 0;
            //第一条
            if(scrollTop>=0 && scrollTop<pos[0]){
                addClass(links[0]);
                return;
            }
            //最后一条
            if(scrollTop>=pos[len-1]){
                addClass(links[len-1]);
                return;
            }
            //中间
            for(;i<len;i++){
                if(scrollTop > pos[i] && scrollTop < pos[i+1]){
                    addClass(links[i]);
                    break;
                }
            }
    };
     //点击列表中的链接变色
     menu.onclick=function(e){
         var target = e.target || e.srcElement;
         if(target.nodeName.toLowerCase() === 'a'){
             //列表项状态指示
             addClass(target);
             return;
         }
         if(target.nodeName.toLowerCase() === 'p'){
             if(target.className == 'static'){
                 //隐藏菜单
                 this.className = 'menu slideIn';
                 setTimeout(function(){
                     target.className = 'static toShow';
                     target.innerHTML = '显示';
                 },1000);
             }else{
                 //显示菜单
                 target.className = 'static';
                 target.innerHTML = '隐藏';
                 this.className = 'menu slideOut';
             }
         }
     }
    //计算各章节的初始位置
    var ln = titles.length;
    while(--ln>-1){
        //titles[len].offsetParent.offsetTop = 0;
        pos.unshift(titles[ln].offsetTop);
    }
    startScroll();
    //监听滚动
    window.onscroll = function(){
          startScroll()
    }
})(document);

分析:

    1. 实现自动跳转到指定节

          这一步可以利用<a>标签的锚功能来做,由于html5以后不支持name 属性(HTML5 不支持。规定锚的名称。),所以考虑用ID来跳转。

    2. 标识悬浮菜单中的项属于左边内容中的哪个章节。

          这一步是难点,先简单分析一下:

            2.1 第一种情况,就是人为点击菜单项。这个很容易,只要标识点击的元素就可以了。

            2.2 第二种情况,通过鼠标中键滚动或拖动滚动条,这个时候要关联左边内容和右边菜单项,这是最难的地方。考虑分步实施,先易后难,各各击破的策略。

             2.2.1 先收集标题元素的坐标高度。也就是所有的h1标签的垂直高度。存入数组1.

             2.2.2 收集菜单项中的a元素,存入数组2.

                2.2.3  监听滚动事件,判断当前内容属于哪个菜单项。

                    做一步的时候,建议在稿纸上画一个图:

            A1

                         ****************
                         *       A2
                         *
                         ****************
                         *       A3
                         *
                         ****************
                         *
                         *     A4
                         *

       每滚动一次,就判断当前滚动的距离是在哪一个区间,如果是0到A1则是第1章,A1到A2则是第2章,以此类推。

                    关于元素的位置高度,我这里简单地用element.offsetTop来获取,可能会存在兼容性问题,如果用jquery来做的话,应当是$('element').offset().top,

                    同样的,滚动条的高度,我也是简单的用了document.body.scrollTop来获取,如果换成jquery的话,应当是$(window).scrollTop();

                   画图的作用是把抽象的问题具体化,帮助我们思考,找出规律。也许称为“建模”会显得高大上一些吧。

                    需要强调的是数组1和数组2中的关系应当是一一对应的。如<a href="#h1">对应的是<h1 id="h1">。

           2.3 第三种情况,直接进入页面时的菜单状态指示。比如通过index.html#h3这样的地址进来,菜单中的h3应当要突出显示。

    3.  实现悬浮菜单的显示和隐藏动画。

        3.1  这一步应当是比较简单的,可以考虑先做。利用css3的tramsform属性就可以了,简单高效,跨浏览器的话,注意兼容。

      注意transform : translate3d(x轴, y轴, z轴); 用3d是可以利用硬件加速,增加动画效果,但是功耗会增加,善用!第一个参数是控制左右方向,如果为正,则表示向右移动,如果为负则向左移动。这么说其实是不严谨的,实际上应当根据参考点来确定,比如元素的静止时的x坐标是0,那么增加x的值向右,减少为向左,0为复位。

    分析完之后,就是编写代码了。这没有什么好说的。尽情享受敲击键盘产生的乐感吧。

    写完之后,预览一下,点击菜单,跳入指定章节,同时点击项变红色,刷新当前页面,依赖显示正确。滑动一下滚轮,菜单项随着内容的变化而相应的变化,拖动一下滚动条,也是这样,最后点击一下隐藏,菜单缩回去,点击显示,菜单滑出来。这样悬浮功能就做完了。

以上就是本文的全部内容了,希望大家能够喜欢。

时间: 2024-08-31 08:09:13

javascript手工制作悬浮菜单_javascript技巧的相关文章

javascript手工制作悬浮菜单

 这篇文章主要介绍了javascript手工制作悬浮菜单,主要也是想自己练练手,感觉还不错,这里推荐给大家.     有选择性的重复造一些轮子,未必是件坏事.Aaron的博客上加了一个悬浮菜单,貌似显得很高大上了.虽然这类小把戏也不是头一次见了,但是从未自己写过.今天就选择性的拿这个功能写一写.下面是这个轮子的开发过程,也可以当作是一篇需求文档的分析和实现过程. 演示地址:http://sandbox.runjs.cn/show/to8wdmuy 源码下载:https://github.com/

JavaScript几种形式的树结构菜单_javascript技巧

1.悬浮层树(Tree) 这种树结构实现类似面包屑导航功能,监听的是节点鼠标移动的事件,然后在节点下方或右方显示子节点,依此递归显示子节点的子节点. 用户首页博客设置文章相册留言评论系统 这里要注意几个小问题,其一这种树结构是悬浮层绝对定位的,在创建层的时候一定要直接放在body的下面,这样做的是确保在IE里面能遮掩住任何层,因为在IE里面是有stacking context这种东西的潜规则在里面的,另外当然还有一个select你能遮住我吗?老掉牙的问题,这里是采用在每个悬浮层后面加个ifram

Javascript实现鼠标右键特色菜单_javascript技巧

在Web端,通常是不需要右键菜单,各个浏览器也有自己的右键菜单.但是对于一些特殊的网页,是需要右键菜单来增加用户体验的,比如百度音乐,QQ邮箱,相信大家都在Web端使用过右键菜单了,现在来分享一下如何实现,比较简单. 运行代码: window.onload = function() { document.oncontextmenu = block; document.body.onmouseup = function(event) { if (!event) event = window.eve

javascript 异常处理使用总结_javascript技巧

JavaScript中的异常可以用try..catch..finally语句来处理,也可以手动的来抛出异常. 1.使用try..catch..finally语句来处理异常 js代码在执行过程中如果出现异常,会手动创建一个异常类对象,该异常类对象将被提交给浏览器,这个过程称为"抛出异常".当浏览器接收到一场对象时,会寻找能处理这一异常的代码并把当前异常对象提交给其处理,这一过程被称为"捕获异常".try..catch..finally语句的基本语法格式为: 复制代码

JS中用三种方式实现导航菜单中的二级下拉菜单_javascript技巧

我们在淘宝.搜狐等大型网站上都可以看到使用的一些二级下拉菜单,比如下面这张图片.那么如何实现导航菜单栏中的二级下拉菜单?下面小编给大家分享实现思路. 但是如何实现类似的图片呢?实际上,我们有至少三种方式来实现,下面,我附上代码供大家参考. 1.仅使用html和css <meta charset="UTF-8"> <title>Document</title> <style> *{margin:0;padding: 0;list-style

web性能优化之javascript性能调优_javascript技巧

JavaScript 是一个比较完善的前端开发语言,在现今的 web 开发中应用非常广泛,尤其是对 Web 2.0 的应用.随着 Web 2.0 越来越流行的今天,我们会发现:在我们的 web 应用项目中,会有大量的 JavaScript 代码,并且以后会越来越多.JavaScript 作为一个解释执行的语言,以及它的单线程机制,决定了性能问题是 JavaScript 的软肋,也是 web 软件工程师们在写 JavaScript 需要高度重视的一个问题,尤其是针对 Web 2.0 的应用.绝大多

纯javascript实现自动发送邮件_javascript技巧

描述: 此JavaScript将帮助你的电子邮件的人.只要按一下电子邮件,有人!和JavaScript会要求的电子邮件地址,主题,等等然后你,新的邮件,是向你打开了. <SCRIPT LANGUAGE="JavaScript"> <!-- Begin function mailsome1(){ who=prompt("Enter recipient's email address: ","antispammer@earthling.net

Google Suggest ;-) 基于js的动态下拉菜单_javascript技巧

基本的原理是在当前窗口创建了一个iframe,然后将相关关键词的提示列表在iframe中,并通过列表点选将选定项放到搜索框中.能这么快的能将所有相关关键词的检索数列出,看来所有的提示词已经提前进行了预搜索和数量记录.试了一下"sex",没有相关检索提示,看来对搜索词进行了严格的色情过滤. 另外:这一动态列表功能也应用在GMail的地址栏自动输入完成中,如图:Google自动完成的源代码如下: // Copyright 2004 and onwards Google Inc. var w

基于javascript实现全国省市二级联动下拉选择菜单_javascript技巧

本文实例讲述了js实现全国省市二级联动下拉选择菜单,分享给大家供大家参考.具体如下: 效果图:   具体代码: <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=gb2312" /> <title>无标题文档</title> <script type="text/javascript"