Handle website scroll offset based on mobile screen size - javascript

I need to make this div visible if can scroll to left ,
<div class="fade-left" [class.visible]="showFadeLeft()"></div>
public showFadeLeft() {
return this.boxToolbarElement.nativeElement.scrollWidth -
Math.abs(this.boxToolbarElement.nativeElement.scrollLeft) !==
this.boxToolbarElement.nativeElement.clientWidth;
}
this.boxToolbarElement is the container of overflowing content .
The problem is when I open site in mobile the "fade-left" div be always shown , because display size (screen zoom) make "showFadeLeft() method" return different values , how can I handle any screen size .

NOTE: you should never use a FUNCTION inside HTML. It may cause some side effects and will decrease your application performance.
Solution
<div class="fade-left" [class.visible]="isVisible"></div>
App.component.ts
isVisible = false; // initial value can be false or tru;
ngAfterViewInit(){ // This life cycle hook will make sure that nativeElement is available for further operation.
this.showFadeLeft();
}
private showFadeLeft() { // Added private keyword
this.isVisible = this.boxToolbarElement.nativeElement.scrollWidth -
Math.abs(this.boxToolbarElement.nativeElement.scrollLeft) !==
this.boxToolbarElement.nativeElement.clientWidth;
}

Related

Navbar which hides when you scroll down and appears again when you scroll up

I have explored few approaches to this, but none really seems to work exactly like I would like:
I would like that when scrolling down, navbar is moving up at the speed the user is scrolling down, like that is static at that point.
When it disappears, I would like that the bottom of it is still visible, because this is where I have a progress bar (but maybe progress bar should detach at that point and be on top of the viewport).
When you scroll up, I would like that navbar appears again, again at the speed of scrolling, like it is static, until you see the whole navbar, when it should stick to the top of the viewport.
Here is an example of behavior I would like, but not performance/experience (because behavior is implemented using scroll event, it is not smooth).
I have also attempted to use CSS transform, which would on scroll down add a class to hide the navbar, and scroll up remove the class, animating the navbar hiding/showing, but the issue with that is that animation speed is disconnected with scrolling speed.
I tried CSS sticky position as well, but it looks like I need the opposite of what it provides.
Is there some other way to make this work well?
I've looked at your problem and I think i found a simple approach.
with this simple function you can get the amount of pixels user has scrolled.
window.onscroll = function (e) {
console.log(window.scrollY); // Value of scroll Y in px
};
after user scrolls the desired amount of pixels, make the progress bar fixed top ( or position:fixed;top:0)
Checking the link you provided, it seems to work as expected (you want it to be linked to the scroll event since you want it to move as "static"). If, though, it staggers on some system due to inconsistent scroll events, you could try adding a transition property with a small enough duration. Keep in mind the this should only be enabled while the position property remains the same, otherwise when changing from "absolute" to "fixed" it would mess things up, since the coordinate origin changes.
So you can add another variable let changedPosition = false; and whenever you change the position property you can do
if (position !== "absolute") {
changedPosition = true;
} else {
changedPosition = false;
}
position = "absolute";
or
if (position !== "fixed") {
changedPosition = true;
} else {
changedPosition = false;
}
position = "fixed";
and when you apply the style do
navbar.style = `position: ${position}; top: ${navbarTop}px; transitiona: ${
changedPosition ? "none" : "100ms linear"
}`;
like https://codepen.io/gpetrioli/pen/XWVKxNG?editors=0010
You should play around a bit with the transition properties you provide, i just put some sample values there.

Prevent javascript from running when screen width is less or more than

I have 2 menus that are contained on the same page but in different locations. One appears when I have screen width > 555px and the parent div is set as display:none when under this size. The other is display:none when 555px or over and shows when less than 555px. Its the same menu but one is on a different section of the page for mobile/smaller screens.
I have javascript on some of the drop down options on the menu and it works for the first menu but not the second, I believe because the js is still attempting to run for the display:none so on the second attempt (on the small screens) it doesn't work.
I'm probably over-complicating what needs to be done but I've attempted to create some code that uses js to create the div that contains the menu code for desktop and mobile and removes them when it shouldn't... so a media query version controlled by js rather than css that rather than hide the div and content will actually make it not be present.
I'm a complete novice at javascript and have just attempted to adapt other code I've seen, basically all I want to do is when >555px browser width add and when it moves under remove then I can use the same code down the page to add/remove div id="y"...
function DynamicDiv() {
var dynDiv = document.createElement("div");
dynDiv.id = "search-holder1";
dynDiv.innerHTML = "Created using JavaScript";
document.body.appendChild(dynDiv);
}
var elem = document.getElementById("search-holder1");
function myFunction(x) {
if (x.matches) { // If media query matches
DynamicDiv();
} else {
elem.parentNode.removeChild(elem);
}
}
var x = window.matchMedia("(max-width: 555px)")
myFunction(x) // Call listener function at run time
x.addListener(myFunction) // Attach listener function on state changes
Here is my way:
function chooseMenu() {
var width = window.innerWidth;
if (width > 555) {
//Add your div
else {
//If div is in document then remove, and add mobile div
}
}
window.onresize = chooseMenu;
You should probably do the same function at the beggining with an anonymous function too.

Scrolling into view an element hidden beneath a persistent header

I'm currently working under some tight restrictions with regard to what I can do with JavaScript (no frameworks such as jQuery for example, and nothing post Firefox 2.0).
Here's my problem; I have a persistent header floating at the top of the page. I have input elements scattered throughout (we're replicating a paper form exactly, including the background image). There is a field nearing the bottom of the page that gets tabbed out (using keyboard tab button) and puts the focus on a field at the top of the page. Firefox will automatically scroll the field "into view". However, while the browser believes the field is in view, it's actually hidden beneath the persistent header.
http://imageshack.us/a/img546/5561/scrollintoviewproblem.png
The blue field above is accessed by hitting "tab" from another location on the page. The browser believes the field has been scrolled into view, but it's in fact hidden beneath the floating persistent header.
What I'm looking for is ideas as to how I can detect that the field is beneath this header and scroll the entire page accordingly.
I've tried a few variations of margin & padding (see other considerations at http://code.stephenmorley.org/javascript/detachable-navigation/#considerations) without luck. I've also tried calling the JavaScript function "scrollIntoView(element)" each time we focus on a field, but given the amount of fields on the form (and the fact that we're aligning them to match the background image of a paper form exactly), this was causing some pretty severe "jumping" behavior when tabbing through fields close to each other that were at slightly different heights.
I can change how the persistent header is done, so long as it doesn't require too much effort. Unfortunately, frames are out of the question because we need to interact with the page content from the persistent header.
Ideally the solution would be in CSS, but I'm open to JavaScript if it solves my problem.
Another note, we require that the input elements have a background color, which means that adding padding to them would make the background color stretch, which hides parts of the background image. BUT, the input elements are in a div, so we might be able to use this to our advantage.
So after doing some more searching (thanks to #Kraz for leading on this route with the scrollTo() suggestion) I've found a solution that works for me.
I've added an onFocus call to each element dynamically, so they always call the scrollScreenArea(element) function, which determines if they're hidden beneath the top header or too close to the footer area (this solves another problem entirely, using the same solution).
/* This function finds an element's position relative to the top of the viewable area */
function findPosFromTop(node) {
var curtop = 0;
var curtopscroll = 0;
if (node.offsetParent) {
do {
curtop += node.offsetTop;
curtopscroll = window.scrollY;
} while (node = node.offsetParent);
}
return (curtop - curtopscroll);
}
/* This function scrolls the page to ensure that elements are
always in the viewable area */
function scrollScreenArea(el)
{
var topOffset = 200; //reserved space (in px) for header
var bottomOffset = 30; //amount of space to leave at bottom
var position = findPosFromTop(el);
//if hidden beneath header, scroll into view
if (position < topOffset)
{
// to scroll up use a negative number
scrollTo(el.offsetLeft,position-topOffset);
}
//if too close to bottom of view screen, scroll into view
else if ((position + bottomOffset) > window.innerHeight)
{
scrollTo(0,window.scrollY+bottomOffset);
}
}
Let me know if you have any questions. Thanks #Kraz for sending me onto this solution.
As well, I'd like to reference Can I detect the user viewable area on the browser? since I took some code from there and that partially described my problem (with a neat diagram to boot).
The easiest method for doing this will be listening for each element's focus event and then seeing if it is on the page. In pure JS, it is something like:
var input = Array.prototype.slice.call(document.getElementsByTagName('input'));
for ( var i in input )
input[i].addEventListener( 'focus', function (e) {
var diff = 150 /* Header height */ - e.target.getBoundingClientRect().top;
if ( diff > 0 ) {
document.body.scrollTop += diff;
document.documentElement && document.documentElement.scrollTop += diff;
}
}, false );
I didn't include the IE addEvent method, but it should be pretty easy to make that on your own given this base.

How to create a dynamic navigation bar which follows you when you reach certain location

I want to create a navigation bar similar to this site's:
http://www.mysupermarket.co.uk/#/shelves/top_offers_in_asda.html
Can anyone tell me how to create that navigation bar, which follows you as you scroll the page down, but not following you at the initial loading of page?
When you access to the given website, try to scrolling down and you will understand what I am talking about. The navigation bar that consists of MY SHOP, OFFERS, IDEAS & LIFESTYLE, BAKERY and so-on...
I have really no idea what it's called. At least tell me what it's called, so I'll be able to search.
Here is the solution I've done
window.onscroll = function(){
if(getScrollTop()>140) {
document.getElementById("menu").style.position="fixed";
} else {
document.getElementById("menu").style.position="";
}
}
function getScrollTop() {
if (window.onscroll) {
// Most browsers
return window.pageYOffset;
}
var d = document.documentElement;
if (d.clientHeight) {
// IE in standards mode
return d.scrollTop;
}
// IE in quirks mode
return document.body.scrollTop;
}
Holding an element on same position can be achieved by fixed position styling.
If you want your navigation bar to stay on exact same location, position:fixed; is enough. (At least non IE6)
You can find a working example and some details here
However, if you want your navigation bar to move from it's initial location to the top border of page as you scroll the page down, you must implement some JavaScript to catch page scroll event and move the <div> accordingly.
See this question for an example on how to do that.
Note: this won't work with the Android 2.3 browser; position:fixed will not behave as expected - it kinda of temporarily attaches its position to the scrolling element before jumping back to the top.
if you want you could just set the z-index to be a specific No. and that should work.
example
z-index:100;

How can I size a .swf to full screen with .js

My application is built in Flash Builder. I want to embed a small Flash login form inside an HTML page. The login form is in the 'login' state of code and is a few hundred pizxels wide/ tall. The 'default' state is set to height and width of 100%. I have a resize function that is executed once the login receives the appropriate credentials.
private function resizeApplication():void {
if(ExternalInterface.available) {
ExternalInterface.call("resizeApplication");
}
The javascript that does the resizing is this:
function resizeApplication() {
var app = document.getElementById('app');
app.style.height = '100%';
app.style.width = '100%';
app.style.left = '0';
app.style.top = '0';}
#app is the div and overflow is set to auto in the body. This works just fine except that I am left with some visable portion of the webpage near the bottom. I want to be able to either resize the webpage to match the swf or hide everything except the swf. I have tried a few different things with the js including setting the bottom attribute to 0 and using variations of the document.body.clientHeight.
You can't make it "Full Screen" but you can make it fill the browser.
First the app element should have the position style pre-set to either fixed or absolute(depending on your page) since setting it from the script will reload the flash object.
And then use this one if the position is fixed:
app.style.top = '0';
app.style.left = '0px';
app.style.top = '0px';
app.style.right = '0px';
app.style.bottom = '0px';
And this for absolute find out the position of the viewport and it's size and just move and resize your app element.
http://www.softcomplex.com/docs/get_window_size_and_scrollbar_position.html
Either way wouldn't it be a lot easier for you if you just made the flash fullscreen from ActipnScript?
fscommand("fullscreen", "true"); // ActionScript 2
stage.displayState = StageDisplayState.FULL_SCREEN; // ActionScript 3
You have to set the height of the div manually to consistently get the effect you are looking for. This is the same trick used to make a background image always fill the screen.
Something like this:
function resizeMain(){
$("#wrapper").height(window.innerHeight);
$("#background").height(window.innerHeight);
$("#background").width(window.innerWidth);
}
window.onresize = resizeMain;
$(document).ready(function(){resizeMain();});
Why not simply enter real full screen mode using
StageDisplayState.FULL_SCREEN

Categories

Resources