jQuery accordion: prevent pane from opening/cancel

2020-08-25 05:41发布

问题:

I've got the following markup:

<div id="accordion" class="leftaligned">
    <div>
        <h3><a href="#">Stakeholder</a></h3>
        <div>Content</div>
    </div>
    <div>
        <h3><a href="#">Relationships</a></h3>
        <div>Blah blah</div>
    </div>
    <div>
        <h3><a href="#">Address</a></h3>
        <div>Yada yada</div>
    </div>
    <div>
        <h3><a href="#">Contact Details</a></h3>
        <div>Foo bar</div>
    </div>
</div>

I create an accordion as follows:

$("#accordion").accordion({
    header: "h3",
    fillSpace: true,
    changestart: function(event, ui) {
        if (someConditionIsTrue()) {
            event.stopPropagation();
            event.preventDefault();
            return (false);
        }
    }
});

The idea is that there are some use cases which would prevent the user from changing panes, however the above cancelling of the event has no effect and the panes can still be changed.

Is there a way to prevent the changing of panes? I also tried activating the current pane programmatically in order to prevent the change, but that fires another changestart event and all hell breaks loose (the accordion actually breaks)

回答1:

$("#accordion .h3").unbind("click");

works for me.



回答2:

Before initing accordion add your custom click handler with your logic. stopImmediatePropagation will stop event before accordion handler will be called.

$('.quiz-qa h3').click(function(e) {      
  if ($(this).hasClass("deleted")) {
    e.stopImmediatePropagation();
    return false;      
   }   
});    
$('.quiz-qa').accordion();


回答3:

I filed an enhancement request for this: Ticket 6651.



回答4:

I found a workaround which works in my context - I avoid having to cancel the event altogether by simply disabling the h3 headers (after giving them an id) when necessary:

html:

<div>
    <h3 id="relationshipsHeader"><a href="#">Relationships</a></h3>
    <div>Blah blah</div>
</div>

script:

if (someConditionIsTrue()) {
    $("#relationshipsHeader").attr("disabled", "disabled");
    // and so on...
}


回答5:

It's a few years after the question was originally asked and I'm using jQuery-UI 1.11.2 so this might not have been a valid answer then.

But this is what I found to work the best:

  1. First give the header you want to disable the id disable_this, or find some other way you can select the relevant header(s).
  2. Then add this line of code

    $('h3#disable_this').addClass('ui-state-disabled');
    

Some of the methods mentioned in earlier answers (unbind("click") and e.stopImmediatePropogation()) worked for me in the limited sense that they prevented the opening of the panel when the header was clicked. But my method has 2 additional benefits:

  • Stops the header taking on a highlighted style when clicked.

  • Gives the header a disabled style.

A lot more user-friendly.



回答6:

I needed a derivation of this behavior because I was chaining draggable and accordion. I'm putting my solution here for anyone looking for the same solution.

The behavior I was trying to avoid was triggering an accordion change after dragging when the headers are the handle for both accordion and draggable. So, every time you drag, it collapses the content section currently expanded.

HTML:

var $container = ('<div id="accordion">');
var $content = ('<div>');
$content.append(
    '<h1>Header 1</h1>' +
    '<div>Content 1</div>' +
    '<h1>Header 2</div>' +
    '<div>Content 2</div>'
);

JS:

$container.append($controls)
.draggable({
    handle: ':header',
    start: function(event, ui) {
        $(event.toElement).addClass('ui-dragging');
    }

});
$container.find(':header').click(function (event) {
    var $this = $(this);
    if ($(this).hasClass('ui-dragging')) {
        event.stopImmediatePropagation();
        $this.removeClass('ui-dragging');
    }
});
$container.accordion({
    collapsible: true,
    header: ':header'
});


回答7:

I am creating the contents of accordion dynamically, so binding the event call before accordion is generated is not working for me. So I tried out binding the stopImmediatePropagation after accordion is created and that worked out for me.



回答8:

$("#accordion h3").unbind("click");

Refer jsFiddle-accordion



回答9:

Maybe it's available in older jQueryUIs but if you use jQuery-UI 1.9.2 or newer you can disable accordion collapsing in beforeActivate event;

beforeActivate: function (event, ui) {
    event.preventDefault();
}


回答10:

Although there is a similar answer by user438316, it has too much unnecessary code, return false being a jarring obvious... how about just:

$('#accordion .deleted').click(function(e) {      
    e.stopImmediatePropagation();
});    
$('#accordion').accordion();