Scroll Behaviour Smooth Alternative for Safari - javascript

I am building a site and want to use some anchor links. On all browsers other than Safari, the scroll-behaviour: smooth; works. I understand that this is not supported on Safari.
I have seen people mention:
import smoothscroll from 'smoothscroll-polyfill';
smoothscroll.polyfill();
However, I am not entirely sure how to implement it.
If someone can explain how to use this, or even a JS function that will give the smooth effect, it would be grately appreciated.

Safari Doesn't support scroll-behaviour: smooth so we need some custom javascript to achieve the same effect.
function SmoothVerticalScrolling(e, time, where) {
var eTop = e.getBoundingClientRect().top;
var eAmt = eTop / 100;
var curTime = 0;
while (curTime <= time) {
window.setTimeout(SVS_B, curTime, eAmt, where);
curTime += time / 100;
}
}
function SVS_B(eAmt, where) {
if(where == "center" || where == "")
window.scrollBy(0, eAmt / 2);
if (where == "top")
window.scrollBy(0, eAmt);
}
SmoothVerticalScrolling(myelement, 275, "center");

Related

Using getScrollTop to work with :Hover elements

Not sure how exactly to make it so that the navbox is opaque after scrolling until hovered over, I would also like to incorporate CSS3 Transitions into this.
This is the working code without hover:
<Script>
window.onload = function() {
function getScrollTop() {
if (typeof window.pageYOffset !== 'undefined' ) {
// 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;
}
window.onscroll = function() {
var box = document.getElementById('navbox'),
scroll = getScrollTop();
if (scroll <= 1) {
box.style.top = "0px";
box.style.opacity = "1";
}
else {
box.style.top = (scroll + 0) + "px";
box.style.opacity = "0.25";
}
};
};
</script>
I've tried adding var hoverbox = document.getElementById('navbox:Hover'), and then using opacity in that fashion below with:
if (scroll <= 1) {
box.style.top = "0px";
box.style.opacity = "1";
navbox.style.opacity = "1";
But that doesn't work either.
Any advice on how to make the hover transition work with JScript?
You are doing it's wrong. With this command document.getElementById('navbox:Hover') you are saying to browser, catch the element where your id is equal 'navbox:hover'. You can try use CSS to this
<style>
#navbox{
transition-property: opacity;
transition-duration: 1s;
}
#navbox:hover{
opacity: 0.5;
}
</style>
Note: The transition property don't are avalaible in all browsers.
Internet Explorer 10, Firefox, Chrome, and Opera supports the transition property.
Safari requires the prefix -webkit-.
Internet Explorer 9, and earlier versions, does not support the transition property.
Chrome 25, and earlier versions, requires the prefix -webkit-.
Read more about this in W3 Schools and in Mozilla Developer Network.
With JS you can use this way:
<script>
function FadeIn(){
this.style.opacity = "0.5";
}
function FadeOut(){
this.style.opacity = "1";
}
function LoadEvents(){
var div = document.getElementById("teste");
div.addEventListener("mouseover", FadeIn, false);
div.addEventListener("mouseout", FadeOut, false);
}
</script>
<body onload="LoadEvents()">
But, I advise use JQuery, is more easy. For to know more about addEventListener(), read this in Mozilla Developer Network
Don't use navbox:Hover. There is a method in jquery mouseover which can define actions to do after mouse over the element.
Or you can use addEventListener() to define the mouseover event.
Check the documentation on how to use the mouseover function.

Javascript / jQuery sticky without using css position: fixed

I'm looking for a Javascript/jQuery plugin for sticky header that will not switch the element's style to position fixed. Usually, I'm working with this one http://stickyjs.com/ and it works fine.
I'm working on a website with jQuery animation and one of my div has a sticky header with width:100%. But when I move it to the left (for example), the width:100% is now based on the window's width and not his container.
So, is there an existing plugin that does the same thing as the others but keep the position: relative and calculate the scrollTop to apply as the margin-top for my sticky header?
EDIT 2021
My answer below is pretty old. I would not recommend to use any JS code for that anymore but simply use CSS with position: sticky; which is much easier to implement, but also much more performant/smooth (note: Internet Explorer doesn't support position: sticky;).
Original answer
So, I solved my problem! Here's my javascript code:
You have to set top:0px as default
function relative_sticky(id, topSpacing){
if(!topSpacing){ var topSpacing = 0; }
var el_top = parseFloat(document.getElementById(id).getBoundingClientRect().top);
el_top = el_top - parseFloat(document.getElementById(id).style.top);
el_top = el_top * (-1);
el_top = el_top + topSpacing;
if(el_top > 0){
document.getElementById(id).style.top = el_top + "px";
} else{
document.getElementById(id).style.top = "0px";
}
}
window.onscroll = function(){
relative_sticky("your_element_id", 10);
}
It's not very smooth in IE, so I add a delay:
var delay = (function(){
var timer = 0;
return function(callback, ms){
clearTimeout (timer);
timer = setTimeout(callback, ms);
};
})();
window.onscroll = function(){
if(BrowserDetect.browser == "Explorer" || BrowserDetect.browser == "Mozilla"){
// or your own way to detect browser
delay(function(){
relative_sticky("admin_users_head", 31);
}, 200);
}
else{
relative_sticky("admin_users_head", 31);
}
}

Browser detection using javascript failing on refresh

I'm trying to detect for devices that do not have support for position:fixed. EDIT: I've fixed the code so it's detecting features rather than browser/OS detection.
I think I was confusing people when I first typed this out. My issue is coming into play when I refresh the page. The height is being incorrectly calculated, which is a completely different issue I know, but am looking for assistance nonetheless.
Updated detection script below:
function fixed() {
var container = document.body;
if (document.createElement && container && container.appendChild && container.removeChild) {
var el = document.createElement('div');
if (!el.getBoundingClientRect) return null;
el.innerHTML = 'x';
el.style.cssText = 'position:fixed;top:100px;';
container.appendChild(el);
var originalHeight = container.style.height,
originalScrollTop = container.scrollTop;
container.style.height = '3000px';
container.scrollTop = 500;
var elementTop = el.getBoundingClientRect().top;
container.style.height = originalHeight;
var isSupported = (elementTop === 100);
container.removeChild(el);
container.scrollTop = originalScrollTop;
return isSupported;
}
return null;
}
//TEST FOR MOBILE, SET TOP IMAGE TO RELATIVE
if(fixed()) {
image_height = jQuery("#outer_homepage_image").height() - 45;
jQuery("#content").css("top",image_height);
jQuery(window).resize(function() {
image_height = jQuery("#outer_homepage_image").height() - 45;
alert(image_height);
jQuery("#content").css("top",image_height);
});
} else {
jQuery("#outer_homepage_image").css("position","relative");
}
This is an extremely brittle and ill-conceived thing to be doing.
if(/Android|webOS|iPhone|iPad|iPod|BlackBerry/i.test(navigator.userAgent)) {
For example, iOS has fully supported position:fixed properly since iOS 4. We're now on 6. For Android & Blackberry, I'm not sure but would err on the side of "supported".
You need to test for features, not user agent. As I said, you could have one iOS device that doesn't support it and another one that does. Indeed, most do these days.
Here's a helpful link to lead you to moral, godly choices: http://kangax.github.com/cft/#IS_POSITION_FIXED_SUPPORTED
Thanks for all the support guys. I solved it with jQuery(window).load(function() {
it works now because everything else is loaded so I can calculate the proper height.

How to add css to a div once it hits the top of the page (when scrolling)?

I would like to make it so when user scrolls down and reaches a certain div, say #float, set that div to margin-top: 50px and position fixed, and if user scrolls back up undo those changes. It's hard to understand I know ))) If you go to this page and pay your attention to sidebar once scrolling up and down you will see what I mean.
As you scroll down 2nd advertisement scrolls with a page too.
How would I achieve same functionality with jQuery/CSS?
This is a way of doing it in jQuery.
This code is provided for example purposes only; there are almost certainly a handful of regularly-maintained jQuery plugins that will do this thing for you - check GitHub or DailyJS.
$(window).scroll(function() {
var styledDiv = $('#styledDiv'),
targetScroll = $('#float').position().top,
currentScroll = $('html').scrollTop() || $('body').scrollTop();
styledDiv.toggleClass('fixedPos', currentScroll >= targetScroll);
});
Here is a simple JSFiddle of the above in action.
Edit: Have now refactored this code to a more elegant solution.
Edit 2: Following an email I received about a question, I've updated the code above so that it also works in Firefox. As $('body').scrollTop() will not work in Firefox (See comments on the jQuery API page), we need to check both the html and body elements.
This is the relevant jQuery/JavaScript code use on that site.
if (window.XMLHttpRequest) {
var topGagStay = $("top-gag-stay");
var isLoggedIn = $("profile-menu") ? true : false;
var sidebarAdsTop = 1061 - 545;
var signupBtnOffset = 60;
var dockPos = 72;
if (!isLoggedIn && !GAG.isReadOnly()) {
sidebarAdsTop += signupBtnOffset
}
if (formMessageShown) {
sidebarAdsTop += formMessageOffset
}
if (topGagStay) {
if (document.documentElement.scrollTop > sidebarAdsTop || self.pageYOffset > sidebarAdsTop) {
if (topGagStay.style.position != "fixed") {
topGagStay.style.position = "fixed";
topGagStay.style.top = dockPos + "px"
}
} else {
if (document.documentElement.scrollTop < sidebarAdsTop || self.pageYOffset < sidebarAdsTop) {
topGagStay.style.position = "";
topGagStay.style.top = ""
}
}
}
}
Thank FireBug and http://jsbeautifier.org/ for the code (and 9GAG, of course).
I have tried the above answer by beardtwizzle and it worked fine. Also made it work for the case when the page is scrolled upto the bottom of the page.
see the working demo/tutorial here

Resizing an image using Javascript running in Opera Browser

I hope someone can help with this quirky issue I am having with the Opera Browser, I have version 11 Beta installed, but I suspect is a common problem in Opera.
The website and page in question is http://www.amigaos.net/index.html.
At the bottom of the body of the html I have the following code which resizes the 3 images you see on this webpage depending on width of the viewport at page load. In Safari and FireFox the code works fine, but in Opera the following lines which involve resizing the width and height of an image do not work:
document.getElementById('img1').width = '475';
document.getElementById('img1').height = '375';
Here is the code in full (sorry, about the layout, stackoverflow hasn't formatted carriage returns correctly)
<script type="text/javascript">
function GetWidth()
{
var x = 0;
if (typeof window.innerWidth != 'undefined')
{
x = window.innerWidth;
}
else if (document.documentElement && document.documentElement.clientHeight)
{
x = document.documentElement.clientWidth;
}
else if (document.body)
{
x = document.getElementsByTagName('body')[0].clientWidth;
}
return x;
}
width = GetWidth();
if (width>=1680)
{
document.getElementById('img1').width = '475';
document.getElementById('img1').height = '375';
document.getElementById('img2').width = '475';
document.getElementById('img2').height = '375';
document.getElementById('img3').width = '475';
document.getElementById('img3').height = '375';
}
else if ((width>800) && (width<=1280))
{
document.getElementById('img1').width = '300';
document.getElementById('img1').height = '235';
document.getElementById('img2').width = '300';
document.getElementById('img2').height = '235';
document.getElementById('img3').width = '300';
document.getElementById('img3').height = '235';
}
else if (width<=800)
{
document.getElementById('img1').width = '225';
document.getElementById('img1').height = '195';
document.getElementById('img2').width = '225';
document.getElementById('img2').height = '195';
document.getElementById('img3').width = '225';
document.getElementById('img3').height = '195';
}
</script>
instead of doing width and height attributes, I think you can just set width: 33% via CSS and have the scaling happen automatically, regardless of the browser window size. Better solution than trying to use javascript, IMHO.
Here's a simple tutorial: http://haslayout.net/css-tuts/CSS-Proportional-Image-Scale
you are making this way too complicated. I don't think your issue is browser-specific, you just need to recode your script.
First. I would recommmend using percentages.. Not sure how you will guess the visitors browser width in pixels.
Let's say that your three resizeable images are 20% width of your browser. So your css would be:
#img1, #img2, #img3 {
width: 20%;
}
now that your css says that your images are 20% of the total with, you're good to add some js. Keep in mind that the percentage will be that of its outer container.
<script type=text/javascript">
function resizeImages() {
document.getElementById('img1').style.height = (document.body.clientHeight - 100) * 0.2;
document.getElementById('img2').style.height = (document.body.clientHeight - 100) * 0.2;
document.getElementById('img3').style.height = (document.body.clientHeight - 100) * 0.2;
}
</script>
and most importantly.. call your function:
add this to your body tag:
<body onresize="resizeImages()">
boom.. you're done.

Categories

Resources