slideDown/slideUp in IE8 with hidden elements in child containers - javascript

So I've got a side menu with various levels of drop down. Each level's container is set to display:none; and javascript then slides these containers up or down when clicking the parent box.
When I'm opening each block, it does not expand the parent div, and the menu slides down over the footer. Now I know what you're thinking, but I have tried the fix of expanding the parent element by the same height, which i have successfully used in other areas of my site.
The problem is, when I'm calculating the height of the parent div, it is coming back with the height of every single div inside added together even though they are display:none; meaning when I expand a section in the side menu, the footer drops to over 10,000px! (using parent height = parent height + expanded section height)
I've tried getting the offset.top of the footer menu and this still comes back with over 10,000px. Alerting in other browsers just returns what I would expect it to be, and I'm not massively clever with javascript to know exactly why this is happening. Any thoughts?
Example Code -
<div class="content">
<div class="level1">
<div class="level2">
<div class="level3">
<div class="level4">
SOME PRODUCTS....
</div>
</div>
<div class="level3">
SOME PRODUCTS....
</div>
</div>
<div class="level2">
<div class="level3">
SOME PRODUCTS....
</div>
<div class="level3">
SOME PRODUCTS....
</div>
</div>
</div>
</div>
There are about 850 products in the real list however. Clicking each div expands it's contents, all the way down to the product level. Some are 3 deep, while some are 5 or 6 deep. All divs are set to display:none; originally, unless a product is currently being viewed, in which case the parent divs are automatically open. It seems that IE8 reads the height of each div even though they are set to display:none;?

Related

Scroll jumps to the bottom of the page after resizing text

I have an Angular 8 project, which receives list of products from the server. Since the number of products per user might be very large, I'm making request and displaying to user only first 20 items, but when he reaches the bottom of the container, I'm uploading 20 more items. For scroll detection I'm using infinite-scroll library. Everything worked fine until I've added another library, that autoresizes product title to fit container width. After adding it, scroll started automatically jump to the end of the container (to the latest uploaded item) and because of that it triggers uploading of another bunch of additional items. Before adding autoresize, users were staying on the same place (at the end of the first 20 items).
I have already tried next steps:
Removed infinite-scroll and wrote my own method to detect when user
reaches end of container to upload new items. Result: same behavior
with scroll drop.
Removed fittext library and wrote my own directive to resize text
label. Result: same behavior with scroll jump.
Tried to switch overflow on container to hidden to prevent scroll,
tried to change scrollTop value.
Nothing helps. Scroll is still jumping to the end each time new items are loaded. But when I'm removing autoresize feature - everything works fine, except I don't have autoresize..
Maybe someone had similar issue or have any ideas about how to prevent that scroll jump?
Thanks!
This is my html:
<div class="prizes__wrapper" *ngIf="viewModel.prizes.items.length > 0" infinite-scroll [scrollWindow]="false"
(scrolled)="scrollDown(this.viewModel.prizes, 0)">
<div class="content-wrapper">
<div class="outer__wrapper" *ngFor="let prize of viewModel.prizes.items; let i=index; first as isFirst">
<div class="inner__wrapper">
<div class="prize">
<div class="image-wrapper">
<div class="prize__date">
{{'claim_page_won_title' | translate:(prize.created | date:'mediumDate')}}
</div>
<div class="prize__image" [ngStyle]="{ 'background-image': 'url(' + prize.machineImage + ')' }">
</div>
</div>
<div class="prize-controls">
<div class="title-container">
<p class="title" appTextFit>{{prize.prizeShortName}}</p>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
Styles for container with overflow:
.prizes__wrapper
height: 100%
overflow-y: scroll
scrollbar-width: none
-ms-overflow-style: none
Adding trackBy on ngFor element helped to fix that issue.
<div class="machine" *ngFor="let machine of viewModel.machines; let i = index; trackBy: trackByFn">

Hiding an element doesn't redraw page correctly in IE8 if the parent elements have a specific combination of display types

I have a problem when hiding/showing certain elements in IE8. If an element with display:inline-block has any child (including nested children) with display:block, then any child of that element has problems when hiding/showing. The page does not redraw correctly, and other elements position do not change to reflect the newly hidden/shown elements.
The minimal markup that shows the problem is below. In the example, when you click 'Clickable element', then the three divs directly below are hidden. However, the Footer Div does not change position - a large gap is left. If you do something to force a page redraw, such as selecting all text on the page, then the footer jumps to the correct position.
Something similar happens when showing the elements. Instead of the footer div being pushed to the bottom, it is overlapped by the newly shown elements.
<div style="display:inline-block">
<div>
<!-- Any number of other HTML elements -->
<div style="display:block">
<div class = "clickable" >Clickable element.</div>
<div class = "toggleable">Hideable element 1.</div>
<div class = "toggleable">Hideable element 2.</div>
<div class = "toggleable">Hideable element 3.</div>
</div>
</div>
</div>
<div>Footer Div</div>
<script type="text/javascript">
$('.clickable').click(function(){
$('.toggleable').toggle();
});
</script>
I've been trying to break this down for a fair while now, and I'm almost certain that I've got the minimal problem down (inline-block element followed by block element, and perform a show/hide on a child element). Has anybody encountered this before - or any suggestions on how to work around this?
This should do the trick. As the answer below states, inline-block isn't supported in older browsers and shows some quirky behaviour in certain versions of IE8. I've remembered this fix from something I did a while back, but I'm sorry, I can't give you a full explanation as to why this is happening. Anyhow, add a float to your main div, and clear your footer and, fingers crossed, it should work.
<div style="display:inline-block;float:left">
<div>
<!-- Any number of other HTML elements -->
<div class="div-2" style="display:block">
<div class = "clickable" >Clickable element.</div>
<div class = "toggleable">Hideable element 1.</div>
<div class = "toggleable">Hideable element 2.</div>
<div class = "toggleable">Hideable element 3.</div>
</div>
</div>
</div>
<div style="clear:left">Footer Div</div>
Seems to be working fine in here... But note that IE8 have some problems rendering jquery, and the css property 'inline-block' is not really supported by old browser versions (ie7, doesn't work, ie8, i'm not sure). Try adding the "zoom:1;" fix to the css of your tags that have the inline-block going on. Hope that helps somehow.

Position elements in a top->down left->right manner

I have a main container <div> which holds 4 or 5 other sub <div>s. The container has a fixed height and a fixed width. What is the best way to position the sub divs so that they are arranged in a top->down then left->right manner?
I've tried floating the sub divs but that just gives me a left->right then top->down order.
Basically I want this
[ sub div 1][sub div 3][sub div 4]
[ sub div 2][ ][sub div 5]
When I mark up the code like this:
<div id="container">
<div class="subdiv">sub div 1...</div>
<div class="subdiv">sub div 2...</div>
<div class="subdiv">sub div 3...</div>
<div class="subdiv">sub div 4...</div>
<div class="subdiv">sub div 5...</div>
</div>
Notice that the sub divs can have variable heights but fixed widths.
Thank you,
To my knowledge, there's no way to do it.
There is some CSS3 that works only on some browsers to support multi-column layout (-moz-column-width, etc...) but I don't know whether it would work with DIVs in the content. And I'm fairly certain it it's not supported in IE7
The way I'd do it would be to break up the content into 3 columns containers
<div id="container">
<div class='column'>
<div class="subdiv">sub div 1...</div>
<div class="subdiv">sub div 2...</div>
</div>
<div class='column'>
<div class="subdiv">sub div 3...</div>
<div class="subdiv">sub div 4...</div>
</div>
<div class='column'>
<div class="subdiv">sub div 5...</div>
</div>
</div>
Use this CSS on the DIVs:
display: inline-block
The only way to do this natively is to use CSS3 columns (as Damp mentioned) but there are some articles on how to achieve a similar effect with JavaScript as seen in this question. That case is actually more complicated than yours.
I'm thinking the best way to do it with JS would be to first split it evenly into column containers as Damp suggested with a best guess. This should help for those with JS disabled. Then us JS to measure heights of the subdivs and move them if the initial guess was off. Assuming you're using a server side language to generate the page, you should be able to split the columns evenly. You can probably even make a good estimation on the split by checking the length of content (assuming its text) as a heuristic for the likely height of the subdiv.

How to prevent Jqtouch autoscrolling to div with current class?

I'm using Jqtouch to design a iphone app.
As I'm using a standard header/toolbar at the top, I want to simply have it fixed there without moving. I found out how to do this by creating a div with class toolbar and setting CSS display to block and min-height to 0px with important.
However, when it starts up and every time I change pages (technically, it's making different divs display and not display(?)), it autoscrolls to the top of the div that it just changed to, and I need to scroll up to see the toolbar (the toolbar is at the very top, above the div).
How do I make it actually scroll up to the toolbar or top of the page?
Here's a simplified layout of my current code: (For body section)
<body>
<div id="toolbar" class="toolbar" style="display: block; min-height: 0px !important;">
<h1>Header</h1>
<a class="button" href="#">Button</a>
</div>
<div id="home" class="current">
<!--Content in here-->
Link to next page
</div>
<div id="next">
<!--Content in here-->
</div>
</body>
I am not entirely sure I got your question, but It sounds like you want to have an element with "fixed" position. If that's the case, you may want to try the solution I posted for this question.

How a Javascript Accordion Works?

I would like to create my own accordion component without using any AJAX toolkits, mostly for learning purposes. I am not sure quite where to start with this one. I'm assuming I would begin by creating div's for each section in the accordion. Perhaps each div would contain a header, which would be the actual button selected to move the accordion to that section. I am not sure the correct approach to take once an accordion's section button is selected though. Would I use the z-order, so that each section is of a higher z-order? Any help is appreciated.
Thanks
I would highly recommend picking up a book such as John Resig's Pro JavaScript techniques that will give you some ideas and initial thoughts about how to approach bulding your own client-side solutions.
Essentially, you would have an element to act as a header, for example <h1> or <div> under which you would have a <div> with an initial style of display: none;. Set up an event handler on the click event of the header to change the style of the div below to display: block and ensuring that any other content <div>s are hidden (do this by using a CSS class on each content <div> for example).
I'll leave the smooth animation to you as an exercise for how it might be accomplished. As a hint, I would recommend looking at how a JavaScript library like jQuery handles animation, by checking out the source.
The best way to order it would be like this
<div id="accordion">
<h3 class="accordion title">Title</h3>
<div class="accordion section">
Section Content
</div>
<h3 class="accordion title">Title 2</h3>
<div class="accordion section">
Section Content
</div>
<h3 class="accordion title">Title 3</h3>
<div class="accordion section">
Section Content
</div>
<h3 class="accordion title">Title 4</h3>
<div class="accordion section">
Section Content
</div>
</div>
You would want to avoid z-order entirely because it is a compatibility mess. Instead you would have the accordion titles be what you would click to open the accordion. You would want to set all of the accordion section <div>'s to visibility:hidden; by default, and then, when one of them is clicked, change it's visibility, and hide all the others. If you want it to work with any amount of accordion sections, you would have it count each <h3 class="accordion title"> and each <div class="accordion section">, and pair those up into an array. When a title is clicked, show it's corresponding div. Alternatively you could give each one a separate ID, but the first way would be much more useful.
Actually, it might be display:none; instead of visibility:hidden;, I would try both.
In addition it's worth mentioning that the animation is usually handled by changing things like the size of the div, so if you were hiding a section, you would make the height smaller and smaller until it reaches 0 and is hidden.
See this question, you will notice my answer contains a demo with the basic workings that should get you started. It was only asked a few minutes ago!
It uses jQuery.

Categories