On my jQuery mobile app;
On menu.html and inside body I do something like this to go help.html;
....
$(document).off('pageinit', '#menupage').on('pageinit', '#menupage', function() {
$(document).off('click', '#help').on('click', '#help', function(){
$.mobile.changePage("help.html", {
reloadPage: true,
transition: "flip",
reverse: false
});
});
}
....
<li><a id="help" href="#" role="link" data-role="none">
<div class="img help"></div>
<div class="menuTitle langMenuItem3">Help</div>
<div class="arrow"></div>
</a></li>
Then on the help.html page I have a back button like this to go back to menu.html:
<header data-role="header">
<a href="#" data-rel="back" class="button" data-role="none">
<div class="arrow_reverse"></div><span class="langBack">Terug</span>
</a>
<div class="pageTitle">Over deze app</div>
</header>
My problem is this works under normal conditions, BUT if I make a refresh on menu.html, then go to help.html and then go back to menu again, menu.html does not load properly, I can see the page visually loaded ok but on firebug I see that some necessary javascripts inside tags does not hit anymore, It never hits any javascripts anywhere on menu.html anymore, just loads the previous html from cache thats all. Also the page title of menu.html does not change correctly and stays as "Help" after that point.
my full menu.html looks like this;
http://jsfiddle.net/M5CYZ/
Any ideas?
Do it this way.
Give back button an ID
<a href="#" id="backbtn" class="button">
<div class="arrow_reverse"></div><span class="langBack">Terug</span>
</a>
and then add the below code in help.html
$('#backbutton').off('click').on('click', function () {
$.mobile.changePage("menu.html", {
reloadPage: true,
transition: "flip",
reverse: true
});
});
This is a wild guess but according to your code this is a normal behaviour.
jQuery Moible event pageinit will trigger only once during the initial page load and unless page is refreshed (manually, with rel="external" or in your case reloadPage="true") it will never trigger again.
If you want javascript to execute again each time page is visited then use pagebeforeshow event instead. As seen in your example, removing pageinit and adding it back will not help you.
If you want to find more, read my other answer/article about page events: jQuery Mobile: document ready vs page events
And here's an example to prove my point: http://jsfiddle.net/Gajotres/Q3Usv/
$(document).on('pageinit', '#index', function(){
alert('Pageinit');
});
$(document).on('pagebeforeshow', '#index', function(){
alert('Pagebeforeshow');
});
Related
I see many websites such as gitHub changing it's html content and URL without refreshing pages.
I find one possible way to do this in HTML Histroy API.
Here is the code.
HTML
<div class="container">
<div class="row">
<ul class="nav navbar-nav">
<li>Home</li>
<li>About</li>
<li>Contact</li>
</ul>
</div>
<div class="row">
<div class="col-md-6">
<div class="well">
Click on Links above to see history API usage using <code>pushState</code> method.
</div>
</div>
<div class="row">
<div class="jumbotron" id="contentHolder">
<h1>Home!</h1>
<p>Lorem Ipsum is simply dummy text of the printing and typesetting industry.</p>
</div>
</div>
</div>
</div>
home.html
This is home page
about.html
This is about page
contact.html
That one is content page
JAVASCRIPT
<script type="text/javascript">
jQuery('document').ready(function(){
jQuery('.historyAPI').on('click', function(e){
e.preventDefault();
var href = $(this).attr('href');
// Getting Content
getContent(href, true);
jQuery('.historyAPI').removeClass('active');
$(this).addClass('active');
});
});
// Adding popstate event listener to handle browser back button
window.addEventListener("popstate", function(e) {
// Get State value using e.state
getContent(location.pathname, false);
});
function getContent(url, addEntry) {
$.get(url)
.done(function( data ) {
// Updating Content on Page
$('#contentHolder').html(data);
if(addEntry == true) {
// Add History Entry using pushState
history.pushState(null, null, url);
}
});
}
</script>
This code is working fine even you go back or forward in browser.
But the problem is that when you refresh page it only shows the file which is being refreshed. For example, if you refresh the about.html then only the following will show: This is the about page.
Unlike the gitHub it can't show the complete page. As you see in gitHub, even you refresh a page it will show the page same as how it was before refreshing.
How can I do that?
Thanks...
You may use Routie or Director to do the routing. And within their callback functions write the code to update the part of your HTML page, for this you may use Fragment.js.
You can change DOM anytime you want without loading the page.
Use fundamental XMLHTTPRequest or Ajax to contact the server without refreshing the browser.
There are many frameworks which offer convenient url routing which can change content automatically without page refreshes. Angular JS is my favorite such framework which offers great routing capability among many other things.
You have to check/set the value of your variable on the event onload of the page.
Your code does not work - when you click on a particular link the page does refresh. correct me if i am wrong.
This script is triggered only once when the page loads.
The page has loaded, click the link, the data came from.
Click the link again, nothing.
Overload the page, the link works, etc.
What is wrong in the script, why it triggered only once?
<script>
$(function() {
$('a').click(function() {
$.get('ajax', function(data) {
$('#mydiv').html(data);
});
});
});
</script>
<div id="mydiv">
Update the div!
</div>
Compared the data in the "mydiv" before and after clicking the link:
before clicking the link
<div id="mydiv">
<a href="#">
Update the div!
</a>
</div>
after link was cliked
<div id="mydiv">
<a href="#">
Update the div!
<!--Here is the data that came from.-->
</a>
</div>
Because you're overwriting the a tag that you attached the click event to, you'd need to rerun the code that attaches the click event again. Or you could use event delegation like blex suggests:
$(document).on("click", "a", function(){
}
Because of dynamically created a you should use:
$(document).on("click", "a", function() {
I'm developing a RhoMobile appand I've been having lot of trouble with page transitions.
At the end, I just decided to turn them off for a better user experience. Every button click works perfectly, except for one where I have a button inside a Collapsible element.
For the click event on the button not to get interpreted as a click on the collapsible, I use this js code, which I suspect is causing trouble:
$(document).on('pagebeforeshow', '#index',function(e){
$('.details').bind('click', function (e) {
e.stopPropagation();
e.stopImmediatePropagation();
});
});
And in the HTML:
<div data-role="page" id="index">
Here go headers & navbar and other stuff
</div>
<div data-role="content">
<div data-role="collapsible-set" class="uurbon-block">
<div data-role="collapsible" data-collapsed="false">
<h3 data-position="inline"><p class='alignleft'>Collapsible title</p><div style="clear: both;"></div>
<span style="float:right;" class="button-span">
<a href="some_url.html" data-role="button" data-mini="true" data-inline='true' data-icon="star" data-iconpos="left" class="details" data-transition="none">
Button
</a>
</span>
</h3>
</div>
</div>
</div>
This will cause a blank page to be shown for 1-2 secs before transitioning. I'd be looking for a fix, but if not, i'd be happy with that page just beeing black (my app background is black also, so this blink wouldnt be so noticeable).
Note: I have alredy tried setting body background color in css, won't work.
Thanks for your ideas!
As pointed by Omar, if you want to put a button inside a collapsible and prevent the collapsible from capturing the click while also handling the page in the same browser, the correct way to do this is (Take notice that this may only apply to RhoMobile, but its worth a try on other jquerymobile-based frameworks):
and avoid RhoMobile trying to open this in a new browser is by using:
javascript:
$(document).on('pagebeforeshow', '#index',function(e){
$('.details').bind('click', function (e) {
e.stopPropagation();
$.mobile.changePage("your_page");
});
});
HTML:
Button
Notice the href="javascript:;". I had this first set to "#" and also "", but that didn't work.
This is the first page where I try to open the detail.html;
<a href="detail.html" data-role="none" role="link">
<div class="place">name</div>
<div class="arrow"></div>
<div class="ammount">-€4,<span class="fontsize14">25</span></div>
</a>
I have problems to load the scripts on detail.html (after href link is clicked on first page)
Here is my script in header of details.html(the page I go after href is clicked on first page), Problem is I can NOT get the console test print, that function is NOT called when details.html page is loaded. It only hits after I manually refresh the page
<script>
$(document).bind("pageinit", function(){//or $(document).ready(function ()
console.log('test');
});
</script>
To understand your problem I think you need to first understand how jQuery Mobile "loads" external pages. By default when you click a link to a separate HTML page JQM loads the first data-role="page" on that page and attaches it to the DOM of the first page, the thing is JQM only loads that page div and not any scripts etc. that are outside that container.
If you want to run code for a second page, you either need to include that script on your first page and use event delegation (since the second page is not part of the DOM yet) or include the script withing the second page's date-role="page" wrapper.
Case in point in your case if you want to run code for your details page you either need to include the script on your first page for example assuming you have a div on your detail.html page like the following
<div id="details" data-role="page"> ..rest of your content
</div>
Then on your first page you could do the following
$(document).on('pageinit', '#details', function() {
console.log('test');
});
Or alternatively you can include a script tag withing your "details" page wrapper.
EDIT:
As I mentioned this is the default behavior, however if you wish you can tell jQuery Mobile to do a full post when loading a second page by adding in data-ajax="false" or rel="external" to your link for example
<a href="detail.html" data-ajax="false" data-role="none" role="link">
<div class="place">name</div>
<div class="arrow"></div>
<div class="ammount">-€4,<span class="fontsize14">25</span></div>
</a>
The difference between data-rel="external" and data-ajax="false" is if the second page is basically semantic in that data-rel="external" should be used if the second page is on a different domain.
I made you an working example: http://jsfiddle.net/Gajotres/Eqzd2/
$("#second").live('pagebeforeshow', function () {
console.log('This will only execute on second page!');
});
You can use on instead of live if you are using last version of jQuery.
Also take a look at my article about event flow in jQM page transition: https://stackoverflow.com/a/14010308/1848600
I have the following js:
$(function() {
$('#header a').click(function() {
$('#contentspace').empty();
// $("#contentspace").load(eventUrl + "#content");
$("#contentspace").load(this.href, + ' #content', function(response){
console.log($('#content', response).html())
event.preventDefault();
});
});
});
and html:
<div id="header" class="ui-corner-all ui-buttonset">
<a title="index" href="index.php" ><span>home</span></a>
<a title="code" href="code.php" ><span>code</span></a>
<a title="design" href="design.php" ><span>design</span></a>
<a title="illustration" href="illustration.php" ><span>illustration</span></a>
<a title="writing" href="writing.php" ><span>writing</span></a>
<a title="links" href="links.php" ><span>links</span></a>
<a title="about" href="about.php" ><span>about</span></a>
</div>
I use this to load sections of web pages into #contentspace, and give my practice site an ajax kind of feel. The problem arises when the user clicks to go back to the main page, and the main page is loaded inside itself. I thought I might've fixed it by adding - ' #header', to the .load argument, but this doesn't seem to do anything, and even if it had I can see how it would create other problems.
Summary: I'm having problems making an effective landing page with jquery. the home page is loading it's header and footers into itself.
Maybe you could separate the main page into something like index.html and home.html, index containing only the header and footer and the other containing only the content of the main page.
Then you could have index do the .load with 'home.html' once when the page is initially loaded (e.g. just before you attach the click handlers to the nav).