Remove all except some elements in jQuery - javascript

Consider the following page layout:
<div id="page-container" class="">
<div id="scroller">
<!-- This page should be removed -->
<div id="page_1" class="pagina"></div>
<!-- These pages should be kept -->
<div id="page_2" class="pagina"></div>
<div id="page_3" class="pagina"></div>
<!-- This is the current page -->
<div id="page_4" class="pagina"></div>
<!-- These pages should be kept -->
<div id="page_5" class="pagina"></div>
<div id="page_6" class="pagina"></div>
<!-- These pages AND everything that follows should be removed -->
<div id="page_7" class="pagina"></div>
<div id="page_8" class="pagina"></div>
</div>
</div>
I have a function loadPage(pageNr) which loads a specific page and scrolls it into view.
I also have a function that load's two more pages on top, or below the current page depending on the scroll direction.
What I want to achieve now, is that when my loadPage() function is called, I want to keep 2 pages below and before the current page. All other pages should be removed. This is for speed purposes as my app has 748 pages in total.
What I have tried:
//Determine which pages on top of current page should be kept
var firstPageToKeep = (pageNr - 2);
//Delete every page on top that should not be kept in memory
for(x=0;x<firstPageToKeep;x++) {
console.log('x: '+x);
$('#page_'+x).remove();
}
//=================================
//Determine which pages below current page should be kept
var lastPageToKeep = (pageNr + 2);
//Delete every page below current page that should not be kept in memory
for(y=0;y<lastPageToKeep;y++) {
$('#page_'+y).remove();
}
This does remove every page except the current page. I believe I have set the limits of which pages should be deleted and which not. Why is everything deleted except the current page?

Try this code:
$('.pagina').each(function(i, page) {
if ((i < pageNr - 3) || (i > pageNr + 1)) {
$(page).remove();
}
});
http://jsfiddle.net/6NCmR/

Try This:
$("#scroller").children().not("#id1 #id2 ...").each(function(){//Your code});

My quick guess is, that your last for-loop deletes all pages up to lastPageToKeep, keeping only the last pages. You should iterate beginning from lastPageToKeep+1 up to the maximum number of pages.
Nevertheless I'd recommend to you the :lt and :gt selectors from jQuery!
I made a quick fiddle for you demonstrating the use:
http://jsfiddle.net/d6tZ6/
Note: As a side effect this will also remove the neccessity for having an ID for each page.

Related

How to scroll to element after click event and new page load with Vanilla JavaScript

I will try to summarize this in a Requirements fashioned way, I hope this simplifies the question.
When clicking on an anchor tag, the web page navigates the user to a new page, where upon page load, the page is scrolled to the element which corresponds to the aforementioned anchor tag, which was previously clicked.
As you will see in the code I am trying to make use of the CSS scroll-behaviour property.
https://developer.mozilla.org/en-US/docs/Web/CSS/scroll-behavior
So far I have tried out the code bellow, however when I run it I get an error message in the developer console stating:
TypeError: Cannot read property 'offsetTop' of undefined
Hence, I surmise that the window.onload function is not really fired on the page which I would like to load but the very same page on which I am located when clicking the anchor tag. How can I change the code so it would count for page intended.
HTML of Page A (where the anchor tag is located):
<a id="ship-it" href="services.html" class="services">
<div id="image-container_4">
<div id="image_4">
<div id="overlay_4"></div>
<h2 class="h2">We pack it and ship it</h2>
<img id=imageB src="/images/shipping.jpg" alt="">
</div>
</div>
</a>
HTML of Page B (where the target element is located):
<section id="manufacturing-section" class="section">
<img src="/images/manufacturingMelting2.jpg" alt="Magnetic Particle Inspection">
<div id="manufacturing-container">
<h2> <span>Manufacturing</span> <br> We provide high quality, low cost solutions to meet your requirements.</h2>
<p>
soemthing something something, DarkSide...
</p>
</div>
</section>
JS / CSS:
function scrollIt(element) {
window.scrollTo({
'behavior': 'smooth',
'left': 0,
'top': element.offsetTop
});
}
const serviceAnchor = document.querySelectorAll('.services');
//'serviceAnchor' is located on page A
const sections = document.querySelectorAll('.section');
// 'sections' is located on page B and represents the element the page should scroll to when the page has loaded after the corresponding anchor tag was clicked
serviceAnchor[0].addEventListener('click', () => {
window.onload = scrollIt(sections[0]);
});
serviceAnchor[1].addEventListener('click', () => {
window.onload = scrollIt(sections[1]);
});
serviceAnchor[2].addEventListener('click', () => {
window.onload = scrollIt(sections[2]);
});
serviceAnchor[3].addEventListener('click', () => {
window.onload = scrollIt(sections[3]);
});
The reason you're getting the error is it's impossible to run javascript across page loads. Assuming you're using a traditional site and not a single-page app, when the browser loads a new page, all javascript on the current page is stopped.
Browsers already support jumping to an element on page load using the www.site.com#myElementId syntax. If you want smooth scrolling, you'll need to pass the id of element to scroll in the url, or some other way like caching its id in localstorage, then run your smooth scrolling js on the pageload of the other page.
You can't navigate to a different page and then ask the browser to launch a piece of JavaScript. That would be a huge security issue, since I could make you click into a link to, let's say, my-bank.com then do a bit of JavaScript do access your secret cookies or local storage and hack into your account.
The only thing you can do is link to anchors inside the linked page, and the default scroll behavior (no smooth scrolling, for most browsers, since it's the least computationally and resources intensive) will be used:
<!-- not possible -->
<a onclick="navigateThenDoSomething()">Some link</a>
<!-- possible -->
Some link
If you own the target page, however, you can hide a target section in the query string then do a bit of magic in the target page's onload to smoothly scroll to your section:
<!-- source-page.html -->
Some link
// script running at target-page.html
const url = new URL(window.location);
const section = url.searchParams.get('section');
if (section) {
// scroll smoothly to `section` using
}
Since .scrollTo JS method with options has the same browser compatibility as scroll-behavior CSS property, and you're OK with that, you might get rid of your JS code and set:
html, body, .or-other-scrolling-container {scroll-behavior:smooth}
and use anchor links.
So HTML of Page A would be e.g.:
<a id="ship-it" href="services.html#manufacturing" class="services">
<div id="image-container_4">
<div id="image_4">
<div id="overlay_4"></div>
<h2 class="h2">We pack it and ship it</h2>
<img id=imageB src="/images/shipping.jpg" alt="">
</div>
</div>
</a>
And HTML of Page B (please note <a name="#manufacturing"> tag):
<a name="manufacturing"></a>
<section id="manufacturing-section" class="section">
<img src="/images/manufacturingMelting2.jpg" alt="Magnetic Particle Inspection">
<div id="manufacturing-container">
<h2>
<span>Manufacturing</span><br>
We provide high quality, low cost solutions to meet your requirements.
</h2>
<p>something something something, DarkSide...</p>
</div>
</section>
Working example:
html {scroll-behavior:smooth}
.long {height:100vh; background:#efc}
<a id="ship-it" href="#manufacturing" class="services">
<div id="image-container_4">
<div id="image_4">
<div id="overlay_4"></div>
<h2 class="h2">We pack it and ship it</h2>
<img id=imageB src="https://picsum.photos/50/50" alt="">
</div>
</div>
</a>
<section class="long">Placeholder to enable scroll</section>
<a name="manufacturing"></a>
<section id="manufacturing-section" class="section">
<img src="https://picsum.photos/400/220" alt="Magnetic Particle Inspection">
<div id="manufacturing-container">
<h2>
<span>Manufacturing</span><br>
We provide high quality, low cost solutions to meet your requirements.
</h2>
<p>something something something, DarkSide...</p>
</div>
</section>
Hope it helps.

How to load html pages with slides

I have three pages on my website. index.html, services.html and company.html. What I need is when a user clicks on services link, then the page will load from the left or right side instead of the load as normal. I don't know perfectly but it may be possible with some Jquery elements like data-transition="left", data-transition="base", data-name="services". Is there any plugin to load pages from left or right. I need this, Please help me.
There is no way to "load" the page from left to right, but what you can do is:
On your services page
create a "wrapper div" around your page content, and
off-set the content inside the wrapper div to beyond the far right of the page, then
use jQuery/javascript on page load (i.e. inside the $(document).ready() function to animate the content back to normal position.
So, something like this (untested):
<body>
<div id="wrapper">
<div id="inner-wrap">
//page content goes here
//Actually, I might create an inner div here and off-set/animate that one...
</div>
</div>
</body>
CSS:
#inner-wrap{position:relative;margin-left:100vw;}
jQuery:
$(document).ready(function(
//use jQuery .animate() method to slide the marginLeft param back to 0.
){});
Note that jQuery's animate method does not use margin-left - rather, it uses marginLeft. Like that.
Example:
Animating marginLeft with jQuery
 
Update:
You can use the same idea that was suggested above, but you only need a single file (e.g. index.html) for the entire website, and the "pages" are all just DIVs, and you can use jQuery/javascript to "change pages".
For example:
<body>
<div id="wrapper">
<div id="page1" class="pagex">
//page ONE content goes here
</div><!-- .pagex -->
<div id="page2" class="pagex">
//page TWO content goes here
</div><!-- .pagex -->
<div id="page3" class="pagex">
//page THREE content goes here
</div><!-- .pagex -->
</div>
</body>
CSS:
#wrapper{position:relative;}
.pagex{position:absolute;top:0;left:100vw;}
Concepts you need to understand:
a) z-index -- allows you to position one div on top of another
b) position:absolute -- removes the div from the HTML flow and allows you to position it anywhere on the screen, even over-top of other divs

Multiple pages in one html page

Looking to be able to put multiple distinct pages into one html page similar to the code shown below that was posted in this post:
Multiple distinct pages in one HTML file
However, I would like to have a fixed header above the pages to allow for navigation.
For example, the header has 4 links (Link1,Link2,etc.) that a user can choose from. If a user where to click on "Link2", then only Link2 will appear beneath and the other pages will remain hidden.
Let me know, Thanks!
function show(shown, hidden) {
document.getElementById(shown).style.display='block';
document.getElementById(hidden).style.display='none';
return false;
}
<!DOCTYPE html>
<html>
<body>
<div id="Page1">
Content of page 1
Show page 2
</div>
<div id="Page2" style="display:none">
Content of page 2
Show page 1
</div>
</body>
</html>
You could play with the IDs only, but if you get many pages that starts to get a little tedious. I suggest using a class to do the hiding. Also, if you want there to be a common header for the pages, you just need to build it from HTML elements and then display the page links there and not within the page content.
I made an alternative suggestion where I added a 'page' class to all the page DIVs. Then what you can do is hide all the DIVs with the "page" class and show the one you want with an ID. This too is not a very flexible system, you can't easily do a dynamic amount of pages or a dynamic first page but it is a place to start. Here's my example:
This is in JSFiddle http://jsfiddle.net/H4dbJ/ but here's the code directly:
// show the given page, hide the rest
function show(elementID) {
// find the requested page and alert if it's not found
const ele = document.getElementById(elementID);
if (!ele) {
alert("no such element");
return;
}
// get all pages, loop through them and hide them
const pages = document.getElementsByClassName('page');
for (let i = 0; i < pages.length; i++) {
pages[i].style.display = 'none';
}
// then show the requested page
ele.style.display = 'block';
}
span {
text-decoration:underline;
color:blue;
cursor:pointer;
}
<p>
Show page
<span onclick="show('Page1');">1</span>,
<span onclick="show('Page2');">2</span>,
<span onclick="show('Page3');">3</span>.
</p>
<div id="Page1" class="page" style="">
Content of page 1
</div>
<div id="Page2" class="page" style="display:none">
Content of page 2
</div>
<div id="Page3" class="page" style="display:none">
Content of page 3
</div>
Further development ideas include: a next/prev button that uses Page1 Page2...PageN the page number as a variable, loops through all the pages an shows the last one. Or shows the first one. After that, a Next/Previous button that keeps track of the current page in a variable and then goes to the next one.

YUI menu change page content not whole page

I have divided html page into :
<body>
<div class="menu_container">
<!-- added menu here -->
</div>
<div class="content">
<!-- body content here -->
</div>
</body>
I want to change the content of "content" div when I select menu item.
ie depending on menu item selection div content should change, like what happens in Tabviews.
How can I do so?
The latest versions of YUI include the concept of Pjax which uses History and Ajax to update the page. It's really easy to set up and it'll keep your URLs working. Check out the User Guide: http://yuilibrary.com/yui/docs/pjax/.
You only need to add the yui3-pjax class to each menu that updates the page, apply the Menu plugin, plug the Pjax plugin and have your server return the right HTML content.
<div id="menu-1" class="yui3-menu">
<div class="yui3-menu-content">
<ul>
<li class="yui3-menuitem">
<a class="yui3-menuitem-content yui3-pjax" href="/some-page.html">Some page</a>
</li>
</ul>
</div>
</div>
<div id="content">
<!-- here goes the page content -->
</div>
<script type="text/javascript">
YUI().use('node-menunav', 'pjax-plugin', function (Y) {
Y.one('#menu-1').plug(Y.Plugin.NodeMenuNav);
Y.one('#content').plug(Y.Plugin.Pjax);
});
</script>
This should do the trick:
Y.one('.menu_container').on('click', function(e) {
Y.one('.content').setHTML("<h1>Hello, <em>World</em>!</h1>");
});
Depending on the selector used instead of menu_container, you can update the content accordingly.
EDIT: In fact, delegate is probably better for your needs:
Y.one('.menu_container').delegate('click', onClick, '.menu-item');
http://jsfiddle.net/olan/w2jfh/

jQuery Mobile: Multi-Page Application with Separate Pages: Second Page not Getting Styled

We have a single page application with two views (essentially, a list of items and a details page for the selected item). Both views are in separate html files, and we’re using sammy.js to transition/navigate between the pages. Everything was working great until we tried to add jQuery Mobile to the mix. Now, when we navigate to the second page (the details page), jQuery Mobile is not styling the page.
Our working app is not set up as described by jQuery Mobile’s multi-page template (i.e., having all page divs in the same html file and use their navigation system to load linked pages into the DOM via AJAX). But, is it possible to have separate pages, use something other than jQuery Mobile’s navigation, and still have jQuery Mobile style the second page? Or, is there a way to force jQuery Mobile to style the second page?
Here’s some code snippets that’ll hopefully help show what we’re doing. (Note: We’re also using ASP.NET razor views.)
index.cshtml
<body>
#RenderPage("Views/items.cshtml")
#RenderPage("Views/item.cshtml")
#Scripts.Render("~/bundles/jquery")
<script>
$(document).bind("mobileinit", function () {
$.mobile.ajaxEnabled = false;
$.mobile.hashListeningEnabled = false;
$.mobile.pushStateEnabled = false;
$.mobile.loader.prototype.options.text = "loading. please wait...";
$.mobile.loader.prototype.options.textVisible = true;
});
</script>
#Scripts.Render("~/bundles/jquerymobile", ...)
</body>
items.cshtml (this page gets loaded and rendered correctly)
<section id="items-view" class="view" data-role="page">
<section data-role="header">
....
</section>
<section data-role="content">
(navbars, ULs, LIs, etc. are here, with each LI a link to go to the details page)
</section>
<section data-role="footer">
....
</section>
</section>
item.cshtml (this page gets loaded but NOT rendered correctly, there is no jQuery Mobile styling)
<section id="item-view" class="view" data-role="page">
<section data-role="header">
....
</section>
<section data-role="content">
(ULs, LIs, listboxes, textboxes, etc. are here)
</section>
<section data-role="footer">
....
</section>
</section>
router.js (used to route between pages)
....
navigateTo = function (url) {
sammy.setLocation(url); // url = #/items or #/item/1234
},
....
In the js file for the item page, we’ve tried:
var $page = $("#item-view");
//$page.trigger("create");
//$page.listview("refresh");
//$page.page(); (this one kind of work but doesn’t style every object)
//$page.page("refresh", true);
but haven’t got any thing to work correctly and completely.
So, again, given our situation, is there a way to have a jQuery Mobile multi-page app with actual separate physical files and have all pages get style correctly? Or is there a programmatic way to force jQuery Mobile to style all pages correctly?
Thanks.
jquery mobile does NOT load everything from your second page.
when you require a new page with JQM (or it's ajax method), it loads parts of your page's DOMs and get all things under
<div data-role="page" id="yourPageID"></div>
so your could simply try put your stylesheet under "data-role", like this:
<div data-role="page" id="yourPageID">
<link rel="stylesheet" href="yourStyleSheetLink.css" />
</div>
then, when JQM requires a new page, your stylesheets will be loaded.
as a non-English speaker, i hope you can understand my words :)

Categories