Why is the scrollHeight property of an element not updating when the display of its inner element is changed to 'none'?

For the sake of learning, I am attempting to develop a bootstrap-style navbar using angularJS 1.3.14. My approach involves creating directives for the navbar, navmenu, navMenuToggle, and navDropDown, with the navMenu serving as a container for toggle and dropdown menu elements.

<navbar>
    <div class="navbar-brand">Brand</div>
    <collapse-icon></collapse-icon>
    <nav-menu>
        <div class="nav-button" ng-click="toggle()">Toggle Button</div>
        <nav-dropdown>
            <ul>
                <li><a href="">First Link</a></li>
                <li><a href="">Second Link</a></li>
            </ul>
        </nav-dropdown>
    </nav-menu>
</navbar>

The issue arises when expanding the navbar and double-clicking the toggle button, as the navbar's height fails to adjust back upon closing the menu.

You can see the behavior in action in this JS Fiddle (resize window to less than 798px): http://jsfiddle.net/5st3h30j/3/

In the navMenu directive, the toggle() function controls the opening and closing of the dropdown by manipulating the CSS display property and then notifying the parent navbar scope via

$scope.$parent.$parent.$broadcast('dropdownClosed')
, triggering the adjustment of the height based on the new scroll height.

navDropdown Controller:

        $scope.toggle = function () {
            if ($scope.open) {
                console.log('closing dropdown');
                $scope.contract();
                $scope.open = false;
                $scope.$parent.$parent.$broadcast('dropdownClosed');
            } else {
                $scope.$parent.$parent.$broadcast('dropdownOpening');
                $scope.expand();
                $scope.open = true;
                $scope.$parent.$parent.$broadcast('dropdownOpened'); 
            }

Navbar:

Controller:

        $scope.$on('dropdownClosed', function () {
            $scope.adjustHeight(); 
        });

Link Function:

            scope.adjustHeight = function () {
                console.log('adjusting height');
                var height = element.prop('scrollHeight');
                element.css('-webkit-transition', 'height 0s');
                element.css('height', height + "px");
                navbarCtrl.expanded = true;
            }

Upon debugging, it appears that the height adjustment functions correctly during expansion but not during contraction. Any insights or alternative approaches would be greatly appreciated.

Answer №1

When trying to find the height of an element, using element.prop('scrollHeight') may not give you reliable results. This property is actually intended to provide the scroll position of an element, rather than its actual height.

For a more accurate approach, consider using element.height(), although it's recommended to avoid setting heights via Javascript altogether and explore a CSS-based solution.

The default height: auto property should typically adjust the height automatically based on content.

Instead of directly manipulating styles with JavaScript like

element.css('-webkit-transition', 'height 0s')
, consider adding a specific class to your element and defining the transition in your CSS:

.my-class {
  transition: height 200ms;
}

I've set the transition duration to 200ms in this example, as a transition of 0s would essentially be unnecessary. Hope these suggestions help resolve your issues.

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Including a hyperlink to a non-secure website from a secure relative path

Forgive me for asking what may be the silliest question ever, but I'm stumped: On my secure HTTPS page: <a href="../../../folder/index.php?openMenu=SEARCH">Advanced search</a> The link seems to work fine, but it points to an HTTP page i ...

Is it possible to utilize WebAssembly in JavaScript to access the memory of a C struct directly?

Looking at the C code snippet below, there is a struct defined as follows typedef struct { ValueType type; union { bool boolean; double number; Obj* obj; } as; } Value; The ValueType enum used in the struct is defined a ...

Is there a way to show a pre-set username value to prevent receiving an error message that says it's undefined?

My navigation bar is set up to show the following on the right side of the screen: Welcome, <%= user %> The issue is that I can only access the user data if I render it in the following way: router.get("/", function (req, res, next) { co ...

Error in finding the element with Selenium webdriver 2.0 was encountered

I can't seem to find the element with the specified class name. Here's a snippet of the HTML code: <a class="j-js-stream-options j-homenav-options jive-icon-med jive-icon-gear" title="Stream options" href="#"></a> I attempted to gen ...

How can we separate XML data retrieved from an Ajax call using jQuery?

I have a massive amount of data from an XML file that I am organizing into an unordered list. I need to split the data into multiple lists so that I can style them as columns using CSS. Is there a way to insert a </ul><ul> every 20 entries or s ...

The ongoing battle between Carousel full page image slider and multi div slider in Bootstrap 4

I need a full-page carousel image slider in one div container and a multi-div slider in another div container on my homepage. Unfortunately, due to some conflicting class names (such as carousel slide, carousel-inner, etc.), they are interfering with each ...

Space separating the text and underline

Can anyone explain why padding-bottom or margin-bottom does not seem to have any effect on the underline in the li > a:before section? I tried adding padding-bottom but it doesn't create any space. Any suggestions? ul { list-style-type: none ...

What is the best way to make a scrollable div with top and bottom padding without adding extra elements inside?

I have created a fiddle to demonstrate my question. Essentially, I am looking to create a scrollable container with padding at the top and bottom that remains visible during scrolling, ensuring there is always a consistent distance from the edge to the con ...

Ways to add a string to an array as a labeled object in javascript?

Is there a way to manipulate the array in imageCollection to achieve the format of the array in carouselPhotos as shown below? export default class HomeScreen extends Component { state = { imageCollection: [ { name: "P ...

406 Not Acceptable Error: Ajax and Rails don't mix well

I'm facing a challenge in getting this request to go through ajax without triggering a 406 error. My goal is to use ajax to add an item to a cart, which does happen successfully, and the cart gets updated after a refresh. However, all I'm getting ...

Transforming an HTML5 game into a native mobile application

I'm currently working on creating a HTML5 game. While I find HTML5 to be the most user-friendly programming language, I am facing an issue. I want my game to run as a native application on desktops (Windows, Mac, and Linux) rather than in a web browse ...

The functionality of a radio button triggering a form submission to different pages is experiencing issues with Firefox

This piece of code is designed to submit a form when a radio button is clicked, and depending on which radio button is selected, the form action should change. While this code works fine in Chrome and Opera, it doesn't seem to function properly in Fir ...

Is it possible to use header() function in a file that is being accessed through

In a specific package, there is a crucial file that verifies session data and redirects the user to the login page with an error message if no valid session exists, using header("Location:" . $var);. This particular file is included in almost all files wi ...

Sending form data field in a request using the POST method

I am faced with the task of making a POST call to a URL with parameters a="x", b="y", c="z", and d, which is a form data field for file upload. When initiating an AJAX call, the code I use is as follows: $.ajax({ contentType: false, pro ...

Stop the page from refreshing following the submission of a form in node.js (without using ajax)

Hey there, I've got a form set up to send fields as well as a file to a node.js server. The server then parses the data using Formidable. Everything is functioning correctly, but once the form is submitted, it loads a page with a response. I'm w ...

Can the design be implemented using the Bootstrap grid system?

Utilizing bootstrap 5, yet a bootstrap 4 demonstration may suffice. Clearly, I can accomplish this design without employing bootstrap, however, that is not my current objective. I am curious if there is a feature within the bootstrap framework that I may ...

Unable to identify the origin of the ng-change runtime error

I encountered a compile error at runtime when running the code below. Despite my efforts, I am unable to pinpoint the exact issue related to my usage of ng-change: <!doctype html> <html> <head> <script src="https://ajax.googleap ...

Angular 6 is throwing an error stating that the element 'app-action-button' is not recognized

I'm facing an issue while trying to incorporate a component that is shared between modules. Unfortunately, all my attempts have resulted in the same error. Despite searching for solutions in similar questions, I have been unable to resolve this error ...

Tips for presenting hierarchical information from my database in ejs

I'm currently working on a genealogy application using node js express and ejs but I'm facing an issue with displaying the database in order (starting from parent). This is the code snippet for retrieving my data and what I see when I log the ou ...

Total of values that are continuously updated

I am working on a code snippet that dynamically updates the total cost of food items and clothing items separately as the user enters the value of each item. I am looking to display the combined Total Cost (sum of clothing + food inputs) which should be up ...