嵌套手风琴所需的jquery_accordion.js代码

时间:2016-04-19 23:10:26

标签: javascript jquery jquery-ui-accordion

我只是希望每个人都知道我是编码的新手,特别是JS。我有能力使用HTML和CSS,除此之外我无能为力。但是,我非常擅长遵循指示。 我花了几天时间研究,但仍然无法解决我的问题...我已经读过你不能打开多个手风琴,但我已经看过它了......我只是不知道怎么做。 我正在使用jquery_accordion.js作为常见问题解答页面 这是我在faq.page.liquid模板顶部的编码。

<script type="text/javascript" src="{{ 'jquery_accordion.js' | asset_url }}"></script>

$(document).ready(function() {
$('.accordion').accordion({

cookieName: 'accordion_nav'
});
});
</script>

/**
 * Accordion, jQuery Plugin
 *
 * This plugin provides an accordion with cookie support.
 *

 * @version 1.1
 */
(function($) {
    $.fn.accordion = function(options) {

        //firewalling
        if (!this || this.length < 1) {
            return this;
        }

        initialize(this, options);

    };

    //create the initial accordion
    function initialize(obj, options) {

        //build main options before element iteration
        var opts = $.extend({}, $.fn.accordion.defaults, options);

        //store any opened default values to set cookie later
        var opened = '';

        //iterate each matched object, bind, and open/close
        obj.each(function() {
            var $this = $(this);
            saveOpts($this, opts);

            //bind it to the event
            if (opts.bind == 'mouseenter') {
                $this.bind('mouseenter', function(e) {
                    e.preventDefault();
                    toggle($this, opts);
                });
            }

            //bind it to the event
            if (opts.bind == 'mouseover') {
                $this.bind('mouseover',function(e) {
                    e.preventDefault();
                    toggle($this, opts);
                });
            }

            //bind it to the event
            if (opts.bind == 'click') {
                $this.bind('click', function(e) {
                    e.preventDefault();
                    toggle($this, opts);
                });
            }

            //bind it to the event
            if (opts.bind == 'dblclick') {
                $this.bind('dblclick', function(e) {
                    e.preventDefault();
                    toggle($this, opts);
                });
            }

            //initialize the panels
            //get the id for this element
            id = $this.attr('id');

            //if not using cookies, open defaults
            if (!useCookies(opts)) {
                //close it if not defaulted to open
                if (id != opts.defaultOpen) {
                    $this.addClass(opts.cssClose);
                    opts.loadClose($this, opts);
                } else { //its a default open, open it
                    $this.addClass(opts.cssOpen);
                    opts.loadOpen($this, opts);
                    opened = id;
                }
            } else { //can use cookies, use them now
                //has a cookie been set, this overrides default open
                if (issetCookie(opts)) {
                    if (inCookie(id, opts) === false) {
                        $this.addClass(opts.cssClose);
                        opts.loadClose($this, opts);
                    } else {
                        $this.addClass(opts.cssOpen);
                        opts.loadOpen($this, opts);
                        opened = id;
                    }
                } else { //a cookie hasn't been set open defaults
                    if (id != opts.defaultOpen) {
                        $this.addClass(opts.cssClose);
                        opts.loadClose($this, opts);
                    } else { //its a default open, open it
                        $this.addClass(opts.cssOpen);
                        opts.loadOpen($this, opts);
                        opened = id;
                    }
                }
            }
        });

        //now that the loop is done, set the cookie
        if (opened.length > 0 && useCookies(opts)) {
            setCookie(opened, opts);
        } else { //there are none open, set cookie
            setCookie('', opts);
        }

        return obj;
    };

    //load opts from object
    function loadOpts($this) {
        return $this.data('accordion-opts');
    }

    //save opts into object
    function saveOpts($this, opts) {
        return $this.data('accordion-opts', opts);
    }

    //hides a accordion panel
    function close(opts) {
        opened = $(document).find('.' + opts.cssOpen);
        $.each(opened, function() {
            //give the proper class to the linked element
            $(this).addClass(opts.cssClose).removeClass(opts.cssOpen);
            opts.animateClose($(this), opts);
        });
    }

    //opens a accordion panel
    function open($this, opts) {
        close(opts);
        //give the proper class to the linked element
        $this.removeClass(opts.cssClose).addClass(opts.cssOpen);

        //open the element
        opts.animateOpen($this, opts);

        //do cookies if plugin available
        if (useCookies(opts)) {
            // split the cookieOpen string by ","
            id = $this.attr('id');
            setCookie(id, opts);
        }
    }

    //toggle a accordion on an event
    function toggle($this, opts) {
        // close the only open item
        if ($this.hasClass(opts.cssOpen))
        {
            close(opts);
            //do cookies if plugin available
            if (useCookies(opts)) {
                // split the cookieOpen string by ","
                setCookie('', opts);
            }
            return false;
        }
        close(opts);
        //open a closed element
        open($this, opts);
        return false;
    }

    //use cookies?
    function useCookies(opts) {
        //return false if cookie plugin not present or if a cookie name is not provided
        if (!$.cookie || opts.cookieName == '') {
            return false;
        }

        //we can use cookies
        return true;
    }

    //set a cookie
    function setCookie(value, opts)
    {
        //can use the cookie plugin
        if (!useCookies(opts)) { //no, quit here
            return false;
        }

        //cookie plugin is available, lets set the cookie
        $.cookie(opts.cookieName, value, opts.cookieOptions);
    }

    //check if a accordion is in the cookie
    function inCookie(value, opts)
    {
        //can use the cookie plugin
        if (!useCookies(opts)) {
            return false;
        }

        //if its not there we don't need to remove from it
        if (!issetCookie(opts)) { //quit here, don't have a cookie
            return false;
        }

        //unescape it
        cookie = unescape($.cookie(opts.cookieName));

        //is this value in the cookie arrray
        if (cookie != value) { //no, quit here
            return false;
        }

        return true;
    }

    //check if a cookie is set
    function issetCookie(opts)
    {
        //can we use the cookie plugin
        if (!useCookies(opts)) { //no, quit here
            return false;
        }

        //is the cookie set
        if ($.cookie(opts.cookieName) == null) { //no, quit here
            return false;
        }

        return true;
    }

    // settings
    $.fn.accordion.defaults = {
        cssClose: 'accordion-close', //class you want to assign to a closed accordion header
        cssOpen: 'accordion-open', //class you want to assign an opened accordion header
        cookieName: 'accordion', //name of the cookie you want to set for this accordion
        cookieOptions: { //cookie options, see cookie plugin for details
            path: '/',
            expires: 7,
            domain: '',
            secure: ''
        },
        defaultOpen: '', //id that you want opened by default
        speed: 'slow', //speed of the slide effect
        bind: 'click', //event to bind to, supports click, dblclick, mouseover and mouseenter
        animateOpen: function (elem, opts) { //replace the standard slideDown with custom function
            elem.next().stop(true, true).slideDown(opts.speed);
        },
        animateClose: function (elem, opts) { //replace the standard slideUp with custom function
            elem.next().stop(true, true).slideUp(opts.speed);
        },
        loadOpen: function (elem, opts) { //replace the default open state with custom function
            elem.next().show();
        },
        loadClose: function (elem, opts) { //replace the default close state with custom function
            elem.next().hide();
        }
    };
})(jQuery);
.accordion {
margin: 0;
padding:10px;
border-top:#000000 2px solid;
background: #ffffff;
text-decoration:none;
color: #000000;
font-size:1em;
position:relative;
}
.accordion-open {
background:#cccccc;
color: #ffffff;
}
.accordion-open span {
display:block;
position:absolute;
right:3px;
top:25%;
padding:10px;
}
.accordion-open span {
background:url('//cdn.shopify.com/s/files/1/0276/6855/t/14/assets/minus.png?4342') center center no-repeat;
}
.accordion-close span {
display:block;
position:absolute;
right:3px;
top:25%;
background:url('//cdn.shopify.com/s/files/1/0276/6855/t/14/assets/plus.png?4342') center center no-repeat;
padding:10px;
}
.faqpage div.container {
padding:0;
margin:0;
}
.faqpage div.container {
max-width:100%;
padding:5px 0;
}
.faqpage div.content {
background:#cccccc;
margin: 0;
padding:10px;
color: #000000;
font-size:.9em;
line-height:1.5em;
}
.faqpage div.content ul {
padding:0;
margin:0;
padding:3px;
}
.faqpage div.content p {
padding:0;
margin:3px 0 10px;
padding:3px;
}
.faqpage div.content ul li {
list-style-position:inside;
line-height:25px;
}
 
</style>

<div class="accordion" id="section1">CATEGORY 1<span></span></div>
<div class="container">
<div class="content">
<div class="accordion" id="section2"><strong>Nested Question 1</strong> <span></span></div>
<div class="container">
<div class="content">
<p>Answer to question 1.</p>
</div>
</div>
<div class="accordion" id="section3">Nested Question 2<span></span></div>
<div class="container">
<div class="content">
<p>Answer to nested question 2.</p>
</div>
</div>
<div class="accordion" id="section4">Nested Question 3<span></span></div>
<div class="container">
<div class="content">
<p>Answer to nested question 3.</p>
</div>
</div>
</div>
</div>
<div class="accordion" id="section1">CATEGORY 2<span></span></div>
<div class="container">
<div class="content">
<div class="accordion" id="section2"><strong>Nested Question 1</strong> <span></span></div>
<div class="container">
<div class="content">
<p>Answer to question 1.</p>
</div>
</div>
<div class="accordion" id="section3">Nested Question 2<span></span></div>
<div class="container">
<div class="content">
<p>Answer to nested question 2.</p>
</div>
</div>
<div class="accordion" id="section4">Nested Question 3<span></span></div>
<div class="container">
<div class="content">
<p>Answer to nested question 3.</p>
</div>
</div>
</div>
</div>
<div class="accordion" id="section1">CATEGORY 3<span></span></div>
<div class="container">
<div class="content">
<div class="accordion" id="section2"><strong>Nested Question 1</strong> <span></span></div>
<div class="container">
<div class="content">
<p>Answer to question 1.</p>
</div>
</div>
<div class="accordion" id="section3">Nested Question 2<span></span></div>
<div class="container">
<div class="content">
<p>Answer to nested question 2.</p>
</div>
</div>
<div class="accordion" id="section4">Nested Question 3<span></span></div>
<div class="container">
<div class="content">
<p>Answer to nested question 3.</p>
</div>
</div>
</div>
</div>

所有东西都正确显示,但当你点击一个嵌套的手风琴时,它会瞬间启动,然后关闭主手风琴。
请记住,我对这一切都很陌生。任何帮助确切的需要删除或添加,以及在哪里将非常感谢! 谢谢!

1 个答案:

答案 0 :(得分:0)

为什么手风琴会关闭? :

//hides a accordion panel
function close(opts) {
    opened = $(document).find('.' + opts.cssOpen);
    $.each(opened, function() {
        //give the proper class to the linked element
        $(this).addClass(opts.cssClose).removeClass(opts.cssOpen);
        opts.animateClose($(this), opts);
    });
}

//opens a accordion panel
function open($this, opts) {
    close(opts, true); // Pass a variable to the close function (That variable only will be passed from here)
    // As you see the open function calls close function that 
    // close all acordions before open the selected.
    .......
}

您可以重写代码部分以满足您的需求。

修改

此外,如果您只想打开嵌套式手风琴的父手风琴,您必须知道手风琴是否在另一支手风琴中。 (您需要知道识别手风琴的id,类或其他内容 - 在您的情况下,每个手风琴都有类.accordion)。见下文:

function close(opts) {
    opened = $(document).find('.' + opts.cssOpen);
    $.each(opened, function() {
        //give the proper class to the linked element
        if(opened.find('.accordion').length == 0 && aux){
          // Now with the aux variable will only close the dialog if 
          // we click to open one. 
          // Accordion with nested found -- Don't close it
        } else {
          $(this).addClass(opts.cssClose).removeClass(opts.cssOpen);
          opts.animateClose($(this), opts);
        }
    });
}

尝试一下,如果您有错误,请告诉我! =)

编辑2

我已经复制了所有代码,现在我已经让它运行了! 基本上当你点击打开手风琴时,你将点击的手风琴的id传递给close函数。现在我们发现点击的手风琴的下一个元素是容器。如果它具有被点击的手风琴的元素,则在容器中查找。如果是什么都不做(不要关闭),否则关闭它。

function open($this, opts) {
    close(opts, $this.attr('id'));
    ...

function close(opts, id_open) {
    opened = $(document).find('.' + opts.cssOpen);
    $.each(opened, function() {
      console.log(id_open, $(this).next().find('[id="' + id_open + '"]').length);
      if($(this).next().find('[id="' + id_open + '"]').length){
        // You have clicked in a accordion, let's see if the next element --(class container)
        // has the element with id="idOfClickedAccordion" -- If it has don't close
      } else {
        $(this).addClass(opts.cssClose).removeClass(opts.cssOpen);
        opts.animateClose($(this), opts);
      }
    });
}

如果你改变每支手风琴的ID,也会很酷:

<div class="accordion" id="section1_1">CATEGORY 1<span></span></div>
<div class="container">
<div class="content">
<div class="accordion" id="section1_2"><strong>Nested Question 1</strong> <span></span></div>
<div class="container">
<div class="content">
<p>Answer to question 1.</p>
</div>
</div>
<div class="accordion" id="section1_3">Nested Question 2<span></span></div>
<div class="container">
<div class="content">
<p>Answer to nested question 2.</p>
</div>
</div>
<div class="accordion" id="section1_4">Nested Question 3<span></span></div>
<div class="container">
<div class="content">
<p>Answer to nested question 3.</p>
</div>
</div>
</div>
</div>
<div class="accordion" id="section2_1">CATEGORY 2<span></span></div>
<div class="container">
<div class="content">
<div class="accordion" id="section2_2"><strong>Nested Question 1</strong> <span></span></div>
<div class="container">
<div class="content">
<p>Answer to question 1.</p>
</div>
</div>
<div class="accordion" id="section2_3">Nested Question 2<span></span></div>
<div class="container">
<div class="content">
<p>Answer to nested question 2.</p>
</div>
</div>
<div class="accordion" id="section2_4">Nested Question 3<span></span></div>
<div class="container">
<div class="content">
<p>Answer to nested question 3.</p>
</div>
</div>
</div>
</div>