类似于Stack Overflow的Intro Bar

8

我有一个简单的使用jQuery的顶部栏,就像Stack Overflow上的那个一样,但我希望它只在人们第一次访问网站时出现。

HTML代码:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
  "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html>
    <head>
        <script src="http://ajax.googleapis.com/ajax/libs/jquery/1.3.2/jquery.min.js"></script>
        <script type="text/javascript" src="bxSlider.js"></script>
        <title>topbar</title>

        <style type="text/css" media="screen">
            #message {
                font-family:Arial,Helvetica,sans-serif;
                position:fixed;
                top:0px;
                left:0px;
                width:100%;
                z-index:105;
                text-align:center;
                color:white;
                padding:2px 0px 2px 0px;
                background-color:#8E1609;
            }

            #example1 {
                text-align: center;
                width: 80%;
            }

            .close-notify {
                white-space: nowrap;
                float:right;
                margin-right:10px;
                color:#fff;
                text-decoration:none;

                padding-left:3px;
                padding-right:3px
            }

            .close-notify a {
                color: #fff;
            }

            h4, p {
                margin:0px;
                padding:0px;
            }
        </style>
    </head>

    <body>
        <DIV ID='message' style="display: none;">
            <DIV ID="example1">
                <DIV CLASS="item">
                    <h4>Head 1</h4>
                    <p>Text 1</p>
                </div><!-- end item -->

                <DIV CLASS="item">
                    <h4>Head 2</h4>
                    <p>Text 2</p>
                </div><!-- end item -->
            </div><!-- end example1 -->
            <a href="#" CLASS="close-notify" onclick="closeNotice()">X</a>
        </div>

        <script type="text/javascript">
            $(document).ready(function() {
             $("#message").fadeIn("slow");
             $('#example1').bxSlider({
              mode: 'slide',
              speed: 250,
              wrapper_CLASS: 'example1_container'
              });
            });

            function closeNotice() {
                $("#message").fadeOut("slow");
            }
        </script>
    </body>
</html>

bxSlider.js:

/**
*
*
* bxSlider: Content slider / fade / ticker using the jQuery javascript library.
*
* Author: Steven Wanderski
* Email: wandoledzep@gmail.com
* URL: http://bxslider.com
*
*
**/

jQuery.fn.bxSlider = function(options){

    /////////////////////////////////////////////////////////////////////////////////////////////////////////////
    // Declare variables and functions
    /////////////////////////////////////////////////////////////////////////////////////////////////////////////
    var defaults = {
        mode: 'slide',
        speed: 500,
        auto: false,
        auto_direction: 'left',
        pause: 2500,
        controls: true,
        prev_text: 'prev',
        next_text: 'next',
        width: $(this).children().width(),
        prev_img: '',
        next_img: '',
        ticker_direction: 'left',
        wrapper_class: 'container'
    };

    options = $.extend(defaults, options);

    if(options.mode == 'ticker'){
        options.auto = true;
    }

    var $this = $(this);

    var $parent_width = options.width;
    var current = 0;
    var is_working = false;
    var child_count = $this.children().size();
    var i = 0;
    var j = 0;
    var k = 0;

    function animate_next(){
        is_working = true;
        $this.animate({'left':'-' + $parent_width * 2 + 'px'}, options.speed, function(){
            $this.css({'left':'-' + $parent_width + 'px'}).children(':first').appendTo($this);
            is_working = false;
        });
    }

    function animate_prev(){
        is_working = true;
        $this.animate({'left': 0}, options.speed, function(){
            $this.css({'left':'-' + $parent_width + 'px'}).children(':last').insertBefore($this.children(':first'));
            is_working = false;
        });
    }

    function fade(direction){
        if(direction == 'next'){
            var last_before_switch = child_count - 1;
            var start_over = 0;
            var incr = k + 1;
        }else if(direction == 'prev'){
            var last_before_switch = 0;
            var start_over = child_count -1;
            var incr = k - 1;
        }

        is_working = true;
        if(k == last_before_switch){
            $this.children().eq(k).fadeTo(options.speed, 0);
            $this.children().eq(start_over).fadeTo(options.speed, 1, function(){
                is_working = false;
                k = start_over;
            });

        }else{
            $this.children().eq(k).fadeTo(options.speed, 0);
            $this.children().eq(incr).fadeTo(options.speed, 1, function(){
                is_working = false;
                k = incr;
            });
        }
    }

    function add_controls(){
        /////////////////////////////////////////////////////////////////////////////////////////////////////////////
        // Check if user selected images to use for next / prev
        /////////////////////////////////////////////////////////////////////////////////////////////////////////////

        if(options.prev_img != '' || options.next_img != ''){
            $this.parent().append('<a class="slider_prev" href=""><img src="' + options.prev_img + '" alt=""/></a><a class="slider_next" href=""><img src="' + options.next_img + '" alt="" /></a>');
        }else{
            $this.parent().append('<a class="slider_prev" href="">' + options.prev_text + '</a><a class="slider_next" href="">' + options.next_text + '</a>');
        }

        $this.parent().find('.slider_prev').css({'float':'left', 'outline':'0', 'color':'yellow'});
        $this.parent().find('.slider_next').css({'float':'right', 'outline':'0', 'color':'yellow'});


        /////////////////////////////////////////////////////////////////////////////////////////////////////////////
        // Accomodate padding-top for controls when elements are absolutely positioned (only in fade mode)
        /////////////////////////////////////////////////////////////////////////////////////////////////////////////

        if(options.mode == 'fade'){
           $this.parent().find('.slider_prev').css({'paddingTop' : $this.children().height()})
           $this.parent().find('.slider_next').css({'paddingTop' : $this.children().height()})
        }

        /////////////////////////////////////////////////////////////////////////////////////////////////////////////
        // Actions when user clicks next / prev buttons
        /////////////////////////////////////////////////////////////////////////////////////////////////////////////

        $this.parent().find('.slider_next').click(function(){
            if(!is_working){
                if(options.mode == 'slide'){
                    animate_next();
                    if(options.auto){
                        clearInterval($.t);
                        $.t = setInterval(function(){animate_next();}, options.pause);
                    }
                }else if(options.mode == 'fade'){
                    fade('next');
                    if(options.auto){
                        clearInterval($.t);
                        $.t = setInterval(function(){fade('next');}, options.pause);
                    }
                }
            }
            return false;
        });

        $this.parent().find('.slider_prev').click(function(){
            if(!is_working){
                if(options.mode == 'slide'){
                    animate_prev();
                    if(options.auto){
                        clearInterval($.t);
                        $.t = setInterval(function(){animate_prev();}, options.pause);
                    }
                }else if(options.mode == 'fade'){
                    fade('prev');
                    if(options.auto){
                        clearInterval($.t);
                        $.t = setInterval(function(){fade('prev');}, options.pause);
                    }
                }
            }
            return false;
        });
    }


    function ticker() {
        if(options.ticker_direction == 'left'){
            $this.animate({'left':'-' + $parent_width * 2 + 'px'}, options.speed, 'linear', function(){
                $this.css({'left':'-' + $parent_width + 'px'}).children(':first').appendTo($this);
                ticker();
            });
        }else if(options.ticker_direction == 'right'){
            $this.animate({'left': 0}, options.speed, 'linear', function(){
                $this.css({'left':'-' + $parent_width + 'px'}).children(':last').insertBefore($this.children(':first'));
                ticker();
            });
        }
    }


    /////////////////////////////////////////////////////////////////////////////////////////////////////////////
    // Create content wrapper and set CSS
    /////////////////////////////////////////////////////////////////////////////////////////////////////////////

    $this.wrap('<div class="' + options.wrapper_class + '"></div>');
    //console.log($this.parent().css('paddingTop'));
    if(options.mode == 'slide' || options.mode == 'ticker'){
        $this.parent().css({
            'overflow' : 'hidden',
            'position' : 'relative',
            'margin' : '0 auto',
            'width' : options.width + 'px'
        });

        $this.css({
            'width' : '999999px',
            'position' : 'relative',
            'left' : '-' + $parent_width + 'px'
        });

        $this.children().css({
            'float' : 'left',
            'width' : $parent_width
        });

        $this.children(':last').insertBefore($this.children(':first'));
    }else if(options.mode == 'fade'){
     $this.parent().css({
         'overflow' : 'hidden',
         'position' : 'relative',
         'width' : options.width + 'px'
         //'height' : $this.children().height()
     });

     if(!options.controls){
         $this.parent().css({'height' : $this.children().height()});
     }

     $this.children().css({
         'position' : 'absolute',
         'width' : $parent_width,
         'listStyle' : 'none',
         'opacity' : 0
     });

     $this.children(':first').css({
         'opacity' : 1
     });
    }

    /////////////////////////////////////////////////////////////////////////////////////////////////////////////
    // Check if user selected "auto"
    /////////////////////////////////////////////////////////////////////////////////////////////////////////////

    if(!options.auto){
        add_controls();
    }else{
        if(options.mode == 'ticker'){
            ticker();
        }else{
            /////////////////////////////////////////////////////////////////////////////////////////////////////////////
            // Set a timed interval
            /////////////////////////////////////////////////////////////////////////////////////////////////////////////
            if(options.mode == 'slide'){
                if(options.auto_direction == 'left'){
                    $.t = setInterval(function(){animate_next();}, options.pause);
                }else if(options.auto_direction == 'right'){
                    $.t = setInterval(function(){animate_prev();}, options.pause);
                }
            }else if(options.mode == 'fade'){
                if(options.auto_direction == 'left'){
                    $.t = setInterval(function(){fade('next');}, options.pause);
                }else if(options.auto_direction == 'right'){
                    $.t = setInterval(function(){fade('prev');}, options.pause);
                }
            }
            if(options.controls){
                add_controls();
            }
        }
    }
}

我正在寻找有人能提供完整的工作解决方案,而不仅仅是参考样例和示例。 - Dasa
6
Dasa,我认为这里社区的理念更多地是你来学习,而一个很好的方式就是通过样例和范例。你不能只靠赏金点数支付别人来替你完成工作 :) - Joshua Cody
你部分正确,学习的想法是对的,但积分制的目的是什么? - Dasa
谢谢您没有太过在意。当然,得到答案是很重要的,但我认为更重要的是激励他人帮助您学习,尤其是当您的问题被忽视时。话虽如此,我希望您能在解决问题的同时也能学到东西。 - Joshua Cody
如果没有访问您的服务器、所有代码和确切需求说明,很难给出可以直接“插入并运行”的确切答案。如果这就是您想要的,我相信有一些自由职业者愿意为之效劳 ;) - hookedonwinter
4个回答

9

您可以使用JavaScript设置cookie

页面加载时,请检查cookie。如果cookie存在,则用户已访问过该站点。如果不存在,则表示他们尚未访问。这不是完美的(您可以轻松删除cookie),但它可以工作。

然后,更改该cookie的值或设置一个新的cookie,指示用户是否单击了x。

我不想只复制并粘贴代码,但W3C学校示例几乎就是您要找的内容。

因此,您将拥有三种状态:

  • 从未来过(没有cookie)
  • 来过但没有单击x(cookie名称=“new_user_status”,值=“new”或其他内容)
  • 单击了x(cookie名称=“new_user_status”,值=“they're good”或其他内容)

您甚至可以针对要显示的每个消息执行此操作。

  • cookie名称= [您的消息标题]
  • cookie值= show / hide

3
Cookies是一种开始,但它们很容易被清除并且可能没有启用。更强大的解决方案是使用其他形式的本地存储,并在不可用时回退到Cookies。你还有其他选择,如:
  • HTML5本地存储
  • Flash持久存储
  • IE本地存储
  • Google Gears
  • Cookies
如果没有人为您实现这个功能,那么实现起来会很麻烦。如果您认为Cookies不够用,请查看Persist-Js。对于仅检测新用户来说,这可能有点过度,但如果您对Cookies不满意,则可以提供更多选项。

2

您需要使用一种会话来存储用户已经看过该栏的值。另一种选择是使用cookie。一旦设置,您可以检查它是否设置,如果没有,则显示该栏,否则不显示。

session_start();

if (!isset($_SESSION['bar_shown']))
{
   // show your info bar

   // finally set the session
   $_SESSION['bar_shown'] = true;
}

@Dasa:你使用哪种服务器端语言?看看我的答案,我提供了 PHP 的原型。 - Sarfraz
我使用PHP,我更喜欢简单的JS解决方案,但请发一个链接给我,我会去查看它。 - Dasa
@Dasa:我自己还没有做过这样的东西。你只需要用显示信息栏的代码替换我说“// show your info bar”的地方即可。 - Sarfraz
它很好,但我希望它继续显示,直到他们点击X。 - Dasa
@Dasa:是的,这将在页面加载时自动发生,与会话相关。 - Sarfraz

1

所以我认为在这里使用cookie比会话更好。从你的措辞中略有歧义,但我认为你只想在网站的第一次访问时显示此栏。

你正在使用jQuery,所以我建议使用jQuery cookie插件来实际读取和写入cookie。在http://plugins.jquery.com/project/cookie获取它。

一旦用户单击栏上的x,调用关闭通知函数与之前相同,但添加了一个cookie设置:

function closeNotice() {
    $("#message").fadeOut("slow");
    var date = new Date();
    //Here we set the expire time to 999 days worth of milliseconds
    date.setTime(date.getTime() + (999 * 24 * 60 * 60 * 1000));
    $.cookie("NO_BAR", 1, { path: '/', expires: date });
}

那么你的文档准备函数就变成了

$(document).ready(function() {
   if (!$.cookie("NO_BAR")) {    
     $("#message").fadeIn("slow");
         $('#example1').bxSlider({
            mode: 'slide',
            speed: 250,
            wrapper_CLASS: 'example1_container'
         });
   }

});

如果我误解了你的问题,实际上你想要在每次访问时都显示该栏,则需要使用会话cookie。为此,只需完全删除到期日期,如下所示:
$.cookie("NO_BAR", 1, { path: '/'});

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接