I have a menu with ~6 buttons, each that lead to the same page.
In that page, there is a drop down menu.
The purpose of the 6 buttons is that when one of those buttons is clicked, the page is redirected, and then the drop down menu opens to the correct tab.
However, all scripts are killed when a page is redirected, so I cant do something like this:
<body>
<a id="buttonID" onclick="GoToPage('buttonID')">All</a>
</body>
<script>
function GoToPage(buttonID){
redirect to page.html;
open menu to tab related to buttonID
}
</script>
Instead I would probably have to create a function that executes when the page loads, and then attempts to find from which button did it get there from, and opens the menu to the correct configuration based on that.
Should I use something like:
window.onload = ....
And how would I be able to pass which button redirected the page to this?
Opening the dropdown menu should be the responsibility of the destination page, not the source page. Since the server doesn't care about the dropdown menu state, send that information in the fragment identifier:
<a id="buttonID" href="page.html#all">All</a>
On the receiving end, you can retrieve the identifier with
document.addEventListener('DOMContentLoaded', (event) => {
let target = window.location.hash; // target = "#all"
// modify your menu as appropriate
});
The load event doesn't fire until the page has completely finished loading: images, stylesheets, everything. Modifying the dropdown menu doesn't require any of that, so use the DOMContentLoaded event instead. It fires when the HTML page has been loaded and parsed and is ready for DOM manipulation.
Related
I am working with this Template from templatemo.
I wanted to include some references to other parts of the website in the body text (e.g. Please "contact me" for further information). If you click "contact me" the page should navigate to "Contact" in the same manner as if the user clicked on the navigation bar to navigate to the page (with the same animation).
In order to so, i added the following code to trigger a click event:
<p class="tm-text">Contact me via the <a id="myLink" href="javascript:loadPage(5);">contact form</a></p>
And the function to trigger the click:
function loadPage(pageNo) {
$(document).ready(function() {
$('.nav-item').get(pageNo).click();});
}
So this code is working, if I click on the reference the page changes as if I clicked the navigation bar. BUT:
If I reload the page and click on the reference, the page navigates to the contact page, which then however is not diplayed properly (the contact form and the google maps view are missing).
If I reload the page, first open the contact page via the menu, then switch to the page with the reference and click on it, the contact page is loaded properly.
This behaviour is also shown if I reference another page (e.g. the Gallery). The gallery elements are displayed (the page is not completely empty), but the spacing between the elements is not correct.
It seems like every page has to be loaded at least once via the navigation bar. If this has happened, all pages are displayed properly when opened via a reference in the text.
Thanks for your support.
Your template use Hero slider + some customs JavaScript functions to move between "pages", so you need to use the same functions to get the same behaviour.
Doing that will work:
<p class="tm-text">Contact me via the <a id="myLink" href="javascript:goToPage('Contact');">contact form</a></p>
You need to add this JS function:
function goToPage(page_name) {
// Retrieve the <a> tag with the page_name
// page_name is the string of the page in the navbar
page_link_a = $('.navbar-nav .nav-link').filter(function(index) { return $(this).text() === page_name; });
page_link_li = page_link_a.parent();
// Trigger js code from hero slider
page_link_li.click();
// Trigger js code from templatemo
page_link_a.click();
}
The function goToPage() take one parameter, the string name of the section so if you have a section named My Gallery you need to put that, not my-gallery nor an index.
Is there a way to open a specific artical via an external link and focus on it when the links open on a one page wepage?
I have a webpage that shows content as you click on links by hiding and showing the divs. What i want is to make an external link to my webpage in the form of mywebpage/(div's name) and have the link open my page but showing the content of that div right away, instead of its usual opening content you would get when clicking on just the ordinary mywebpage link.
Is it possible? And how?
Short answer: yes.
Long answer: You will have to examine the URL's hash on page load and manually translate that into hidden or shown divs (or other positioning).
While you're at it, you could include browser history support when your divs are opened and closed.
Pulling apart what I did for http://www.tipmedia.com (Segment starts on line 322 of the page source)
//on page ready
$(document).ready(function() {
//examine hash
if(window.location.hash == "#thanks") {
//scroll to an anchor tag, slight delay to insure correct page height
setTimeout(function() {
$('html,body').animate({scrollTop:$("#contact").offset().top}, 0);
},500);
//hide and show necessary divs
$("#contactThanks").css({"display":"block"});
$("#contactIndex").css({"display":"none"});
$("#contactGeneral").css({"display":"none"});
$("#contactMeeting").css({"display":"none"});
$("#contactCareers").css({"display":"none"});
//clear the hash (not necessary for your use)
window.location.hash = "";
}
}
The history stuff is easy too, I used Modernizer.js for the best cross browser support, but it looks like this (non-Modernizer use is very similar)
//during the hide/show of new content...
//if history is available
if(Modernizr.history) {
//this data is whatever it is you wish to save
lastPageState = { div:divName, pos:amount, page:lastLoadedPage };
history.pushState(lastPageState, divName.substring(1,divName.length-6), "index.html");
}
//...
//then later, the popsate event handler
window.onpopstate = function(event) {
//examine event.state and do whatever you need to
//example segment starts line 989
//Whatever data you saved would be read here and you would do the appropriate action,
//hiding or showing divs, reloading AJAX content, etc.
}
Yes, you can use an anchor link.
So in your target page name the div with an id,say div id="target".
Then in the referring page use a link in this form
Referring Page:
GO to Target Info...
Target Page:
<div id="target">
...content...
</div>
FYI-"target" is just an example name, it could be anything...
I have a site that uses AJAX to dynamically load content into a div.
The links to do so are anchors with href="#" and an onclick event to trigger the AJAX.
This leaves me without a history when I click back, so if I load one page, then another and click back, it does nothing.
A basic version of the code is this:
<script type="text/javascript">
function loadXMLDoc(url)
{
<!-- Load XML Script here. -->
}
</script>
</head>
<body>
<div id="myDiv">
<!-- Target div. -->
</div>
Click Me.
Click Me.
Click Me.
</body>
What I would like to know is, can I give each link a different "#" and then use a popstate handler to call the appropriate event, so if I click link 1, 2 and then 3 and then start hitting the back button, it'll go back to 2 and then 1 etc..
I was going to use history.js and start using pushstate in the loadXML script but I think the whole manipulating history thing is a bit dirty and unreliable.
Am I thinking on the right lines or is there a better way?
Currently all my links just use "#" so that it pops back to the top of the page when loading more content but I'd like to be able to go back if possible.
Any help would be great.
Browser saves hashtags to history properly. Just add hashtag #1 to this question page, hit enter, change it to #2, hit enter, change it to #3, hit enter. Now click back button, and you'll see hash changes from #3 to #2. I recommend to change only hash itself on link click and react on page hash change and page load events.
function react() {
var hash = window.location.hash.replace("#", "");
loadXMLDoc(hash + ".txt");
};
document.body.onload = function() {
react();
window.onhashchange = react;
};
Click me
Click me
Click me
Please note that onhashchange event does not supported by old IE. The only way to deal with it if you want is to define timer with setInterval and check hashes equality.
Try to use combination of LocalStorage and HistoryAPI.
When you load XMLDoc store it in LocatStorage, when back is pressed - load data from storage, not from web.
A bit code above.
/* Handling history.back added */
window.onpopstate = function(event) {
yourHandleBackFunction(event.state);
};
function yourHandleBackFunction(renderTs) {
/*Check TS and load from localStorage if needed*/
};
I have a menu that loads a new html file in a div. The loading is done by a click event attached to the menu's <a> tags. The loading works well and I add the new load to the history by constructing a new href with a hash tag.
But when I use the back button, the URL is updated correct in the browsers address field, but the page is never loaded. If I focus the address field and press enter it loads.
This is the javascript located in the mypage.html header.
<script type="text/javascript">
$(document).ready(function() {
// replace menu link click
$(".right-menu a").live('click', function(ev) {
ev.preventDefault();
ev.stopPropagation();
window.location.href = $(this).attr('href');
$("#content-right").load('mypage'+window.location.hash.substring(1)+'.html');
return false;
});
// If page loads, load the content area according to the hash.
var hrtag = window.location.hash.substring(1);
if(hrtag=="")
hrtag='about';
$("#content-right").load('mypage'+hrtag+'.html');
window.location.hash = hrtag;
});
</script>
This is the menu
<ul class="right-menu">
<li>About</li>
<li>Screens</li>
<li>License</li>
<li>Download</li>
<li>Donate</li>
</ul>
If I load the page as mypage.html, the javascript will append the hash #about and load the div id "content-right" with mypageabout.html
If I click the menu, for example download, it will load the div id "content-right" with mypagedownload.html
In both cases, the window.location will be set to the hash version of the page, mypage.html#about and mypage.html#download to register them in the history.
If i click the menu in the following order; license, about, screens and then click the browser's back button, the address field will show; mypage.html#about, mypage.html#license but it will NOT load the pages!?!
The URLs are obviously in the history, but they don't load.
Any clue to what might be wrong here?
// Thanks
EDIT - The solution
Thanks to Andres Gallo's article I came up with this solution:
<script type="text/javascript">
$(document).ready(function() {
// Make sure the page always load #about
LoadIDWithURL('#content-right','myPageAbout.html');
window.addEventListener('hashchange',function() {
if (window.location.hash != "") {
// We have a hash, use it!
LoadIDWithURL('#content-right','MyPage'+window.location.hash.substring(1)+'.html');
} else {
// We do not have a hash, force page reload!
window.history.go(0);
}
});
});
// Load the targetID with the URL loadURL.
function LoadIDWithURL(targetID,loadURL) {
$(targetID).load(loadURL);
}
</script>
I wrote a very detailed article on this exact topic. It explains how to build exactly what you are trying to do.
Furthermore my article also explains how you can pass parameters in your links to have javascript do special things
Here is a link to the article http://andresgallo.com/2012/06/08/ajaxifying-the-web-the-easy-way/
The best method is to attach your functionality to your hashchanges rather than to you click events. This allows any changes in history to take advantage of your javascript functionalities.
This is normal behaviour when navigating between pages which differ only in their hash. You have two options:
Use the hashchange event, or an emulation of it, to detect when the user changes the hash by navigation back or forward and update the page appropriately
Use the HTML5 history API.
you can try with hashchange
$(function(){
$(window).hashchange(function(){
// some event
})
})
Here's what I have:
A web application that runs in a single HTML page (call it myapp.req), with content coming and going via AJAX
The application can be entered externally with a link such as myapp.req?id=123, and the application opens a tab with the item at id 123
The content on the page is mostly user's content, and many times has inner-application links to myapp.req?id=123
The problem is that clicking a link to myapp.req?id=123 reloads the browser, and removes any content or state that the user had loaded
What I want is to be able to catch link clicks whose destination is myapp.req?id=123, and instead of reloading the page, just open the tab for item 123, leaving anything else currently loaded alone. If the link is for an external website, though, obviously just let the browser leave.
So my question really: Can I have a global link handler that checks if I want to handle the link click, and if so, run some Javascript and don't leave?
I understand I could find all <a>s and add listeners, but my hope is that the solution would only require setting up the listener once, and not adding link handlers every time new content is loaded on the page. Since content can be loaded many different ways, it would be cumbersome to add code to all those places.
Does that make sense?
jQuery's live is what you need:
$('a').live("click", function () {
var myID = $(this).attr('href').match(/id=([a-zA-Z0-9_-]*)\&?/)[1];
if (myID) {
//run code here
alert(myID);
return false;
}
});
Any link will now have this click handler whether it's been added after this is called or not.
Sure you can. Add a clickhandler on the body. So you catch all clicks. Then you have to check if the target of the event or one of its parent is a link with your specific href. In this case stop the event and open the tab.
updated to use .live instead of .click
If you use jQuery, you can add a "live" click event handler to every a href at once:
<body>
click here
<br/>
whatever
</body>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.6.2/jquery.min.js"></script>
<script type="text/javascript">
$('a').live('click',function() {
var myID = $(this).attr('href').match(/id=([a-zA-Z0-9_-]*)\&?/)[1];
if (myID) {
//run code here
alert(myID);
return false;
}
});
</script>
This should extract the id from the href's query string and let you do whatever you want with it.