代码之家  ›  专栏  ›  技术社区  ›  Complainingest

jQuery toggle with cookies:如何在默认情况下获取折叠状态并保持可访问性?

  •  0
  • Complainingest  · 技术社区  · 15 年前

    我完全是个初学者,所以请原谅我看不到一个明显的解决方案(如果有的话)。也就是说,我在互联网上搜索了这个问题的答案,只遇到了同样的问题。我目前的工作是:利用我在 http://www.tobypitman.com/multiple-collapsable-panels-with-cookies/ ,我设法让多个容器在 display:block 和 display:none ,我正在用Klaus Hartl的cookie.js设置cookie。

    一切都很好!但我希望切换容器的初始状态是关闭的。我真的很想做到这一点 显示:无 直接在CSS中,因此在关闭JS的情况下内容仍然可以访问。我不是一个程序员,我用暴力的方法来改变事情的来龙去脉,直到事情发生,但这并不能完全改变它。我已经包含了下面所有的HTML、CSS和jQuery——我的示例中唯一缺少的是 <h6> 那就是触发点。

    
    
    
        
        Toggle with cookie

    <style>
        .toggle-wrapper {
            overflow:hidden;
            display:block;
        }
    
        .toggle-wrapper .toggle-container {
            position:relative;
            overflow: hidden;
        }
    
        .toggle-wrapper h6.trigger {
            background: transparent url(images/trigger-sprite.png) no-repeat left top;/*sprite is 15x30px - plus sign on top, minus on bottom*/
            height: 15px;/*half of sprite's height*/
            cursor:pointer;
            padding:0 0 0 16px;
            margin:0;
        }
    
        .toggle-wrapper h6.active {
            background-position: left bottom;/*this is the open state, showing the minus sign part of sprite*/
            padding:0 0 0 16px;
        }
    </style>
    
    <script src="http://ajax.googleapis.com/ajax/libs/jquery/1.4.2/jquery.min.js"></script>
    <script>
        /**
         * Get the value of a cookie with the given key.
         *
         * @example $.cookie('the_cookie');
         * @desc Get the value of a cookie.
         *
         * @param String key The key of the cookie.
         * @return The value of the cookie.
         * @type String
         *
         * @name $.cookie
         * @cat Plugins/Cookie
         * @author Klaus Hartl/klaus.hartl@stilbuero.de
         */
        jQuery.cookie = function (key, value, options) {
    
            // key and value given, set cookie...
            if (arguments.length > 1 && (value === null || typeof value !== "object")) {
                options = jQuery.extend({}, options);
    
                if (value === null) {
                    options.expires = -1;
                }
    
                if (typeof options.expires === 'number') {
                    var days = options.expires, t = options.expires = new Date();
                    t.setDate(t.getDate() + days);
                }
    
                return (document.cookie = [
                    encodeURIComponent(key), '=',
                    options.raw ? String(value) : encodeURIComponent(String(value)),
                    options.expires ? '; expires=' + options.expires.toUTCString() : '', // use expires attribute, max-age is not supported by IE
                    options.path ? '; path=' + options.path : '',
                    options.domain ? '; domain=' + options.domain : '',
                    options.secure ? '; secure' : ''
                ].join(''));
            }
    
            // key and possibly options given, get cookie...
            options = value || {};
            var result, decode = options.raw ? function (s) { return s; } : decodeURIComponent;
            return (result = new RegExp('(?:^|; )' + encodeURIComponent(key) + '=([^;]*)').exec(document.cookie)) ? decode(result[1]) : null;
        };
    
        // http://www.tobypitman.com/multiple-collapsable-panels-with-cookies/
    
        $(document).ready(function(){
    
            $("div.toggle-wrapper h6").addClass("active");
    
            var l = $('div.toggle-wrapper h6').length;
            var panel = $("div.toggle-wrapper div.toggle-container");
    
            for (c=0;c<=l;c++){
                var cvalue = $.cookie('panel' + c);
                if ( cvalue == 'closed' + c ) {
                    $(panel).eq(c).css({display:"none"});
                    $(panel).eq(c).prev().removeClass('active').addClass('inactive');
                };
            };
    
            $("div.toggle-wrapper h6.active").toggle(
                function () {
                    var num = $("div.toggle-wrapper h6").index(this);
                    var cookieName = 'panel' + num;
                    var cookieValue = 'closed' + num;
                    $(this).next("div.toggle-container").slideUp(500);
                    $(this).removeClass('active');
                    $.cookie(cookieName, cookieValue, { path: '/', expires: 10 }); 
                },
                function () {
                    var num = $("div.toggle-wrapper h6").index(this);
                    var cookieName = 'panel' + num;
                    $(this).next("div.toggle-container").slideDown(500);
                    $(this).addClass("active");        
                    $.cookie(cookieName, null, { path: '/', expires: 10 });
                }
            );
    
            $("div.toggle-wrapper h6.inactive").toggle(
                function () {
                    var num = $("div.toggle-wrapper h6").index(this);
                    var cookieName = 'panel' + num;
                    $(this).next("div.toggle-container").slideDown(500);
                    $(this).addClass("active");
                    $(this).removeClass('inactive');       
                    $.cookie(cookieName, null, { path: '/', expires: 10 });
                },
                function () {
                    var num = $("div.toggle-wrapper h6").index(this);
                    var cookieName = 'panel' + num;
                    var cookieValue = 'closed' + num;
                    $(this).next("div.toggle-container").slideUp(500);
                    $(this).removeClass('active');
                    $.cookie(cookieName, cookieValue, { path: '/', expires: 10 }); 
                }
            );
    
        });
    </script>
    

    <div class=“toggle wrapper”> <h6 class=“trigger”>触发器1<h6> <div class=“toggle container”> <p>东西在里面<p> <p>更多内容<p> <p>更均匀<p> </分区> </分区> <div class=“toggle wrapper”> <h6 class=“trigger”>触发器2<h6> <div class=“toggle container”> <p>东西在里面<p> <p>更多内容<p> <p>更均匀<p> </分区> </分区> <div class=“toggle wrapper”> <h6 class=“trigger”>触发器3<h6> <div class=“toggle container”> <p>东西进入这里<p> <p>更多内容<p> <p>更均匀<p> </分区> </分区>

    2 回复  |  直到 15 年前
        1
  •  2
  •   Brenno Visser    14 年前

    要创建一个关闭的默认状态,只需使toggle容器依赖于另一个名为“open”的cookie。如果没有cookie'open+c',容器也会被隐藏。

    if ( cvalue == 'closed' + c || cvalue != 'open' + c ){
      //hide()etc...
    }
    

    现在不要让toggle函数在slideDown上删除panel cookie,而是将panel cookie的值设置为'open+num'。

    var cookieValue = 'open' + num; 
    
    $.cookie(cookieName, cookieValue, { path: '/', expires: 10 });
    

    在设置了open cookie之后,脚本的工作方式与以前一样。下面是不同类名的全部内容,但这不应该是一个问题。

    $(document).ready(function(){
    
    // Toggle sliding containers with cookies
    $("div.toggle_widget h2.toggle_trigger").addClass("active");
    
    var l = $('div.toggle_widget h2.toggle_trigger').length;
    
    var panel = $("div.toggle_widget div.toggle_container");
    
    for (c=0;c<=l;c++){
    
       var cvalue = $.cookie('panel' + c);
    
       if ( cvalue == 'closed' + c || cvalue != 'open' + c ) {
    
            $(panel).eq(c).css({display:"none"});
            $(panel).eq(c).prev().removeClass('active').addClass('inactive');
       };
    };
    
    
    $("div.toggle_widget h2.toggle_trigger.active").toggle(
          function () {
                var num = $("div.toggle_widget h2.toggle_trigger").index(this);
                var cookieName = 'panel' + num;
                var cookieValue = 'closed' + num;
            $(this).next("div.toggle_container").slideUp(250);
            $(this).removeClass('active');
                $.cookie(cookieName, cookieValue, { path: '/', expires: 10 });  
    
          },
          function () {
                var num = $("div.toggle_widget h2.toggle_trigger").index(this);
                var cookieName = 'panel' + num;
                var cookieValue = 'open' + num;
                $(this).next("div.toggle_container").slideDown(250);
                $(this).addClass("active");         
            $.cookie(cookieName, cookieValue, { path: '/', expires: 10 });
          }
        );
    
    
    $("div.toggle_widget h2.toggle_trigger.inactive").toggle(
          function () {
                var num = $("div.toggle_widget h2.toggle_trigger").index(this);
                var cookieName = 'panel' + num;
                var cookieValue = 'open' + num;
                $(this).next("div.toggle_container").slideDown(250);
                $(this).addClass("active"); 
                $(this).removeClass('inactive');        
            $.cookie(cookieName, cookieValue, { path: '/', expires: 10 });
    
          },
          function () {
                var num = $("div.toggle_widget h2.toggle_trigger").index(this);
                var cookieName = 'panel' + num;
                var cookieValue = 'closed' + num;
            $(this).next("div.toggle_container").slideUp(250);
            $(this).removeClass('active');
                $.cookie(cookieName, cookieValue, { path: '/', expires: 10 });  
          }
        );
    });
    
        2
  •  0
  •   Will Martin    15 年前

    你试图解决的问题是如何在视觉上隐藏内容,而不让屏幕阅读器无法访问。有很多方法可以做到这一点;最新的(截至2011年7月)是clip方法。在这里:

    .hidden {
        position: absolute !important;
        clip: rect(1px 1px 1px 1px); /* IE6, IE7 */
        clip: rect(1px, 1px, 1px, 1px);
        padding: 0 !important;
        border: 0 !important;
        height: 1px !important;
        width: 1px !important;
        overflow: hidden;
    }
    

    如果你喜欢的话,你可以在文章中读到更多 When and How to Visually Hide Content 在设计节上,也讨论了一些旧的方法。

    另外,请注意slideUp jQuery方法指定 display: none 它的目标完成后,这将使它不可用的屏幕阅读器,直到面板再次显示。在你的具体案例中,这可能不是问题。但是,如果它困扰您,您可以向slideUp添加一个回调函数,该函数将display重置为block并添加隐藏类,以便在面板离开屏幕后,屏幕阅读器可以再次使用它。