How to remove flicking in IE? - javascript

I have created this fiddle where I have flicking problem in IE. Even Chrome isnt good, but in fiddle it looks more or less fine. I think problem is in "size of step" for one scroll, when you grab scroller manualy everything is smooth, but using your mousewheel leads to jumping/flicking in IE and Chrome.
window.addEventListener('scroll', function() { ...}, false);
This is my current HTML:
<div id="fakeBody">
<div id="spacer">scroll down</div>
<div class="niceBanner hide roller" id="niceBannerFrame">
<div id="bannerShadow"></div>
<div id="thumb0">
<div id="niceBannerOriginal" class="roller thumb1 thumb2"></div>
<div id="niceBannerBlur" class="roller deblur thumb1 thumb2"></div>
<div id="blackRow"></div>
</div>
</div>
</div>
Script:
window.addEventListener('scroll', function () {
var totalHeigth, currentScroll, visibleHeight;
var newResolutionBannerHeight = 0;
currentScroll = (document.documentElement.scrollTop) ? document.documentElement.scrollTop : document.body.scrollTop;
totalHeigth = (document.height !== undefined) ? document.height : document.getElementById("fakeBody").offsetHeight;
visibleHeight = document.documentElement.clientHeight;
var w = window,
d = document,
e = d.documentElement,
g = d.getElementsByTagName('body')[0],
x = w.innerWidth || e.clientWidth || g.clientWidth,
y = w.innerHeight || e.clientHeight || g.clientHeight;
var curentWidth = x;
console.log('curent Width: ' + curentWidth);
if (curentWidth < 1070) {
var newBannerWidth = Math.round((curentWidth / 1070) * 1920);
var newMargin = Math.round((newBannerWidth - curentWidth) / 2);
newResolutionBannerHeight = Math.round((500 / 1920) * newBannerWidth);
} else {}
//now it is easy to recognize if visitor is at the bottom of page
if (visibleHeight + currentScroll >= totalHeigth) {
//do the magic with banner
document.getElementById("niceBannerFrame").className = "unhide";
var bannerHeight = visibleHeight + currentScroll - totalHeigth;
var style = document.createElement('style');
style.type = 'text/css';
var number = (curentWidth < 500) ? 10 + bannerHeight : 50 + bannerHeight; //not ideal solution, slower rolling for small screen, picture is realy small
if (curentWidth > 1070) {
number = (number > 500) ? 500 : number;
var opacityBlur = 1 - (number / 500);
style.innerHTML = '.roller {bottom:-' + number + 'px;} .deblur {opacity:' + opacityBlur + ';} .thumb2{height: 500px;} ';
} else {
number = (number > newResolutionBannerHeight) ? newResolutionBannerHeight : number;
var opacityBlur = 1 - (number / newResolutionBannerHeight);
style.innerHTML = '.roller {bottom:-' + number + 'px;} .deblur {opacity:' + opacityBlur + ';} .thumb2{height:' + newResolutionBannerHeight + 'px;} ';
}
document.head.appendChild(style);
} else {
//it is not good time for magic, scroll a bit more or I will hide already visible bilboard
document.getElementById("niceBannerFrame").className = "hide";
}
}, false);
and CSS:
#spacer {
height: 1000px;
background-color: whitesmoke;
}
#niceBannerOriginal {
background-image:url(http://nzworker.com/jakub-portfolio/justfiles/1920x500_original.jpg);
position: absolute;
z-index:-3;
}
#niceBannerBlur {
background-image:url(http://nzworker.com/jakub-portfolio/justfiles/1920x500_blur.jpg);
position: absolute;
z-index:-2;
}
#bannerShadow {
position:absolute;
background-image:url(http://nzworker.com/jakub-portfolio/justfiles/Stin.png);
background-repeat:repeat-x;
width:100%;
z-index:-1;
height:25px;
}
.hide {
display: none;
}
.unhide {
display: block;
}
#fakeBody {
height:1000px;
position:relative;
top:0;
left:0;
right:0;
}
#blackRow {
display:none;
}
#niceBannerFrame {
overflow: hidden;
}
#media (min-width: 1921px) {
#blackRow {
background-color: #000000;
display: block;
height:500px;
position: absolute;
width: 100%;
z-index: -6;
}
}
/*desktop resolution*/
#media (min-width: 1070px) and (max-width: 1920px) {
.thumb1 {
width: 100%;
height: 500px;
background-position: 50% 50%;
/*image centering*/
}
.thumb2 {
}
}
/*mobile and tablet resolution*/
#media (max-width: 1069px) {
.thumb2 {
width: 100%;
height: 500px;
background-repeat:no-repeat;
/*background-position: 50% 50%; image centering*/
}
#niceBannerOriginal {
background-image:url(http://nzworker.com/jakub-portfolio/justfiles/1920x500_original-thumb.jpg);
background-size: 100%;
}
#niceBannerBlur {
background-image:url(http://nzworker.com/jakub-portfolio/justfiles/1920x500_blur-thumb.jpg);
background-size: 100%;
}
}
My question is do you how to remove this flicking? Or do you know how to cut one mouse wheel step to more smaller ones?
PS: I can not use jQuery or other plugins.

I can't be 100% sure about this, but I think the flickering isn't from the amount you're scrolling, but due to the fact that you're changing the display mode, and pushing the view back up a tiny bit.
Essentially if you are just underneath the visibleHeight+currentScroll >= totalHeigth test by a couple of pixels, then currentScroll get's pushed up a tiny bit when whatever happens in there happens (I don't entirely understand what's going on, so I can't really give any better advice on that), so that it's no longer greater than totalHigth, and so it then fails the test immediately after, hence the flickering.
Worked this out by getting rid of the hide line at the end and it seems to work. Unfortunately I don't entirely understand the code, so I can't give you any better idea than that, though hopefully it points you towards a solution.

Related

element not appends in body on window onload

I have been created the function which detects the screen zoom-in or zoom-out function. I am trying if window zoom == 100 or is in normal size the notification will remove else it append instantly.
In my code, it's working perfectly but it not working on window load, for showing the demo and result I have to click ctrl+ or ctrl-.
I am trying as window load it auto decide and append if window zoom, not 100 or normal.
Please help me with how I fix this?
function informationbar(percentage, zoomstatus) {
$("body").append('<div id="informationbar" style="top: 0px;"><img src="#" style="width: 14px; height: 14px; float: right; border: 0; margin-right: 5px" />You are using the window screen on ' + percentage + '% ' + zoomstatus + ' resolution, might some options are not visible properly on this current resolution please fit the screen on 100% as this our highly recommendation.</div>');
}
$(window).resize(function() {
var browserZoomLevel = Math.round(window.devicePixelRatio * 100);
if (browserZoomLevel !== '100') {
if (browserZoomLevel > "100") {
var status = "ZoomIn";
} else {
var status = "ZoomOut";
}
informationbar(browserZoomLevel, status);
} else {
$("div#informationbar").remove();
}
});
var browserZoomLevel = Math.round(window.devicePixelRatio * 100);
if (browserZoomLevel == '100') {
$("div#informationbar").remove();
} else {
if (browserZoomLevel > "100") {
var status = "ZoomIn";
} else {
var status = "ZoomOut";
}
informationbar(browserZoomLevel, status);
}
#informationbar {
position: fixed;
left: 0;
width: 100 %;
text - indent: 5 px;
padding: 5 px 0;
background - color: lightyellow;
border - bottom: 1 px solid black;
font: bold 12 px Verdana;
}
* html# informationbar {
/*IE6 hack*/
position: absolute;
width: expression(document.compatMode=="CSS1Compat" ? document.documentElement.clientWidth + "px": body.clientWidth + "px");
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
You seem to be using !== to compare numbers and strings, e.g. browserZoomLeveL !== '100' where browserZoomLevel = Math.round(...).
That will always give false, since the a string isn't a number, and === is strict about types. You should replace === '100' with just === 100.

Background image not changing properly with 'Offset' in Waypoints.js

Here is some Javascript and CSS from my program:
<script>
var $body = $('body');
$body.waypoint(function (direction) {
if (direction == 'down') {
$body.addClass('body2');
} else{
$body.removeClass('body2');
}
}, { offset: '50%'});
</script>
<style>
body {
background-image: url("images/image1.png");
background-repeat: no-repeat;
background-position: 400px 200px;
background-size: 900px 300px;
margin-right: 400px;
background-attachment: fixed;
}
.body2 {
background-image: url("images/image2.png");
background-repeat: no-repeat;
background-position: 400px 200px;
background-size: 900px 300px;
margin-right: 400px;
background-attachment: fixed;
}
I'm trying to change the background image from image1 (body) to image2 (body2) as I scroll 50% of the way down the page. However, when I launch the program the only image displayed is image2 and nothing changes as I scroll. Any help would be greatly appreciated, thanks in advance!
I tried to use waypoints, but I can't seem to make it work though (it gives unreliable results for me, on Chrome).
You could use your own custom function to handle the scroll event as you wish.
You need to compute:
height: total document height (offset 50% = height/2)
y: current scroll position
direction: by comparing y with the last scroll position
Like in this example (Run code snippet):
/**
* very simple on scroll event handler
* use: Scroller.onScroll(..custom function here...)
* custom function gets 3 parameters: y, height and direction
*/
var Scroller = {
_initiated: 0,
_init: function() {
var t = this;
t._listener = function() {
t._scrollEvent();
};
window.addEventListener("scroll", t._listener);
t.y = t.getY();
t._initiated = 1;
},
_onScroll: null,
_scrollEvent: function() {
var t = this;
if (!t._initiated || !t._onScroll)
return false;
var y = t.getY();
t.height = document.body.scrollHeight;
t.direction = y < t.y ? "up" : "down";
t.y = y;
t._onScroll(t.y, t.height, t.direction);
},
getY: function() {
//for cross-browser compatability
// https://stackoverflow.com/a/51933072/4902724
return (window.pageYOffset !== undefined) ?
window.pageYOffset :
(document.documentElement || document.body.parentNode || document.body).scrollTop;
},
onScroll: function(fn) {
var t = this;
t._onScroll = fn;
if (!t._initiated)
t._init();
},
destroy: function() {
var t = this;
window.removeEventListener("scroll", t._listener);
t._onScroll = null;
t._initiated = 0;
}
};
/**
* global vars
*/
var $body = $("body");
// keep track of changes, to cancel unnecessary class changes
$body.classChanged = 0;
/**
* on scroll setup
*/
Scroller.onScroll(function(y, height, direction) {
/* to check for 50%, compare y vs. height/2 */
if (y > height / 2 && direction == "down" && !$body.classChanged) {
$body.addClass("body2");
$body.classChanged = 1;
}
if (y < height / 2 && direction == "up" && $body.classChanged) {
$body.removeClass("body2");
$body.classChanged = 0;
}
});
body {
background-color: lightgreen;
}
.body2 {
background-color: gold;
}
/* demo helpers...*/
div {
float: left;
width: 100%;
height: 250px;
border: 1px solid grey;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<p>Sroll down below 50% to change body color...."</p>
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
Hope this helps, even without that plugin.
I've actually figured out the problem. All I needed to do was set the offset percentage as negative.

Javascript function on the first load page

I was looking for an sticky footer and I found this
https://gist.github.com/robertvunabandi/b66dc9872f51c93af796094e08155731
It's pretty useful but the problem is when I refresh the page the footer appears on the top first and 1 second after it takes the right place at the bottom, it's there's way to avoid that? I mean when I refresh the page the footer appears at the bottom as it should be?
window.addEventListener("load", activateStickyFooter);
function activateStickyFooter() {
adjustFooterCssTopToSticky();
window.addEventListener("resize", adjustFooterCssTopToSticky);
}
function adjustFooterCssTopToSticky() {
const footer = document.querySelector("#footer");
const bounding_box = footer.getBoundingClientRect();
const footer_height = bounding_box.height;
const window_height = window.innerHeight;
const above_footer_height = bounding_box.top - getCssTopAttribute(footer);
if (above_footer_height + footer_height <= window_height) {
const new_footer_top = window_height - (above_footer_height + footer_height);
footer.style.top = new_footer_top + "px";
} else if (above_footer_height + footer_height > window_height) {
footer.style.top = null;
}
}
function getCssTopAttribute(htmlElement) {
const top_string = htmlElement.style.top;
if (top_string === null || top_string.length === 0) {
return 0;
}
const extracted_top_pixels = top_string.substring(0, top_string.length - 2);
return parseFloat(extracted_top_pixels);
}
I guess its not a good idea to manipulate DOM-elements with JS at the page load event. Better use CSS to do the trick:
How to make a sticky footer using CSS?
If you do it in CSS you shouldn't have this issue, plus it's very few lines of code, I made a quick mock-up as an example.
HTML:
<header>Header</header>
<main>Main</main>
<footer>Footer</footer>
CSS:
header {
background-color:blanchedalmond;
height: 10vh;
min-height: 60px;
}
main {
background-color:beige;
height: 70vh;
min-height: 800px;
}
footer {
background-color:blanchedalmond;
height: 20vh;
min-height: 200px;
position: -webkit-sticky;
position: sticky;
bottom: 0;
}

Unexpected NaN value when parsing the attribute on after content + z-index

I have a really weird issue, here it is :
i wanted to create a perspective shadow like this topic (::after instead in my case) How to create a perspective shadow with CSS?
div {
position: relative;
display: inline-block;
height: 150px;
width: 150px;
background: url(//placehold.it/150x150);
margin-left: 30px;
}
div::before {
content: "";
position: absolute;
z-index: -1;
bottom: 0;
left: 15px;
height: 10%;
width: 70%;
box-shadow: -25px -4px 4px 0 rgba(0,0,0,0.75);
transform: skewX(60deg);
}
and then when i load my webpage and then i click on "inspect element" from firefox and click on something in the code, i've got this issue "Unexpected NaN value when parsing the attribute", i searched on forum and people said that it may be a Qjery problem but when i delete this ::after everything is good.
here is my Javascript file:
function styleTabHover(tabButton){
tabButton.style.color= "#ff9900";
}
function styleTabOut(tabButton){
tabButton.style.color= "white";
tabButton.style.borderColor= "white";
}
function check_email(ev){
var champ = ev.currentTarget;
if(!champ.value.includes("#")){
champ.style.outline = "2px dotted red";
document.getElementById("champ_requis").style.opacity = "1";
}else{
champ.style.outline = "none";
document.getElementById("champ_requis").style.opacity = "0";
}
}
function changeTab(idbouton){
var tabs = document.getElementsByClassName("menu_bouton");
console.log(tabs,"changetab fonction lancé")
var i;
for (i=0;i<tabs.length;i++){
tabs[i].style.backgroundColor = "initial";
tabs[i].style.zIndex = "0";
tabs[i].onmouseover = function(){styleTabHover(this)};
tabs[i].onmouseout = function(){styleTabOut(this)};
}
var bouton = document.getElementById(idbouton);
bouton.style.background = "#ff9900";
bouton.style.color = "white";
bouton.onmouseover= function(){this.style.cursor = "default"};
}
var imgPositionMoins = 0;
function style_projet_slide(droite){
var lst_projetImg = document.getElementsByClassName("projets_img");
var i;
if(droite && (imgPositionMoins > (-100*(lst_projetImg.length-1)) ) ){
imgPositionMoins -= 100;
for(i=0;i<lst_projetImg.length;i++){
lst_projetImg[i].style.left = imgPositionMoins+"%";
}
}else if ( !droite && imgPositionMoins < 0){
imgPositionMoins += 100;
for(i=lst_projetImg.length-1; i>=0; i--){
lst_projetImg[i].style.left = imgPositionMoins+"%";
}
}
}
function projet_desc(indice){
var lst_desc=document.getElementById("projet_desc").children;
var i;
for (i=0;i<lst_desc.length;i++){
if (i==indice){
lst_desc[i].style.display = "block";
} else{
lst_desc[i].style.display = "none";
}
}
window.scroll({
top: 800,
left: 0,
behavior: 'smooth'
});
}
another problem i get, when i use z-index -1 when i load the webpage, i see the ::before content during 1 second which is supposed to be behind the main content. So, i tried to use a positive z-index as people said but it doesnt work when i put a higher z-index on the main content. I saw that i have to put position:relative but on the official doc. it shows that we can do an absolute position.
Can someone help me ? Thanks !

jQuery photoResize function isn't working

I'm new to jQuery and i'm still in the process of learning HTML and CSS. I wanted to have a responsive image on the homepage of my website that scaled itself with the user's browser window. I found this at github: https://github.com/gutierrezalex/photo-resize.git
but i think i might be using it wrong, since i can't get it to work for me.
Here's my html:
<head>
<script
src="https://ajax.googleapis.com/ajax/libs/jquery/1.12.2/jquery.min.js">
</script>
<reference path="jquery-1.5.1.min.js" />
<script src="jquery-photo-resize.js"></script>
<script type="text/javascript" charset="utf-8">
$(document).ready(function() {
$("img").photoResize()
});
</script>
</head>
and here's the jquery-photo-resize.js file:
function photoResize($) {
"use strict";
$.fn.photoResize = function (options) {
var element = $(this),
defaults = {
bottomSpacing: 10
};
function updatePhotoHeight() {
var o = options,
photoHeight = $(window).height();
$(element).attr('height', photoHeight - o.bottomSpacing);
}
$(element).load(function () {
updatePhotoHeight();
$(window).bind('resize', function () {
updatePhotoHeight();
});
});
options = $.extend(defaults, options);
};
}
Like i said, i'm a novice, so please let me know what i'm doing wrong, and how i can achieve my desired effect.
You don't need jquery for this. Just set a class name and then in your style sheet use a width. If you only set a width it'll auto size the height to maintain the aspect ratio. Same goes for setting the height only. If you set both your aspect ratio may be off. The width can be a percentage of the current element. You could also use vw (view port width). Also calc is super helpful.
{ width:75%}
Update:
.cropper {
width: 75px;
height: 75px;
overflow: hidden;
position: relative;
}
.cropped {
width: 100px;
position: absolute;
left: -12.5px;
top: -12.5px;
}
<div class="cropper">
<img class="cropped" src="https://upload.wikimedia.org/wikipedia/commons/thumb/b/b6/SIPI_Jelly_Beans_4.1.07.tiff/lossy-page1-256px-SIPI_Jelly_Beans_4.1.07.tiff.jpg"/>
</div>
Here is code :
CSS :
.featured { overflow:hidden;
border:2px solid #000;
position:relative;}
.featured img { width:100%; position:relative;}
#pos_1 { width:200px; height:190px; }
#pos_2 { width:150px; height:250px; }
#pos_3 { width:350px; height:150px; }
HTML :
<div id="topGallery">
<article class="featured" id="pos_1">
<img src="abc.jpd" class="attachment-post-thumbnail wp-post-image" alt="piano" />
</article>
</div>
Javascript :
jQuery(document).ready(function($) {
///HOME PAGE - image resizing
function imageLoaded() {
var w = $(this).width();
var h = $(this).height();
var parentW = $(this).parent().width();
var parentH = $(this).parent().height();
//console.log(w + '-' + h + '-' + parentW + '-' + parentH);
//if (w >= parentW){ //always true because of CSS
if (h > parentH){
$(this).css('top', -(h-parentH)/2);
} else if (h < parentH){
$(this).css('height', parentH).css('width', 'auto');
$(this).css('left', -($(this).width()-parentW)/2);
}
//}
}
$('#topGallery img').each(function() {
if( this.complete ) {
imageLoaded.call( this );
} else {
$(this).one('load', imageLoaded);
}
});
});

Categories