jQuery Mobile objects stay in memory - javascript

I am currently developing a jQuery mobile app. On one page there is a chart created (highcharts) which then can be exported (canvg and canvas2ImagePlugin). However, I noticed that the chart object stays in memory. This has the effect that if the page is opened multiple times and the export button is then pressed, all the previously generated graphs will be exported.
Having a look at Chrome Dev Tool's heap snapshot, I noticed that all the objects stay in memory. To demonstrate this, I made a very basic app on jsfiddle, leaving all the highchart and canvg code out: http://jsfiddle.net/dreischer/Lt4Xw/ --> just click on the button to go to the second page. If you click the export button a pop-up will open. However, if you go back to page one and then page two and click the button again, two pop-ups will open (you might need to allow pop-ups).
I also tried setting analyseGraph null or undefined or using .remove() on pagebeforehide but it didn't help.
Thank you for your help!
Here is the code, for this example:
HTML:
<div data-role="page" id="p1">
<div data-role="header"><h1>Header Page 1</h1></div>
<div data-role="content">
<p>Page 1</p>
Go To Page 2
</div>
</div>
<div data-role="page" id="p2">
<div data-role="header" data-rel="back"><h1>Header Page 2</h1></div>
<div data-role="content">
<p>Page 2</p>
Go To Page 1
<a id="export_graph" data-role="button" style="max-width: 300px;" data-mini="true">Export</a>
</div>
</div>
Javascript:
$(document).on('pagebeforeshow', '#p2', function (){
var Graph = function (){
this.drawGraph = function(){};
this.exportCanvas = function(){
window.open();
};
}
var analyseGraph = new Graph();
analyseGraph.drawGraph();
$(document).on('click', '#export_graph', function(){
analyseGraph.exportCanvas();
});
});

Every time you show page 2 you bind a click event to document. So I think you must use 'off' once in a while, like this
$(document).on('click', '#export_graph', function(){
analyseGraph.exportCanvas();
$(document).off('click');
});

Related

Continuing to Show/Hide a div based off user selection throughout time on website

I currently have a section on my website (site is constructed in Laravel 5) which the user can show/hide. It is essentially a greeting from me. At the moment, all I am doing is using jQuery .toggle() on the element to show/hide. The issue is, when a user visits a different page the element re-appears (because it wasn't hidden originally).
I have considered just using AJAX for my sub pages and not refreshing the page, as there is very little content here anyway, but I was wondering if there is a better way to just pass session variables or cookies to different views and continue to hide the div.
HTML:
<div class="container">
<div class="row-fluid welcome-container">
<div class="col-md-3 profile">
<img class="profile-picture" src="images/jon.jpg">
</div>
<div class="col-md-9 welcome-box">
<div class="welcome">
<h2>
Welcome to my website.
<hr>
</h2>
</div>
<p class="hide-welcome">
[-]
</p>
</div>
</div>
<p class="show-welcome">
[+]
</p>
</div>
JS:
$(".hide-welcome").click(function() {
$(".welcome-container").slideToggle(500, "swing");
$(".hide-welcome").css("display", "none");
$(".show-welcome").css("display", "block");
var hidden = 1;
});
$(".show-welcome").click(function() {
$(".welcome-container").slideToggle(500, "swing");
$(".show-welcome").css("display", "none");
$(".hide-welcome").css("display", "block");
var hidden = 0;
});
I figure if I can pass 'hidden' along to each view via a Session/Cookie I could just run a blade check on that variable and then either hide/show the div at page load. Is there an easy way to do this, or should I just do AJAX loading of body content (and never leave the home page)?

Navigation issue on Onsen UI. How do I work around? (Onsen UI ons-navigator implementation issue)

Hi, I'm facing this issue on Onsen UI. How do I work around?
Intro: The following code creates an Onsen app interface that shows a start page. On the start page are two things (1) is the dynamic-content and (2) is the navigation button.
When the start page loads, pageinit event triggers and feed/populate dynamic-content to the start page. navigation button navigates to the start page every time.
The intention is to: Populate dynamic-content when a dynamic content becomes available (for this example it's at instant). The dynamic-content should be there for as long as the start page exist in DOM.
The issue: Happens when user try to navigate to the same page. While the animation kicks in, the pageinit does trigger for the start page. But the dynamic content went missing.
Perhaps... when navigator is trying to animate the page, it duplicate the start page and without the dynamic content
How should I work around?
Thanks for helping. ('',)V
<ons-sliding-menu
var="appMenu"
menu-page="menu.html"
main-page="navigator.html"
swipeable="true"
swipe-target-width="100px"
side="left"
type="overlay"
max-slide-distance="220px">
<div id="toast">
<div class="fly-wrapper">
<div class="fly-card z-depth-5" style="display:none;">
<div class="message"></div>
</div>
</div>
</div>
</ons-sliding-menu>
<script>
document.addEventListener("pageinit", function(e) {
if (e.target.id == "start") {
document.getElementById('dynamic-content').textContent = 'The start page was here';
}
}, false);
</script>
<ons-template id="navigator.html" style="display:none;">
<ons-navigator var="appNav" page="start.html"></ons-navigator>
</ons-template>
<ons-template id="start.html" style="display:none;">
<ons-page id="start" class="start">
<div id="dynamic-content"></div>
<a class="button" ng-click="appNav.pushPage('start.html',{animation:'simpleslide'})">
Load start again
</a>
</ons-page>
</ons-template>
<ons-template id="navigator.html" style="display:none;">
<ons-page></ons-page>
</ons-template>
Onsen tutorial about ons-navigator:
http://onsen.io/guide/overview.html#Pageinitevent
http://codepen.io/onsen/pen/IDvFJ
Right now I use the following work code:
<a class="trigger-pageload" app-href="start.html">Load start page</a>
$(document)
.on('tap','.trigger-pageload',function(){
var href = $(this).attr('app-href');
if(appNav.getCurrentPage().name!=href) appNav.replacePage(href);
});
SOLLUTION:
2 key steps as follows
prevent same page transition.
use replacePage instead of pushPage (don't follow onsen tutorial/example).
Additional step: Please update (Onsen tutorial and example).

Popup a dialog use jquery mobile in phone gap

I'm developing a phonegap project, I wanna popup a dialog of error information. I learn some from the demos of jQuery mobile, here is the link http://demos.jquerymobile.com/1.4.0/popup/#&ui-state=dialog I used the code of it and in my js file I use popup('open') to open it.
Here is part of my html code
<div data-role="popup" id="dialogZ" data-overlay-theme="b" data-theme="a" data-dismissible="false" data-transition="pop">
<div data-role="header" data-theme="b">
<h1 align="center">Sign in failed</h1>
</div>
<div role="main" class="ui-content">
<p id="SigninError"></p>
<span align="center">OK</span>
</div>
</div>
And here is part of my js code
else if (data == "Error2") {
var message = '<p align="center">Wrong username or password</p>';
SigninError.empty().append(message);
$('#dialogZ').popup('open');
}
I wanna have the effect like the demo but it didn't work.
Anyone knows why? It seems I can not have the css work properly, but I have included the jquery.mobile-1.4.0.css. Need helps!!
ya i got same issue before 4 months finally i got a solution. when you append content inside the popupview at the time u must call like this.....
JS
$('#dialogZ').popup();
$('#dialogZ').popup('open');
or
$('#dialogZ').popup();
setTimeout(function(){
$('#dialogZ').popup('open');
},100);
HTML
your data-role popup must inside the content of your calling page
Ideally data-transition should be on the link which triggers popup. since you are opening the popup in code, there is an additional attribute for $(dialog).open function, u need to pass the transition as part of open function., jquery doc

JQueryMobile: stopPropagation() makes blank page flash on href click

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.

jQuery Mobile multiple pages causing problems when calling a panel

I have an HTML document with multiple pages using jQuery Mobile's data-role="page". I am trying to call a panel on the second page but am receiving the error
cannot read property 'nodeType' of undefined
The error occurs when I try to transition to the second page. My basic page structure is as follows:
<body>
<div data-role="page" id="page1">
Enter Page 2
</div>
<div data-role="page" id="page2">
<h3> tthis is page 2 </h3>
<input type="button" id="myButton"> My Button </input>
<div data-role="panel" id="myPanel">
<p> Panel content </p>
</div>
</div>
</body>
The panel is being called through a function, but I still receive the same error when I comment out the function.
$(document).ready(function() {
$('#myButton').on('click', function() {
$('#myPanel').panel('open')
})
})
The panel works if it is on the first page and if I define it on the first page and open it on the second, it still opens on the first. It is there when I hit the back button. I am using jQuery Mobile too is that has an effect on anything.
Why am I receiving this error? Is there a simple solution or do I need hack my way around this by creating the panel dynamically? Thanks.
First off, never use .ready() in jQuery Mobile.
Important: Use $(document).bind('pageinit'), not $(document).ready()
The first thing you learn in jQuery is to call code inside the $(document).ready() function so everything will execute as soon as the DOM is loaded. However, in jQuery Mobile, Ajax is used to load the contents of each page into the DOM as you navigate, and the DOM ready handler only executes for the first page. To execute code whenever a new page is loaded and created, you can bind to the pageinit event. This event is explained in detail at the bottom of this page.
Source: http://jquerymobile.com/demos/1.2.0/docs/api/events.html
Secondly, each page should have its' own panel with a different id, and the div containing the panel should be a direct child of data-role=page.
Panel markup/structure:
<div data-role="panel" id="id" data-position="left" data-display="push" data-theme="b">
<!-- Contents -->
</div>
Opening a panel:
Statically by using anchor/button:
Open
Dynamically:
$.mobile.activePage.find('[data-role=panel]').panel('open');
// Or
$('#panel_id').panel('open');
Closing a panel:
(in case data-dismissible is set to false)
Statically by using anchor/button (Note: It should be placed inside Panel div):
Close
Dynamically:
$.mobile.activePage.find('[data-role=panel]').panel('close');
// Or
$('#panel_id').panel('close');
Demo

Categories