1

I'm have a bunch of accordions on a site built with Bootstrap. I'm trying to add a behavior where the page will scroll to the open panel once the accordion is done collapsing. It works in all browsers except IE (of course!). Here's the function I've written:

$('.accordion').on('hidden', function() {
    $('.accordion .current').removeClass('current');
    $(this).find('.in').prev().find('a').addClass('current');
    $('html,body').animate({'scrollTop':$('.accordion-toggle.current').position().top},500);
})

IE says the position() property of the newly made "current" item is undefined. I know the object is there because I ran an alert on $('.current'), and it reported [object Object], but it seems to be unable to find the position of it. Does it have something to do with the execution queue of this function? Is it looking for the position of an object that doesn't exist yet? I'm tearing my hair out here!

HTML:

<div id="accordion" class="accordion"> 
    <div class="accordion-group"> 
        <div class="accordion-heading"> 
            <a class="accordion-toggle" href="#collapseOne" data-parent="#accordion" data-toggle="collapse">Panel 1</a>
        </div> 
        <div id="collapseOne" class="accordion-body collapse"> 
            <div class="accordion-inner"> 
            <!-- Content goes here --> 
            </div> 
        </div> 
   </div> 
</div>

@Kris Hollebeck...

I want it to scroll to the currently open pane. There is no automatic provision for that in Bootstrap. It does not add a class to the heading, but to the pane below it. I want the heading to be visible in the window, too. I may be going about it wrong, but that's what I'm trying to do and, at the risk of repeating myself, it works in every other browser except IE.

Here is a fiddle that shows what I am trying to do. Run it in IE and you will see that it does not work.

madth3
  • 7,275
  • 12
  • 50
  • 74
  • what do you get when you do `console.log( $('.accordion-toggle.current').position().top );` or in your case `alert( $('.accordion-toggle.current').position().top);` – khollenbeck Feb 28 '13 at 18:29
  • SCRIPT5007: Unable to get value of the property 'top': object is null or undefined functions.js, line 20 character 3 – Joshua Brown Feb 28 '13 at 19:21
  • Okay, So my guess is either the object it is looking for is not in the DOM. Or the syntax for the selector is wrong. Could you provide the HTML for the container you are trying to scroll to? – khollenbeck Feb 28 '13 at 19:36
  • I don't think that's the problem, since it works in all other major browsers, but I will post my code. – Joshua Brown Feb 28 '13 at 19:46
  • Is the object hidden? – khollenbeck Feb 28 '13 at 19:48
  • `` Forgive me, I'm new to posting here, so I'm not really sure how to post long blocks of code. That is a shortened version of what my accordion looks like. It's a basic Bootstrap implementation. – Joshua Brown Feb 28 '13 at 19:51
  • When I'm done with the task I'm currently working on, I will try to put this up in jsfiddle and post the link. – Joshua Brown Feb 28 '13 at 19:51
  • Any reason as to why you are adding the class current to the toggle link? I am assuming current is the area you want to scroll to, correct? I would add it to `accordion-heading` and scroll to there. (not really relevant though I guess) – khollenbeck Feb 28 '13 at 19:58
  • Your bootstrap resources in your fiddle fail to load for me. – khollenbeck Feb 28 '13 at 20:08
  • Shoot, needed external links. Please try again. http://jsfiddle.net/9R97A/1/ – Joshua Brown Feb 28 '13 at 20:10

1 Answers1

0

The problem is this part here.

$(this).find('.in').prev().find('a').addClass('current');

The reason why it isn't working is because .prev() doesn't work in IE. So because of this it isn't recognizing the selector you are using with scrollTop:

Which is why you are getting this error.

SCRIPT5007: Unable to get value of the property 'top': object is null or undefined 

http://bugs.jquery.com/ticket/2590

This bug is pretty old, but it is set to won't fix, so I am assuming they have never fixed it.

My suggestion would be to find a different way to get to that selector. I personally would set a class to the parent container accordion-heading.

Something like:

$('.accordion-toggle').click(function(){
   $(this).parent('.accordion-heading').addClass('open');
});

And then use:

 $('html,body').animate({'scrollTop':$('.accordion-heading.open').position().top},500);
khollenbeck
  • 16,028
  • 18
  • 66
  • 101
  • This doesn't work either: `$('html,body').animate({'scrollTop':$('.in').position().top},500);` It's like the "in" class that is being added by Bootstrap is getting added _after_ IE looks for the position. I can't figure it out. – Joshua Brown Feb 28 '13 at 20:26
  • Are you familiar with the Bootstrap accordion? All the functions of the accordion itself are handled by the bootstrap.js script. "hidden" is the event created by bootstrap. In my code I'm setting a listener for the "hidden" event, which is supposed to be when the collapse is all done, and then I want to scroll the page up to the top of the open pane. The "in" class is what bootstrap adds to the open pane to actually open it. I'm using the "hidden" event instead of a click event because it needs to happen after the animation is done, otherwise the position.top will be in the wrong place. – Joshua Brown Feb 28 '13 at 20:36
  • I fixed it. I removed the first two lines adding the "current" class and animated the body to the top of the "in" div, minus 40px for an offset. I think it was the prev() that was breaking things, after all. Thanks for your help. – Joshua Brown Feb 28 '13 at 20:44
  • I lied. It's still broken. Forget it, I don't know how to explain my problem here and I don't know how to solve it. – Joshua Brown Feb 28 '13 at 20:48
  • The "hidden" event does not work, but the "hide" event does. Weird. – Joshua Brown Feb 28 '13 at 20:52
  • Yeah I don't think "hidden" is a recognized event. You might be mistaking it for http://api.jquery.com/hidden-selector/ also look at http://stackoverflow.com/questions/2857900/onhide-type-event-in-jquery – khollenbeck Feb 28 '13 at 20:56
  • No, they are custom events created by Bootstrap. Forgive me, I appreciate your help, but it really seems like you are not familiar at all with the Twitter Bootstrap framework. "Hide" and "hidden" are custom events that are triggered by the bootstrap collapse plugin when the panel starts to open and when it is done opening, respectively. – Joshua Brown Feb 28 '13 at 20:58
  • Okay that makes sense. Also I am reading through the documentation and I see where you are getting the `in` class from. – khollenbeck Feb 28 '13 at 20:59
  • HMM.. I may have been wrong about `.prev()` .. I went to http://api.jquery.com/prev/ in IE and it seems to work fine. IE is defiantly not finding your object. As to why? I am not certain. Sorry I couldn't be more help. – khollenbeck Feb 28 '13 at 21:06
  • The problem exists in chrome also, when the page loads if you click the expanded item instead of the a closed tab it will throw the error. You need to add the class `current` to the expanded item's header anchor. ex http://jsfiddle.net/arunpjohny/9R97A/4/ – Arun P Johny Mar 01 '13 at 00:39