Does anybody know how to detect orientation change for Nativescript? - javascript

I have created two xml files for a screen. one named "login-page.port.xml" and the other one is "login-page.land.xaml".
Is there a way to programmatically detect orientation change within the application?
Thanks,
Keks

Yes, there is a way to detect orientation change in the application. The easiest method is in the page you want to get the orientation; add the loaded and unloaded events to your page.xml files:
<Page loaded="pageLoaded" unloaded="pageUnloaded">
In your page.js file; add code like this:
var application=require('application');
exports.pageLoaded = function() {
application.on(application.orientationChangedEvent, setOrientation);
};
exports.pageUnloaded = function() {
application.off(application.orientationChangedEvent, setOrientation);
}
function setOrientation(args) {
// Will console out the new Orientation
console.log(args.newValue);
}
A couple notes;
1. You want to add & remove the event listener as you enter and exit the page; otherwise the listener is global and will continue to fire when the orientation changes even when you are on another page.
2. You can add multiple listeners to this event, so again if you don't remove the listener, then each time you re-load this page you will add ANOTHER copy of this listener to the group and so it will fire as many times as you have added it.
3. On android in v1.6.1 their is a bug in the orientation firing. https://github.com/NativeScript/NativeScript/issues/1656 (Basically if you start in Landscape, rotate it won't detect it. The issue has the patch that I've applied manually to my code).
Now Looking at your actual example; are you aware that at least as of version 1.6.x of NativeScript it will only load the XML for which ever orientation it currently is set as; but it will NOT load the other orientation's xml when you rotate. So, if you are in Landscape; enter the screen then rotate it will still be using the Landscape xml file.
Now with all that said you might seriously consider looking at the nativescript-orientation plugin which I am the author of, this plugin simplifies dealing with screen orientation and allows you to only have ONE .xml file and then change things via css.

For those using angular2-nativescript typescript
Please refer to the on method found in the documentation
on(event: "orientationChanged", callback: function, thisArg?: any):
any Defined in application/application.d.ts:232 This event is raised
the orientation of the current device has changed.
Parameters
event: "orientationChanged"
callback: function
(args: OrientationChangedEventData): void Parameters
args: OrientationChangedEventData
Returns void Optional thisArg: any
Returns any
Example in use:
#Component({
selector: "Test"
//templateUrl, styleUrls, etc...
})
export class TestComponent{
constructor(){
on("orientationChanged", this.onOrientationChanged)
}
public onOrientationChanged = (evt) => {
console.log("Orientation has changed !");
console.log(evt.eventName); // orientationChanged
console.log(evt.newValue); //landscape or portrait
};
}

Related

Flash HTML5 canvas fl_MouseOverHandler

I'm quite new to Flash Actionscript & Javascript but I'm hoping to get some help here if possible. I'm creating a website using the canvas element, there is an image on the canvas and when you scroll over a part of that image, a movie clip plays, when you click on it, it takes you to another page.
I'm using flash to create it, but I'm having difficulty figuring out what's going wrong. I'm using code snippets to add in event handlers but I'm not getting the movie clip to play. The link to the page works but the mouse over event does not.
Also, my movie clip contains many layers, will this make a difference?
Any help would be greatly appreciated.
/* Stop a Movie Clip*/
this.movieClip_11.stop();
/* Mouse Over Event*/
var frequency = 3;
stage.enableMouseOver(frequency);
this.movieClip_11.addEventListener("mouseover", fl_MouseOverHandler_32);
function fl_MouseOverHandler_32()
{
this.movieClip_11.play();
}
/* Play a Movie Clip*/
/* Click to Go to Web Page*/
this.movieClip_11.addEventListener("click", fl_ClickToGoToWebPage_15);
function fl_ClickToGoToWebPage_15() {
window.open("___", "_self");
}
The problem is that javascript handles scope(i.e. this) differently to ActionScript. In AS3 you can assume that the event handler maintains the scope of its containing object. In JS this isn't the case. Here are a couple of solutions to this problem:
You can pass the scope to the event handler using the bind method. For example, this technique is utilized in the code snippets in Flash for HTML5 Canvas/Timeline Navigation/Click to Go to Frame and Play.
this.movieClip_11.stop();
var frequency=3;
stage.enableMouseOver(frequency);
this.movieClip_11.addEventListener("mouseover",
fl_MouseOverHandler_32.bind(this));
function fl_MouseOverHandler_32()
{
this.movieClip_11.play();
}
An alternative solution available in easeljs(the javascript library utilized by Flash for producing HTML canvas content) is achieved by calling the EventDispatcher method called on instead of addEventListener. easeljs docs Now the event handler assumes the scope of the object that dispatched the event.
this.movieClip_11.stop();
var frequency=3;
stage.enableMouseOver(frequency);
this.movieClip_11.on("rollover",fl_MouseOverHandler_32);
function fl_MouseOverHandler_32()
{
this.play();
}

Javascript: Changing "document.body.onresize" does not take hold without "console.log"

I'm writing a website with a canvas in it. The website has a script that runs successfully on every refresh except for a line at the end. When the script ends with:
document.body.onresize = function() {viewport.resizeCanvas()}
"document.body.onresize" is unchanged. (I double-checked in Chrome's javascript console: Entering "document.body.onresize" returns "undefined".)
However, when the script ends with:
document.body.onresize = function() {viewport.resizeCanvas()}
console.log(document.body.onresize)
"document.body.onresize" does change. The function works exactly as it should.
I can't explain why these two functionally identical pieces of code have different results. Can anyone help?
Edit: As far as I can tell, "document.body" is referring to the correct "document.body". When I call console.log(document.body) just before I assign document.body.onresize, the correct HTML is printed.
Edit 2: A solution (sort of)
When I substituted "window" for "document" the viewport's "resizeCanvas" function was called without fail every time I resized the window.
Why does "window" work while "document" only works if you call "console.log" first? Not a clue.
Resize events: no go
Most browsers don't support resize events on anything other than the window object. According to this page, only Opera supported detecting resizing documents. You can use the test page to quickly test it in multiple browsers. Another source that mentions a resize event on the body element specifically also notes that it doesn't work. If we look at these bug reports for Internet Explorer, we find out that having a resize event fire on arbitrary elements was an Internet Explorer-only feature, since removed.
Object.observe: maybe in the future
A more general method of figuring out changes to properties has been proposed and will most likely be implemented cross-browser: Object.observe(). You can observe any property for changes and run a function when that happens. This way, you can observe the element and when any property changes, such as clientWidth or clientHeight, you will get notified. It currently works only in Chrome with the experimental Javascript flag turned on. Plus, it is buggy. I could only get Chrome to notify me about properties that were changed inside Javascript, not properties that were changed by the browser. Experimental stuff; may or may not work in the future.
Current solution
Currently, you will have to do dirty checking: assign the value of the property that you want to watch to a variable and then check whether it has changed every 100 ms. For example, if you have the following HTML on a page:
<span id="editableSpan" contentEditable>Change me!</span>
And this script:
window.onload = function() {
function watch(obj, prop, func) {
var oldVal = null;
setInterval(function() {
var newVal = obj[prop];
if(oldVal != newVal) {
var oldValArg = oldVal;
oldVal = newVal;
func(newVal, oldValArg);
}
}, 100);
}
var span = document.querySelector('#editableSpan');
// add a watch on the offsetWidth property of the span element
watch(span, "offsetWidth", function(newVal, oldVal) {
console.log("width changed", oldVal, newVal);
});
}
This works similarly to Object.observe and for example the watch function in the AngularJS framework. It's not perfect, because with many such checks you will have a lot of code running every 100 ms. Additionally any action will be delayed 100 ms. You could possibly improve on this by using requestAnimationFrame instead of setInterval. That way, an update will be noticed whenever the browser redraws your webpage.
What you can do is that if you know for certain what particular action triggers a resize on your element that doesn't resize the full window you can trigger a resize event so your browser recalculate all of the divs (if by the case the browser is not triggering the event correctly).
With Jquery:
$(window).trigger('resize');
In the other hand, if you have an action that resizes an element you can always hold from that action to handle other following logic.
<script>
function body_OnResize() {
alert('resize');
}
</script>
<body onresize="body_OnResize()"></body>

iframe contents not appearing on screen even when checking for onload event javascript

We are trying to build an HTML game in which abobe edge is being used for animations and those animations are being inserted into iframes. We are trying to preload the iframes before removing the 'loading screen' so that the users won't see blank iframes initially.
Here is the code for loading the iframes.
We have a global variable var middleBotLoaded = false;
The following function tries to dynamically populate the iframe and once the iframe has loaded , we are assigning the variable to true
function _trackIFrameLoading()
{
if (document.getElementById("botzmiddleidlesequence_iframe").attachEvent)
{
document.getElementById("botzmiddleidlesequence_iframe").attachEvent("onload", function() { middleBotLoaded = true; });
}
else
{
document.getElementById("botzmiddleidlesequence_iframe").onload = function() { middleBotLoaded = true; };
}
document.getElementById("botzmiddleidlesequence_iframe").src = APP_BASE_URL + "blitzbotzidlesequence/blitzbotz/"+middleBotzId;
}
We have a method to check if the global variable has become true and if so , we are removing the loading screen.The method is being called in a interval of 500 milliseconds
setTimeout(_haveAllCharactersLoaded,500);
function _haveAllCharactersLoaded()
{
if(middleBotLoaded == true)
{
$(jOverlay).fadeOut(800, function() {
$(jOverlay).remove();
});
}
else
{
setTimeout(_haveAllCharactersLoaded,500);
}
}
The problem is that even after the loading screen disappears , the iframe contents take time to come up on the screen .
We have observed that the duration depends on the speed of the net connection , but then , isn't using onload the whole point of making sure that the contents have loaded.
Is there any other approach for dealing with this problem.
Thanks.
EDIT : I have to wait for two days before I can start a bounty but I am willing to award it to anyone who can provide a canonical answer to the question.
I have two answers here.
First, I think you should reconsider the way you're coding this game, unless it's a static, turn based game that only relies upon animations (think Pokemon.)
Second, I have a suggestion for you to try in fixing your code.
First Answer:
You asked if there is any other approach to dealing with this problem.
My first reaction to that, would be to skip using iFrames entirely. Adobe Edge may provide you with a good way to craft animations, but for use in a game engine you will only find yourself fighting against the design of how Adobe Edge handles it's animations.
Instead, I would recommend learning how to use HTML5's canvas element. Canvas is built to handle dynamically loaded content (such as your game engine will be generating.) I can only imagine the event of having particle effect animation overlayed onto a game character as he is hit by a weapon. With your current approach, would you place that in an iFrame? Then, how would you ensure that this particle effect is placed on the correct location on the object?
There are many resources out there to help you begin learning the code you need to make a true game engine in the browser. I would recommend beginning by learning how Canvas works. If you want to animate using the DOM, learn about requestAnimationFrame.
http://creativejs.com/
http://www.paulirish.com/2011/requestanimationframe-for-smart-animating/
https://developer.mozilla.org/en-US/docs/Web/Guide/HTML/Canvas_tutorial
Second Answer:
I would recommend looking into the variable scope of your middleBotLoaded. This answer (Set variable in parent window from iframe) would be a good place to look.
Instead of using document.getElementById("botzmiddleidlesequence_iframe").attachEvent("onload", function() { middleBotLoaded = true; });
try using document.getElementById("botzmiddleidlesequence_iframe").attachEvent("onload", function() { parent.middleBotLoaded = true; });
Alternatively, try something along these lines:
onLoad event:
document.getElementById("botzmiddleidlesequence_iframe").attachEvent("onload", function() { parent.middleBotLoaded();});
Function to handle loading:
function middleBotLoaded()
{
$(jOverlay).fadeOut(800, function() {
$(jOverlay).remove();
});
}
It's a better practice to directly call an event, rather than polling for variable changes using setTimeout.

Use Javascript to CTRL+ and CTRL- in Firefox & Chrome

I would like to give users the ability to increase/decrease the rendering size of the content inside of a web app.
The CTRL+ and CTRL- features (or CTRL1 through CTRL9) of Chrome & Firefox are handy - but is there a way from JavaScript to execute those features?
Clarification:
I want the user to be able to achieve this via mouse-clicks, not keypresses, so something like this:
function resize_rendering() {
// code that executes ctrl+ or crtl-
}
The browser zoom level is a user setting, which is there for accessiblity purposes; it's not intended for the site developer to ever know or care what the zoom level is, so I would expect that you'll have trouble doing exactly what you want. Certainly, it'll be hard to get it right in a way that works cross-browser.
The normal approach to this is to have a sizing gadget that changes the base font size.
If all the font sizes in your site are in em units, then you can change the sizes of all the text on the site with a single CSS change.
So you would have a set of buttons on the site which use Javascript to set the font-size of the <body> element to (for example) 12, 14, 16 or 18 pixels, depending on the element clicked.
There's a write-up of the technique here: http://labnol.blogspot.com/2006/12/allow-site-visitors-to-change-font.html
You are not allowed to by design. You can't change a user's browser setting via Javascript.
You can do other things, like modify all of the CSS on your page to scale everything down to simulate a CTRL-, but that's all.
In some browsers you can capture CTRL+/- before the browser does, allowing you to stop those events from occuring. But you cannot do the oppisite - you cannot cause those events to occur from your own script.
This library here by John Resig is a jQuery plugin that should do the job. There's some samples. Its quite easy to hookup combinations of keys as well.
You could intercept the keystroke in a general key event handler (such as on the window object), check to see if it's the one you're looking for, and if so, call stopPropagation() on the event parameter (and return false) to prevent the browser from then handling it on its own.
You'd then have to perform the sizing operation yourself, such as by modifying a stylesheet using JavaScript.
window.addEventListener( 'keydown', function( e ) {
if ( /* check e.keyCode etc. */ ) {
// modify global style to increase/decrease font size
e.stopPropagation();
return false;
} );
Look towards CSS property "zoom"
/* ctrl++ */
body {
zoom: 1.1;
}
For JS, it's like:
function resize_rendering(zoom) {
let currentZoom = parseFloat(document.body.style.zoom) || 1
document.body.style.zoom = currentZoom * zoom
}
resize_rendering(1.1) // ctrl++
resize_rendering(0.9) // ctrl+-

JavaScript & IE7 - Why won't my *.onload = function() { } fire?

I have a gallery I quickly coded up for a small site, and under Firefox 3 and Safari 3 works fine. But when I test on my old best friend IE7, it seems to not fire the imageVar.onload = function() { // code here }.. which I want to use to stop the load effect and load the image.
Please bear in mind...
I know the thumbnails are just scaled down version of the larger images. When the images are finalised by the client I am going to create proper thumbnails.
This is my first attempt to try and get out of procedural JavaScript for the most part.. so please go easy and kindly let me know where my code sucks!
For successful use of Image.onload, you must register the event handler method before the src attribute is set.
Related Information in this Question:
Javascript callback for Image Loading
Cross browser event support is not so straightforward due to implementation differences. Since you are using jQuery at your site, you are better off using its events methods to normalize browser support:
instead of:
window.load = function(){
//actions to be performed on window load
}
imageViewer.image.onload = function(){
//actions to be performed on image load
}
Do:
$(window).load(function(){
//actions to be performed on window load
});
$(imageViewer.image).load(function(){
//actions to be performed on image load
});
Just to add to the suggestion by Eran to use the jQuery's built in event handlers you can run code when the document is loaded and the DOM is created but before the images are downloaded with:
$(document).ready(function(){
//your code
});

Categories

Resources