Dynamic css multi column layout - update columns / force reflow? - javascript

TLDR: Can I force a column layout refresh after dynamically updating the 'css-column' css with javascript/jquery?
I have a navigation menu that I am using css columns for (I cannot work out how to use the Magento2 menu column functionality). I cannot really change the markup much. I want to stop 'widow' titles from happening (titles at the bottom of the column, with all the content on the next column - see 3rd pink title in screenshot below). It cannot be set with css as the nav items are dynamic and will change.
(I have tried "break-after:avoid" on the parent list, but this stops the list from breaking altogether - i.e. it should be able to break anywhere in the middle of the list).
I came up with a hacky solution that almost works - with javascript I am dynamically adding "break-before: column" to any list that has a widow title. (It checks the left offset of the title, compared with the offset of the first list child. If it is different then it means the title starts on the previous column).
This (sometimes) works BUT it (sometimes) does not update the columns until you resize the screen a bit.
I have been been trying out these kinds of solutions and many of these too. However none of them seem to work, for example I have tried:
console.log(elt.offsetHeight);
console.log(elt.getBoundingClientRect());
Tried 'elt' being all sorts, the parent elements, the whole body/doc wrapper etc. I thought maybe this was because the element in question is hidden until you hover over the nav link. But I forced it to be open using chrome devtools and ran the same 'reflow triggering' javascript and it still made no difference?
Is there a (preferably nice and not forcing reflow of the whole document every pageload??) way to force a recalculation of the css columns?
OR is a better solution possible using css grid / any other way?
Thanks!
In case it is relevant to another possible solution, the markup is like this:
<ul class="level0 submenu">
<li class="navigation_item__back hidden-desktop">
Back
</li>
<li class="navigation_item__link hidden-desktop">
Title
</li>
<li class="level1 nav-3-1 category-item first parent">
<a href="">
<span>Sub Title</span>
</a>
<ul class="level1 submenu">
<li class="navigation_item__back hidden-desktop">
Back
</li>
<li class="navigation_item__link hidden-desktop">
Sub Title
</li>
<li class="level2 nav-3-1-1 category-item first">
<a href="/">
<span>Lorem 1psum</span>
</a>
</li>
<li class="level2 nav-3-1-2 category-item">
<a href="/">
<span>Lorem 2psum</span>
</a>
</li>
</ul>
</li>
...
</ul>

Related

How to scroll to a component from another component in Angular?

I've been hours, even a couple of days trying to get this done but i can't find a solution, I've tried everything but haven't found a case like mine.
I'm trying to scroll to another component in my one-page website from a navbar, which is another component. The main app component I set like this:
<body>
<app-navbar></app-navbar>
<app-page-one id="page-one"></app-page-one>
<app-page-two id="page-two"></app-page-two>
<app-page-three id="page-three"></app-page-three>
<app-footer></app-footer>
</body>
As you can see i put an id on each component so i could identify it when trying to scroll.
I want to click the Page Three button inside my navbar for it to scroll down to the page three component. My navbar component looks like this:
<body class="body">
<header class="header">
LOGO
<div class="menu-toggle">
<fa-icon [icon]="faBars" transform="grow-20"></fa-icon>
</div>
<nav class="nav">
<ul>
<li>
Page One
</li>
<li>
Page Two
</li>
<li >
Page Three
</li>
</ul>
</nav>
</header>
</body>
I've tried using Ngx Page Scroll and everything, but can't seem to make it work. I'm not sure if I need to use Input Output to make them communicate or something like that, anything will help, thanks.
you can use angular router fragment or the angular cdk for scrolling.
I find the angular router is the easiest, but I will give you the link for the angular cdk in case you don't like this way.
first thing on index.html declare a style tag - because without it smooth scrolling won't smooth scroll.
index.html
<style>
html {
scroll-behavior: smooth;
}
</style>
you can change the scroll offset as you see fit
app-router.module.ts
imports: [RouterModule.forRoot(routes, {scrollPositionRestoration: 'enabled',
anchorScrolling: 'enabled',
scrollOffset: [0, 64]})]
then your component.ts
<li>
<a routerLink="." fragment="page-one" >Page One</a>
</li>
<li>
<a routerLink="." fragment="page-two">Page Two</a>
</li>
<li >
<a routerLink="." fragment="page-three">Page Three</a>
</li>
edit your component.css
a{
cursor: pointer
}
you can also do this to scroll to fragments on other views. https://angular.io/api/router/RouterLink
you might need to add a # on each fragment which is better than id #page-two as an example. and you would change the fragment to reflect that. the cdk way is in this link https://material.angular.io/cdk/scrolling/overview
Each href needs to have a reference to what element.id you want ngx-page-scroll to move the viewport to. Therefore the body should be something like this.
<li>
Page One
</li>
<li>
Page Two
</li>
<li >
Page Three
</li>
If you refer to the npm page and look at the url, https://www.npmjs.com/package/ngx-page-scroll#usage. You can see there is both a link and an element reference(#usage) to the Usage section (id="usage") of the documentation.

how do I wrap my menu in to sub menu using jquery?

this is my site.
this is how I finally make it look like
I want to divide the the menu list items into two sub menu say menu left and right. And then wrap them in a div. This is make it easy for me to style them and this way they would stay responsive as well.
Now, I have been trying to achieve this by
jQuery( ".menu-item-580", ".menu-item-583",".menu-item-584",".menu-item-563").wrapAll("<div class='new' />").after(".menubar-brand");
I have trying this in browser console.
I also tried same above code by using appendTo() instead of after()
But, still no luck.
In your code you're basically doing this:
<ul>
<li>
<div class="new">
<li>
<li>
</div>
<li>
</ul>
which is not a valid markup.
The easiest way to goup <li>s would be to assign different additional css classes to different parts of the list:
<ul>
<li class="group1">
<li class="group1">
<li class="group2">
<li class="group2">
</ul>
Also, have a look at this: Is there a way to group `<li>` elements?

Highlighting menu section not active

I'm working on a project that requires 2 distinct menus, one on top, and one on the left of the page:
<div class="navigation">
<ul class="navigation">
<li>FILM </li>
<li>PHOTOGRAPHY </li>
<li>OTHER WORKS </li>
<li>INFO/INQUIRE </li>
</ul>
</div>
<div class="navigationLeft">
<ul class="navigationLeft">
<li><a href='../item1/index.html'><span>item 1</span></a></li>
<li><a href='../item2/index.html'><span>item 2</span></a></li>
<li><a href='../item3/index.html'><span>item 3</span></a></li>
<li><a href='../item4/index.html'><span>item 4</span></a></li>
</ul>
</div>
The left one is basically a sort of sub-menu of a section in the top menu. Originally, the project was meant to be small, so I used straight CSS to highlight selected sections using class, but the website has grown so much now that I want to use templating for future updates. That means that straight CSS is now out. I've implemented the following script in my header:
<script type="text/javascript" >
$(function() {
$(".navigationLeft a").each(function() {
if (this.href == window.location) {
$(this).css("color", "#ff9900");
};
});
});
</script>
It's working for my left menu, but obviously wouldn't work for my top menu, because technically the section that I'm in isn't the "current page". I'm looking for a way using jQuery/js to parse through the url and have the highlighting applied to any link that is once up the tree. So basically, in my top menu, any <a href> that contained for example /photography/ would also be highlighted, even though it's not technically the current page. Many thanks in advance!

How can I manipulate an element's data attributes from an external page link?

I'm looking for the absolute simplest way to pass a data attribute along to a new page (non AJAX loading).
I've been messing around with a Wordpress theme all night trying to customize the gallery category filters. I want to do as little coding as possible in making my adjustments to a pre-existing layout, but the complicating factor here is that I have a single page which already has data attributes assigned to elements that can be filtered from links on the same page and I need to be able to load the page with data attributes already set for filtering from external links.
I'll try to make a visual for the scenario that might help (or not ?):
First page is already functioning:
<!---main-gallery_page.php--->
<header class="category-filters">
<ul class="list">
<li> Category Filter 1 </li>
<li> Category Filter 2 </li>
<li> Category Filter 3 </li>
</ul>
</header>
<div class="gallery-thumbs">
<!--- thumbnails with example-id data attributes are filtered, respectively: "generic-X" --->
</div>
Second page needs to manipulate the page above after loading it ^
<!---second-example_page.php--->
<div class="alternate-category-filters">
<ul class="list">
<li> Category Filter 1 </li>
<li> Category Filter 2 </li>
<li> Category Filter 3 </li>
</ul>
</div>
Obviously the second example is not going to function because the new page doesn't receive any instructions to filter the thumbnails, so it'll just load as-is.
Just want to be able to operate the category filter on page load as specified from an external (non-ajax) page. Any ideas on a simple method? I've been trying to see what I can do with php echoes and even stuffing the info into the hyperlink href value, but I couldn't get that to work. It would be ideal if I could do something like this:
<!---second-example_page.php--->
<div class="alternate-category-filters">
<ul class="list">
<li> Category Filter 1 </li>
<li> Category Filter 2 </li>
<li> Category Filter 3 </li>
</ul>
</div>
Help would be greatly appreciated, I've exhausted myself jumping around millions of topics that always seem to just miss explaining this particular scenario's solution.
You could poll a value in localStorage. Make the main page poll localStorage.category. (Using setTimeout for example). Then, once the second page loads and changes the value, the main page could see the change and act accordingly.

jquery tabs with tab navigations

I want to make a content box with jquery tabs with a tab navigation for many tab contents, such as for more than 10 tab contents. The problem is that jquery UI does not provide built in tab navigation for large tab number and the "scrollable tabs for jquery plugin" at google code, https://code.google.com/p/jquery-ui-scrollable-tabs/, looks very slow and inefficient for large volumes about more than 50 pages. If the user tries to read the 1st and the 40th page, it will take more than 30 sec. to navigate for clicking the arrows.
So, I made a tab content box with only 5 tabs including selected shown and with a tab navigation of input text box selecting specific pages and next and previous with the first and the last page tab navigation buttons. (If you put regular jquery UI tab with more than 20-30 tabs it will mess up appearance and css.)
<div id="tabs" class="tabs-bottom">
<ul>
<li>Nunc tincidunt
</li>
<li>Proin dolor
</li>
<li>Aenean lacinia
</li>
</ul>
<ul class="TabbedPageNavi">
<li>Page
<input id="pageNumber" type="text" value="01" style="width:30px;" />
</li>
<li><a class="previous" href="#">« Prev</a>
</li>
<li><a class="nexttab" href="#">Next »</a>
</li>
<li class="copyTab">2013 ©John3825 blog</li>
</ul>
<div class="tabs-spacer"></div>
<div id="tab-contents">
<div id="tabs-1">
Sample:
http://jsfiddle.net/john3825/anh7c/embedded/result/
What is the best possible way to manage the large numbers of content tabs with navigation? Please tell me a example or correct problems.
I also want to make the tab content box fit within 350px width x 1000px height.
As far as the best possible way is concerned,there are many of them.One suggestion would be using iFrames.
The Result would be quite like this : DEMO
Or either your approach is quite scalable and is old-school which is good thing in reference of compatibility and usability. Now the other requirement goes like this. You set the width:350px; and the height:1000px for the content-tab like this.
Working Fiddle: DEMO
Code:
#tab-content{
height: 1000px !important;
width:350px;
background-color:darkgrey;
border:2px ridge black;
}

Categories

Resources