Mobile - Browser addreds bar doesn't hide when scrolling with Ionic - web

When an Ionic App is deployed in the web and you access it from a phone, the bar address never dissapears. I know this is because of ion-content or something similar but I haven't found any work around or info about this, only an issue in github from Ionic 2.
Isn't there any work around to hide the browser address bar yet? This is a really downcoming to Ionic...

I did it in ionic5. But my solution removes navigation animation.
And not perfectly clean. But no one knows how to hide the mobile access bar.
So reveal my solution.
If you find a better solution, please let me know :)
in global.scss
//mobile access bar auto hide system
.plt-mobileweb {
ion-action-sheet {
position: fixed;
}
ion-modal {
position: fixed;
}
ion-picker {
position: fixed;
}
body {
max-height: initial;
height: initial;
overflow: scroll;
position: static;
overscroll-behavior-y: initial;
-webkit-overflow-scrolling: touch;
}
body.backdrop-no-scroll {
overflow: hidden;
}
ion-app.ion-page {
left: initial;
right: initial;
top: initial;
bottom: initial;
display: initial;
position: initial;
flex-direction: initial;
justify-content: initial;
contain: initial;
overflow: initial;
}
ion-router-outlet {
left: initial;
right: initial;
top: initial;
bottom: initial;
position: initial;
contain: initial;
z-index: initial;
overflow: initial;
}
ion-router-outlet {
.ion-page {
left: initial;
right: initial;
top: initial;
bottom: initial;
display: initial;
position: initial;
flex-direction: initial;
justify-content: initial;
contain: initial;
overflow: initial;
}
ion-header {
position: fixed;
top: 0;
left: 0;
right: 0;
z-index: 11;
}
ion-footer {
position: fixed;
left: 0;
right: 0;
bottom: 0;
z-index: 11;
}
ion-content {
display: initial;
position: initial;
width: initial;
height: initial;
font-family: var(--ion-font-family, inherit);
contain: initial;
flex: initial;
margin: initial;
padding: initial;
}
ion-tabs {
display: initial;
position: initial;
top: initial;
left: initial;
right: initial;
bottom: initial;
flex-direction: initial;
width: initial;
height: initial;
contain: initial;
z-index: initial;
}
div.tabs-inner {
position: initial;
flex: initial;
contain: initial;
padding-bottom: 56px;
}
ion-tab-bar {
width: 100%;
}
ion-tab-bar[slot=top] + div.tabs-inner {
padding-bottom: 0;
}
ion-tab-bar[slot=top] {
position: fixed;
top: 0;
left: 0;
right: 0;
}
ion-tab-bar[slot=bottom] {
position: fixed;
bottom: 0;
left: 0;
right: 0;
}
}
}
and make directive
#Directive({
selector: 'ion-content'
})
export class MobilewebContentDirective {
minHeight = {
ios: 50,
md: 56
}
constructor(
private el: ElementRef,
private plt: Platform
) {
}
ngOnInit() {
if(this.plt.is('mobileweb') || this.plt.is('desktop')) {
const observer = new MutationObserver(mutations => {
for(let i = 0; i < mutations.length; i++) {
const children = this.el.nativeElement.shadowRoot.children;
let main:HTMLElement | null = null;
let background:HTMLElement | null = null;
for(let i = 0; i < children.length; i++) {
if(children[i].tagName === 'MAIN') {
main = children[i];
}
if(children[i].id === 'background-content') {
background = children[i];
}
}
if(background) {
background.style.position = 'fixed';
}
if(main) {
//default setting for body scroll
observer.disconnect();
main.style.position = 'relative';
main.style.bottom = 'initial';
main.style.overflowY = 'hidden';
main.style.touchAction = 'manipulation';
main.style.width = '100%';
main.style.marginLeft = 'auto';
main.style.marginRight = 'auto';
const header = this.el.nativeElement.previousSibling;
const footer = this.el.nativeElement.nextSibling;
if(header) {
//header
main.style.marginTop = (this.plt.is('ios') ? this.minHeight.ios : this.minHeight.md) + 'px';
} else {
//tab (temperatory)
main.style.marginTop = (this.plt.is('ios') ? this.minHeight.ios : this.minHeight.md) + 'px';
}
if(footer) {
main.style.paddingBottom = (this.plt.is('ios') ? this.minHeight.ios : this.minHeight.md) + 'px';
}
//reset scroll (should add some more functions)
window.scrollTo(0, 0);
break;
}
}
});
observer.observe(this.el.nativeElement.shadowRoot, {childList: true});
}
}
}

Related

Change color of hamburger menu on hover/click

Let me just say that my knowledge in coding is very minimal. I am trying to figure out how to turn the hamburger menu from the current color to white when the cursor hovers it or when you click it. I hope that makes sense! It will be three white lines on a black background, so it will be visible.
I have tried adding color: #fff; but I think there needs to be some specific line of coding to actually change the hamburger menu on hover/click. I am unaware of this code.
Please let me know if I included the right CSS for what I am asking about! I added the custom js in case it is needed!
/* Header */
.header-wrap #logo {
display: table-cell;
vertical-align: middle;
width: 100%;
font-size: 2em;
text-align: center;
}
.header-wrap #logo #wsite-title {
font-size: inherit !important;
}
.header-wrap .wsite-logo {
padding: 0 50px;
}
.header-wrap .wsite-logo a img {
max-height: 40px;
}
.header-wrap .search {
display: none;
}
.header-wrap .nav-wrap {
position: fixed;
display: table;
background: #shade;
top: 0;
left: 0;
z-index: 15;
height: 55px;
-webkit-transition: all 610ms cubic-bezier(0, 0.8, 0.55, 1);
-moz-transition: all 610ms cubic-bezier(0, 0.8, 0.55, 1);
-ms-transition: all 610ms cubic-bezier(0, 0.8, 0.55, 1);
-o-transition: all 610ms cubic-bezier(0, 0.8, 0.55, 1);
transition: all 610ms cubic-bezier(0, 0.8, 0.55, 1);
}
.header-wrap .nav-wrap ul {
padding: 0 4em;
}
.header-wrap .hamburger {
position: absolute;
top: 0;
right: 0;
display: block;
width: 30px;
height: 30px;
padding: 10px;
cursor: pointer;
}
.header-wrap .hamburger span,
.header-wrap .hamburger span:before,
.header-wrap .hamburger span:after {
position: relative;
display: block;
width: 20px;
height: 2px;
background: #color;
content: '';
}
.header-wrap .hamburger span {
top: 10px;
left: 4px;
margin: 6px 0;
}
.header-wrap .hamburger span:before {
top: -8px;
}
.header-wrap .hamburger span:after {
bottom: -6px;
}
jQuery(function($) {
// Mobile sidebars
$.fn.expandableSidebar = function(expandedClass) {
var $me = this;
$me.on('click', function() {
if(!$me.hasClass(expandedClass)) {
$me.addClass(expandedClass);
} else {
$me.removeClass(expandedClass);
}
});
}
var haberdasherController = {
init: function(opts) {
var base = this;
// Add classes to elements
base._attachEvents();
setTimeout(function(){
base._addClasses();
base._checkCartItems();
}, 1000);
},
_addClasses: function() {
var base = this;
// Add placeholder text to inputs
$('.wsite-form-sublabel').each(function(){
var sublabel = $(this).text();
$(this).prev('.wsite-form-input').attr('placeholder', sublabel);
});
// Add fullwidth class to gallery thumbs if less than 6
$('.imageGallery').each(function(){
if ($(this).children('div').length <= 6) {
$(this).children('div').addClass('fullwidth-mobile');
}
});
},
_stickyFooter: function() {
var stickyFooterMargin = $('#footer-wrap').height();
$('.wrapper').css('margin-bottom', -stickyFooterMargin);
$('#footer-wrap, .sticky-footer-push').css('height', stickyFooterMargin);
},
_checkCartItems: function() {
var base = this;
if($('#wsite-mini-cart').find('li.wsite-product-item').length > 0) {
$('#wsite-mini-cart').addClass('full');
base.cartHasItems = true;
} else {
$('#wsite-mini-cart').removeClass('full');
base.cartHasItems = false;
}
},
_attachEvents: function() {
var base = this;
$('.hamburger').on('click', function(e) {
e.preventDefault();
$('body').toggleClass('nav-open');
});
// Pad header on mobile
setTimeout(function(){
if($(window).width() < 992) {
$(".banner-wrap").css({"padding-top" : $(".header-wrap > .nav-wrap").height() + "px"});
}
}, 800);
// Copy login and search to mobile nav
var login = $("#member-login").clone(true),
search = $("#wsite-header-search-form").clone(true)
$("#navmobile .wsite-menu-default").append(login).append(search);
// Menu text alignment
if($('.search').is(':empty') || $('.search').css('display') == 'none') {
$('.menu').css('text-align', 'center');
}
// Store category dropdown
$('.wsite-com-sidebar').expandableSidebar('sidebar-expanded');
// Search filters dropdown
$('#wsite-search-sidebar').expandableSidebar('sidebar-expanded');
// Init fancybox swipe on mobile
if('ontouchstart' in window) {
$('body').on('click', 'a.w-fancybox', function() {
base._initSwipeGallery();
});
}
// Init sticky footer
if($(window).width() > 992) {
base._stickyFooter();
}
},
_initSwipeGallery: function() {
var base = this;
setTimeout(function(){
var touchGallery = document.getElementsByClassName('fancybox-wrap')[0];
var mc = new Hammer(touchGallery);
mc.on("panleft panright", function(ev) {
if (ev.type == "panleft") {
$("a.fancybox-next").trigger("click");
} else if (ev.type == "panright") {
$("a.fancybox-prev").trigger("click");
}
base._initSwipeGallery();
});
}, 500);
}
}
$(document).ready(function(){
haberdasherController.init();
});
});

Soft keyboard pushes my background image up in mobile

I'm using styled components to put a background image on my react app. I have a background container and also a background component to create a background image with some gradient of some sort. My problem is when I go open my site in mobile view and bring up the soft keyboard, it pushes the background image up which can get annoying after a while.
const BackgroundContainer = styled.div`
-blur-radius: 20px;
position: absolute;
width: 100%;
height: 60vh;
top: 0;
left: 0;
right: 0;
bottom: 0;
overflow: hidden;
background: #6e7290;
z-index: -1;
&:after {
--color-background--rgb: 103, 103, 171;
content: "";
position: absolute;
height: 50%;
left: 0;
right: 0;
bottom: 0;
background: transparent;
background: linear-gradient(
0deg,
rgba(var(--color-background--rgb), 1) 0,
rgba(var(--color-background--rgb), 0.987) 8.1%,
rgba(var(--color-background--rgb), 0.951) 15.5%,
rgba(var(--color-background--rgb), 0.896) 22.5%,
rgba(var(--color-background--rgb), 0.825) 29%,
rgba(var(--color-background--rgb), 0.741) 35.3%,
rgba(var(--color-background--rgb), 0.648) 41.2%,
rgba(var(--color-background--rgb), 0.55) 47.1%,
rgba(var(--color-background--rgb), 0.45) 52.9%,
rgba(var(--color-background--rgb), 0.352) 58.8%,
rgba(var(--color-background--rgb), 0.259) 64.7%,
rgba(var(--color-background--rgb), 0.175) 71%,
rgba(var(--color-background--rgb), 0.104) 77.5%,
rgba(var(--color-background--rgb), 0.049) 84.5%,
rgba(var(--color-background--rgb), 0.013) 91.9%,
rgba(var(--color-background--rgb), 0)
);
}
`;
const Background = styled.div`
--blur-radius: 20px;
background-image: url(${reviewssw[0].Image});
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
margin: calc(var(--blur-radius) * -1) calc(var(--blur-radius) * -1);
background-size: cover;
background-position: 50%;
mix-blend-mode: overlay;
filter: blur(var(--blur-radius));
`;

Using flex-box with Slick-carousel, width = 0 & first slide is hidden

When first loading the slick-carousel while using flex-boxes, the width of the slick-slide and the slick-track are set to 0 which hides the first slide until it triggers the next slide. If there is only one slide, it's hidden and will never show unless the window is manually resized.
First wrap your carousel with a container:
.myContainer {
position: fixed;
top: 0;
left: 0;
height: 100%;
width:100%;
}
<div class="myContainer">
<div class="myCarousel" (click)="navigate()"></div>
</div>
Next, be sure is to have min-height & min-width set to 0 for the .slick-slider.
CSS:
note the changes from the default slick-carousel styles are commented
// new definition
.slick-slider {
min-height: 1px;
min-width: 1px;
}
.slick-slide {
float: left;
[dir="rtl"] {
float: right;
}
img {
display: block;
}
&.slick-loading img {
display: none;
}
display: none;
&.dragging img {
pointer-events: none;
}
.slick-initialized {
display: block;
// set height and width
height: 100%; // helps to fix the loading issue when using flex-box - stretches slide vertically
width: 100% !important; // helps to fix the loading issue when using flex-box - shows slide upon load
}
.slick-loading {
visibility: hidden;
}
.slick-vertical {
display: block;
height: auto;
border: 1px solid transparent;
}
}
.slick-track {
position: relative;
left: 0;
top: 0;
display: block;
// set height
width: 100% !important; // helps to fix the loading issue when using flex-box
&:before,
&:after {
content: "";
display: table;
}
&:after {
clear: both;
}
.slick-loading {
visibility: hidden;
}
}
.slick-initialized {
display: block;
// set height and width
height: 100%; // helps to fix the loading issue when using flex-box - stretches slide vertically
width: 100% !important; // helps to fix the loading issue when using flex-box - shows slide upon load
}
.slick-loading {
visibility: hidden;
}
.slick-vertical {
display: block;
height: auto;
border: 1px solid transparent;
}
Finally, make sure you have defined the responsive setting when initializing your slick-slider:
// initialize carousel
private initializeCarouselSettings(){
this.carousel.slick({
accessibility: false,
autoplay: false,
arrows: false,
slidesToShow: 1,
pauseOnHover: false,
pauseOnFocus: false,
draggable: false,
swipe: false,
touchMove: false,
centerMode: true,
fade: this.isTransitionTypeFade(),
autoplaySpeed: this.getSlideInterval(),
speed: this.getSpeedValue(),
responsive: [ // fixes the loading issue when using flex-box
{
breakpoint: 1024,
settings: {
mobileFirst: false,
infinite: true,
speed: this.getSpeedValue(),
slidesToShow: 1,
centerMode: true,
variableWidth: false,
focusOnSelect: false
}
}
]
});
}

Write state name on svg map using jqv map

I have created USA states map using jqvmap
. See
jqvmap.com
I want to write state names in middle of map like image below.
I have tried using pseudo elements but its not working.
This is my code.
jQuery(document).ready(function () {
jQuery('#vmap').vectorMap({
map: 'usa_en',
enableZoom: false,
showTooltip: true,
backgroundColor: '#D9D9D9',
color: '#009F45',
borderColor: '#ffffff',
borderOpacity: 0.25,
borderWidth: 2,
hoverColor: '#999999',
selectedColor: '#0077aa',
selectedRegion: 'MO',
onRegionClick: function (element, code, region)
{
var message = 'You clicked "'
+ region
+ '" which has the code: '
+ code.toUpperCase();
alert(message);
}
});
});
/*!
* jQVMap Version 1.0
*
* http://jqvmap.com
*
* Copyright 2012, Peter Schmalfeldt <manifestinteractive#gmail.com>
* Licensed under the MIT license.
*
* Fork Me # https://github.com/manifestinteractive/jqvmap
*/
.jqvmap-label
{
position: absolute;
display: none;
-webkit-border-radius: 3px;
-moz-border-radius: 3px;
border-radius: 3px;
background: #292929;
color: white;
font-family: sans-serif, Verdana;
font-size: smaller;
padding: 3px;
}
.jqvmap-zoomin, .jqvmap-zoomout
{
position: absolute;
left: 10px;
-webkit-border-radius: 3px;
-moz-border-radius: 3px;
border-radius: 3px;
background: #000000;
padding: 3px;
color: white;
width: 10px;
height: 10px;
cursor: pointer;
line-height: 10px;
text-align: center;
}
.jqvmap-zoomin
{
top: 10px;
}
.jqvmap-zoomout
{
top: 30px;
}
.jqvmap-region
{
cursor: pointer;
}
.jqvmap-ajax_response
{
width: 100%;
height: 500px;
}
/*Colors of state*/
path#jqvmap1_nj{
fill:#7AC37A;
}
path#jqvmap1_tn{
fill:#7AC37A;
}
path#jqvmap1_in{
fill:#7AC37A;
}
path#jqvmap1_co{
fill:#7AC37A;
}
path#jqvmap1_ca{
fill:#026E38;
}
path#jqvmap1_ca:after{
content:'ca';
position: absolute;
top: 0;
color:#fff;
}
path#jqvmap1_ak{
fill:#6E6F73;
}
path#jqvmap1_tx{
fill:#6E6F73;
}
path#jqvmap1_ar{
fill:#6E6F73;
}
path#jqvmap1_la{
fill:#6E6F73;
}
path#jqvmap1_al{
fill:#6E6F73;
}
path#jqvmap1_nh{
fill:#6E6F73;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.0.0/jquery.min.js"></script>
<script src="https://jqvmap.com/js/vmap/jquery.vmap.js"></script>
<script src="https://jqvmap.com/js/vmap/jquery.vmap.usa.js"></script>
<div id="vmap" style="width: 600px; height: 400px;"></div>
First, there is no built-in parameter in jqvmap to add the states code.
Finding a good position for this labels is not a trivial task. For example, Florida's shape is not convex, Michigan has two parts.
Some questions related on stackexchange network:
- Algorithm for finding irrregular polygon centroid (label point)
- How to split compound polygons into convex polygons?
- Partitioning a polygon into convex parts
So, I tried to place them with a dummy algorithm, which places the state code at a kind of centroid of state shapes.
Then, you can move them as you want, and use the positions you have set.
Here is the main function which compute the centroid of a SVG path:
//svgPathParser => browserified version of
// https://github.com/hughsk/svg-path-parser
var parsedPath= svgPathParser(path);
// pathes in jqvmap are, for the most of them, in the form of [ start Point, [ curves ] ]
// if you want better results it is possible to refine that.
var origin= { x: parsedPath[0].x, y: parsedPath[0].y };
var pathPartCentroids= [];
var totalLength= 0;
for( var i=1; i< parsedPath.length - 1; i++){
var pathPart= parsedPath[i];
if(pathPart.code !="c")
break;
//centroidOfPathPart returns the centroid of a Bezier curve.
var pathPartCentroid= centroidOfPathPart([ [0,0], [ pathPart.x1, pathPart.y1 ], [ pathPart.x2, pathPart.y2 ], [ pathPart.x, pathPart.y ] ]);
pathPartCentroid.x += origin.x;
pathPartCentroid.y += origin.y;
pathPartCentroid={ centroid: pathPartCentroid, distance: norm( pathPartCentroid, origin) }
pathPartCentroids.push(pathPartCentroid);
totalLength+= pathPartCentroid.distance;
origin.x+= pathPart.x;
origin.y+= pathPart.y;
}
var centroid= {x:0,y:0};
//segments are weighted by their length
pathPartCentroids.forEach(function( pathPart ){
centroid.x += pathPart.centroid.x * pathPart.distance / totalLength;
centroid.y += pathPart.centroid.y * pathPart.distance / totalLength;
});
You can edit position with this pen.
Then use that another one to add state codes in a map.

LESS mixin as function parameter

..................................................
Existing mixins:
.mixin_1 {
height: 1px;
}
.mixin_2 {
height: 2px;
}
.mixin_3 {
height: 3px;
}
.function(#get) {
#get();
}
CALL:
.a{
.function(mixin_1);
}
.b{
.function(mixin_2);
}
.c{
.function(mixin_3);
}
RESULT:
.a{
height: 1px;
}
.b{
height: 2px;
}
.c{
height: 3px;
}
Question: how to do this? It's possible with current language specifications?
You cannot currently do a dynamic call to a mixin based off a variable directly. You can make your function() mixin into a "caller" or "getter" mixin in which you register the mixins that can be called by your function() mixin, like so (which utilizes pattern matching):
LESS
.function(#get) {
.-(#get); //call for mixin
//register mixins you want to call with function
.-(mixin_1) { .mixin_1; }
.-(mixin_2) { .mixin_2; }
}
.mixin_1 {
height: 1px;
}
.mixin_2 {
height: 2px;
}
#block {
.function(mixin_1);
}
Outputs
.mixin_1 {
height: 1px;
}
.mixin_2 {
height: 2px;
}
#block {
height: 1px;
}
Of course, if you want the mixins invisible to the css, then change them to this:
LESS change (added parenthesis)
.mixin_1() {
height: 1px;
}
.mixin_2() {
height: 2px;
}
New Output
#block {
height: 1px;
}
Do you need it?
That level of abstraction can be useful at times, but often simply a pattern matching on the mixins will suffice. You would have to determine that. So with this simple example, it would be better to reduce to something like this:
.setHeight(1) {
height: 1px;
}
.setHeight(2) {
height: 2px;
}
#block {
.setHeight(1);
}
More complex examples of mixins may not be so easily reduced, and then a mixin like what you want may be useful.
I think your code do same thing like this:
.mixin_1() {
height: 1px;
}
.mixin_2() {
height: 2px;
}
#block {
.mixin_1();
}
And output will be:
#block {
height: 1px;
}
I was asking about little different thing. However I found solution:
.function(#get) {
.-(#get); //call for mixin
//register mixins you want to call with function
.-(mixin) { .mixin; }
}
#block {
.mixin() {
height: 1px;
}
.function(mixin);
}
#block {
.mixin() {
height: 2px;
}
.function(mixin);
}
It outputs exactly what i wanted:
#block {
height: 1px;
}
#block {
height: 2px;
}
Overall, thanks for help.

Resources