We are writing JQueryMobile application using ASP.NET MVC3 + JqueryMobile RC1.
Few pages have their own Ajax methods which we call using jQuery code ($.getJSON()
You could keep a variable IsPageInitialized = false
for each page, bind events only if this variable is false and set it to true when you assign the event handlers.
It sounds like you might need to wrap your code in an IsPostBack
check. For example:
void Page_Init(object sender, EventArgs e)
{
if (!IsPostBack)
{
RegisterScriptHere();
}
}
EDIT
On a second reading, you may not be asking about the server side, if you are trying to do this on the client side, ignore my answer.
Two options:
1. use one() instead of bind() or live()
As long as the page is not dropped from the DOM, this should help. See here.
It says: "attach a handler to an event for an element. The handler is executed at most once per element."
Jquery Mobile uses it inside JQM too, probably for the same reason. So if you do like this:
$('button').one('click', function () { do something });
that should fire only once.
2. Use data() to set a flag after event is fired
Another idea would be to use data() to attach a flag to the page element or, as pages can be removed from the DOM, better attach it to the HTML or BODY element. These will stay...
I initiate scrollview on pages (hopefully once) like this:
$('div[data-role="page"]').live('pagebeforeshow.scroll', function(event){
var $page = $(this);
if ( $page.data('scrollable', 'Off') ) {
$page.data('scrollable', 'On');
scrollMe( $page ); // init
}
});
This would probably mean putting your function call outside of the actual page.
EDIT:
This also works for me using attr
:
// on pageinit - set global argument
$('html').attr('fire-once', 'Off');
$( '#your page' ).live( 'pageshow',function(event){
if ( $('html').attr('fire-once') == 'Off' ) {
$('html').attr('fire-once', 'On');
// your button.bind.behavior here
}
});
This way you set "fire-once" on the HTML element, which will always stay the same in JQM while you load pages in and out. Only if you go to a page with data-rel="external", fire-once will be reset.
On your specified page you listen for pageshow, fire the function, that first changes fire-once to "On" and then adds your button binding.
Since fire-once is now turned "On", even with multiple bindings the if-statement will fail and you will only assign the button behavior once.
I'm using the same setup with a JQM-panel history-array, which I need to setup only once and only add entries on changePage once, too. The above works fine for me and should also serve your purpose.
Send me a message, if you want to see a live example.
Cheers,
Frequent
Why don't you kill your handlers upon navigating away, something like this:
$("#@ViewBag.DivTitle").live("pagehide", function() {
$("#@ViewBag.DivTitle").die("pageshow");
}
You example code uses 'pageshow' rather than 'pageinit'. 'Pageinit' should work fine.
Using the jQuery Mobile framework, if you place a <script>
inside the <div data-role="page">
element it will be run each time the page is shown and if you are binding event handlers inside the code they will be bound each time the page is viewed as the DOM remains the same throughout site navigation.
Try moving the @RenderSection("BodyScriptsSection", required: false)
statement to the bottom of the page, just before the closing </body>
tag. That way the script will be included on every full-refresh (like if the user presses their refresh button) and if a user deep-links into your site; however it will not be run each time the page is gathered by jQuery Mobile's AJAX navigation.
You can also fix this issue by caching each page so it doesn't have to be gathered by the AJAX navigation on subsequent visits to the page. By default, jQuery Mobile Beta 3 and later (RC 1 at this time) remove pages from the DOM after they have been navigated away from by the user (event handlers bound are however not removed), this feature helps control the size of the DOM. To cache a page add data-dom-cache="true"
to the <div data-role="page">
element.