jQuery 使用 cookies 切换:如何默认获得折叠状态并保持可访问?

发布于 2024-10-03 15:53:56 字数 6564 浏览 1 评论 0原文

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

一切都运转得非常好!除了我希望切换容器的初始状态关闭之外。我真的很想在 CSS 中不直接使用任何 display:none 来完成此任务,这样即使关闭 JS 也可以访问内容。我不是程序员,我用蛮力的方法到处改变事情直到事情发生,这并不能完全解决问题。我已经在下面包含了 HTML、CSS 和 jQuery - 我的示例中唯一缺少的是用作触发器的

的 CSS 图像精灵。

<代码>




    
    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/[email protected]
     */
    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">Trigger 1</h6> <div class="toggle-container"> <p>Stuff goes inside of here</p> <p>More stuff</p> <p>More even</p> </div> </div> <div class="toggle-wrapper"> <h6 class="trigger">Trigger 2</h6> <div class="toggle-container"> <p>Stuff goes inside of here</p> <p>More stuff</p> <p>More even</p> </div> </div> <div class="toggle-wrapper"> <h6 class="trigger">Trigger 3</h6> <div class="toggle-container"> <p>Stuff goes inside of here</p> <p>More stuff</p> <p>More even</p> </div> </div>

I am a total beginner, so excuse my inability to see an obvious solution (if there is one). That said, I have scoured the interweb for an answer to this and have only run into the same question. What I've got working so far: using what I found at http://www.tobypitman.com/multiple-collapsable-panels-with-cookies/, I've managed to get multiple containers to toggle between display:block and display:none, and I'm setting cookies with Klaus Hartl's cookie.js.

Everything works terrifically! Except that I want the toggle containers' initial state to be closed. I'd really like to accomplish this without having any display:none directly in the CSS, so the content remains accessible with JS off. I'm not a programmer, and my brute force method of changing things here and there until something happens is not quite cutting it. I've included the HTML, CSS and jQuery all below - the only thing that will be missing from my example is the CSS image sprite for the <h6> that serves as the trigger.




    
    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/[email protected]
     */
    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">Trigger 1</h6>
<div class="toggle-container">
<p>Stuff goes inside of here</p>
<p>More stuff</p>
<p>More even</p>
</div>
</div>

<div class="toggle-wrapper">
<h6 class="trigger">Trigger 2</h6>
<div class="toggle-container">
<p>Stuff goes inside of here</p>
<p>More stuff</p>
<p>More even</p>
</div>
</div>

<div class="toggle-wrapper">
<h6 class="trigger">Trigger 3</h6>
<div class="toggle-container">
<p>Stuff goes inside of here</p>
<p>More stuff</p>
<p>More even</p>
</div>
</div>

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

庆幸我还是我 2024-10-10 15:53:56

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

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

现在不要让切换功能删除slideDown 上的面板cookie,而是将面板cookie 设置为值“open + num”。

var cookieValue = 'open' + num; 

$.cookie(cookieName, cookieValue, { path: '/', expires: 10 });

设置打开 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 });  
      }
    );
});

To create a closed default state, just make the toggle-container depend on another cookie called let's say 'open'. If there is no cookie 'open + c' the container is hidden as well.

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

Now don't make the toggle function remove the panel cookie on slideDown, but set the panel cookie with value 'open + num'.

var cookieValue = 'open' + num; 

$.cookie(cookieName, cookieValue, { path: '/', expires: 10 });

After setting the open cookie the script works like it did before. Here is the whole thing with different class names but that should not be a problem.

$(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 });  
      }
    );
});
千柳 2024-10-10 15:53:56

您要解决的问题是如何在视觉上隐藏内容而不使其无法被屏幕阅读器访问。有多种方法可以做到这一点;最新的(截至 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以及设计节上的如何在视觉上隐藏内容,其中也讨论了一些较旧的方法。

另请注意,slideUp jQuery 方法在完成时将 display: none 分配给其目标,这将使其对屏幕阅读器不可用,直到再次显示面板。对于您的具体情况,这可能不是问题。但是,如果它困扰您,您可以向 SlideUp 添加回调函数,该函数将显示重置为阻止并添加隐藏类,以便在面板关闭屏幕后,它再次可供屏幕阅读器使用。

The problem you're trying to solve is how to hide content visually without making it inaccessible to screen readers. There are a number of ways to do this; the most up-to-date (as of July 2011) is the clip method. Here:

.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;
}

If you like, you can read more about it in the article When and How to Visually Hide Content on Design Festival, which discusses some of the older methods as well.

Also, note that the slideUp jQuery method assigns display: none to its target on completion, which will render it unavailable to screen readers until the panel is revealed again. That may not be a problem in your specific case. However, if it bothers you, you can add a callback function to slideUp which resets display to block and adds the hidden class so that AFTER the panel is off screen, it is once more made available to screen readers.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文