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.
Related
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");
I want two elements in different locations and different "parents" in the DOM tree to have the same height and width, even if one changes.
Is there a solution that will support all browsers including IE 8?
EDIT: If there is a solution that will not work on IE 8 I would still like to hear about it, but it will not be accepted as the solution I'm looking for.
Clarification: I want to solution to handle any cause for the size change: Window size change, content size change, etc.
You can use setInterval to do what you want.
var changeIndex = -1; // record element width or height is change or not
function setToSame() {
if(changeIndex!=-1) {
console.log("test");
$('.same').height($('.same').eq(changeIndex).height());
$('.same').width($('.same').eq(changeIndex).width());
changeIndex = -1;
}
}
// set your own function to change size, but reserve changeIndex setting
$('input').change(function() {
$(this).parent().children('.same').css($(this).attr('id'), $(this).val() +'px');
// set the changeIndex to the current change div
changeIndex = $('.same').index($(this).parent().children('.same'));
console.log(changeIndex);
});
setInterval(setToSame, 4);
See jsfiddle here.
You can use jQuery to get a solution that works for IE8.
Suppose the two element that you want to have same height and width are,
<div id="fir">
</div>
<div id="sec">
</div>
Now specify height and width of just one element as,
#fir{
height: 50px;
width: 100px;
}
There is no predefined method in CSS to detect height or width change but you can achieve the results using jQuery as,
$(document).ready(function(){
$('#fir').bind('heightChange', function(){
var h = $("#fir").height();
$("#sec").height(h);
});
$('#fir').bind('widthChange', function(){
var w = $("#fir").width();
$("#sec").width(w);
});
$('#sec').bind('heightChange', function(){
var h = $("#sec").height();
$("#fir").height(h);
});
$('#sec').bind('widthChange', function(){
var w = $("#sec").width();
$("#fir").width(w);
});
});
This will detect the height and width change for both element and set the height and width of other element likewise.
To check if the above code works properly you can create a test script that changes width of element with id="fir" by creating a button,
<button id="btn">Change width</button>
Now include the below function,
$("#btn").click(function() {
$("#fir").css('width', '400px');
$("#fir").trigger('widthChange');
});
Here is the fiddle for it
<html>
<head>
<style>
div{}
#A{background: red}
#B{background: blue}
</style>
<script>
mBlockChange = false; //Required for IE9-
function equalSize(f, t){
mBlockChange = true;
f = (f || document.getElementById('A'));
t = (t || document.getElementById('B'));
//We take the larger dimension of both since it is better than clipping.
//Change on your demands.
t.style.height = '';
t.style.width = '';
f.style.height = '';
f.style.width = '';
t.style.height = Math.max(f.offsetHeight, t.offsetHeight).toString() + 'px';
t.style.width = Math.max(f.offsetWidth, t.offsetWidth).toString() + 'px';
f.style.height = Math.max(f.offsetHeight, t.offsetHeight).toString() + 'px';
f.style.width = Math.max(f.offsetWidth, t.offsetWidth).toString() + 'px';
setTimeout(function(){mBlockChange = false}, 100);
}
//This one for IE9+, FFox, Chrome and Safari
//http://help.dottoro.com/ljrmcldi.php
function bindEvents(){
var tA = document.getElementById('A');
var tB = document.getElementById('B');
//The addEventListener() method is not supported in Internet Explorer 8 and earlier versions with resize.
//Resizing the body
document.body.onresize = function(){
//We only do this once the resizing is actually finished.
if (this.Timer) clearTimeout(this.Timer);
this.Timer = setTimeout(function(){
//console.log('Resize', this);
equalSize()
}, 300)
};
//If supported, we listen on dom changes.
if ('MutationEvent' in window){
document.addEventListener('DOMSubtreeModified', function(){
if (document.Timer) clearInterval(document.Timer);
//console.log('DOMSubtreeModified', this);
if (!mBlockChange) equalSize()
}, false);
}
//We set an interval for browsers which do not support DOMSubtreeModified
//If you do not want to rely on ('MutationEvent' in window) put it out of else and cancel the timer (scenario B)
//Can not bind parameters to setInterval in IE8- :s
else{
document.Timer = setInterval(function(){
//console.log('Interval', 'Document');
equalSize()
}, 1000);
}
}
</script>
</head>
<body onload = 'bindEvents()'>
<div id = 'A'><p contenteditable = 'true'>A</p></div>
<div id = 'B'><p contenteditable = 'true'>B</p></div>
</body>
</html>
https://jsfiddle.net/5cn7maqe/
Yet your elements height and width should not magically change, it always requires some interactions, like changing dom by ajax, oninput with contenteditable or resizing the window. You would be better off to just adjust it after those actions manually.
Edit: Made some minor changes.
https://jsfiddle.net/5cn7maqe/1/
I want to execute the window onscroll event, but I don't know why it doesn't work on all browsers(firefox, chrome, etc), and there is no errors occurred.
Full code:
var elem = document.getElementById('repeat');
var show = document.getElementById('show');
for (i = 1; i <= 300; i++) {
elem.innerHTML += i + "<br/>";
}
window.onscroll = function () {
show.innerHTML = document.body.scrollTop;
};
#show {
display:block;
position:fixed;
top:0px;
left:300px;
}
<pre id="repeat"></pre>
<div style="position:relative;">
<div id="show">x</div>
</div>
Also jsfiddle:
http://jsfiddle.net/sqo0140j
What is the problem ?
You said something interesting:
x changed to 0 and remains as is.
The only way in your code that can happen is if the onscroll function block makes a change because your HTML sets x.
If your window.onscroll = function() is indeed firing, but you are not getting the right scroll position (i.e. 0), try changing the way the scroll position is returned:
window.onscroll = function () {
show.innerHTML = document.documentElement.scrollTop || document.body.scrollTop;
};
I found out that document.documentElement.scrollTop always returns 0 on Chrome. This is because WebKit uses body for keeping track of scrolling, but Firefox and IE use html.
Please try your updated snippet:
var elem = document.getElementById('repeat');
var show = document.getElementById('show');
for (i = 1; i <= 300; i++) {
elem.innerHTML += i + "<br/>";
}
window.onscroll = function () {
show.innerHTML = document.documentElement.scrollTop || document.body.scrollTop;
};
#show {
display:block;
position:fixed;
top:0px;
left:300px;
}
<pre id="repeat"></pre>
<div style="position:relative;">
<div id="show">x</div>
</div>
For me the statement document.body.scrollTop; works well in Chrome and Opera, but on Firefox returns 0.
Viceversa the statement document.documentElement.scrollTop; works good on Firefox but not in Chrome and Opera...
Maybe document.body.scrollTop; is not well supported by FF
Possible Solutions:
I tried:
Math.max(document.body.scrollTop, document.documentElement.scrollTop);
and
document.body.scrollTop || document.documentElement.scrollTop;
They both works well on all above browsers.
I had also the same problem , but I didn't know the proper reason for that .
In my case
window.onscroll = function () {
console.log(document.documentElement.scrollTop || document.body.scrollTop);
};
this code didn't work even after removing margin:0; and padding:0; .
But by mention the addEventListener on the document.body it is worked
document.body.addEventListener('scroll',()=>{
console.log(document.documentElement.scrollTop || document.body.scrollTop);
})
This question has been answered, but I wanted to include details of my situation that prevent onscroll from working.
I have datacontainer that had its own scroll bar which overrides the built in window scroll bar. I didnt notice this until I started giving a more thorough look at the elements on the page using chrome developer. My outer tag looked like this,
This caused two scroll bars to appear on the left. This was because the property, overflow:auto, was telling the data container to make another scroll bar.
Once I removed the overflow:auto I could now correct hit the onscroll event.
Because a lot of people use W3Schools i wanted to leave this here.
This simple scroll event wasn't firing
window.onscroll = function () { myFunction() };
var navbar = document.getElementById("navbar");
var sticky = navbar.offsetTop;
function myFunction() {
if (window.pageYOffset - 20 >= sticky) {
navbar.classList.add("sticky");
}
}
Until I removed < link rel="stylesheet" href="https://www.w3schools.com/w3css/4/w3.css">
and everything was working again flawlessly.
For people having issues with this function. Another reason that it looks like it is not working is that you define it multiple times.
window.onscroll = function() {
console.log('scroll 1');
};
// some other js code
window.onscroll = function() {
console.log('scroll 2');
};
Only the last one gets executed since it overwrites your first declaration. The solution is then
window.addEventListener('scroll', function() {
console.log('scroll 1');
})
window.addEventListener('scroll', function() {
console.log('scroll 2');
})
how can i build fixed menu like gmail menu. i have tried css, but the div stays in middle, it doesnt come up like the gmail menu does on scroll.
open in large image
i have tried using css property, following is some example code (not real code):
.menu {
position:fixed;
height: 36px;
background-color:#fff;
}
You need to use javascript to check the scrollTop and set the position of your menu to fixed if if the scrollTop is more than the height of your header.
function getScrollTop() {
if(typeof pageYOffset!= 'undefined') {
//most browsers
return pageYOffset;
}
else {
var b = document.body; //IE 'quirks'
var d = document.documentElement; //IE with doctype
d = (d.clientHeight) ? d : b;
return d.scrollTop;
}
}
function onScroll() {
var menu = document.getElementById('divMyMenu');
var headerAndNavHeight = document.getElementById('divHeader').clientHeight
+ document.getElementById('tsMain').clientHeight;
if (getScrollTop() < headerAndNavHeight) {
menu.style.top = headerAndNavHeight + 'px';
menu.style.position = 'absolute';
}
else {
menu.style.top = '0px';
menu.style.position = 'fixed';
}
}
A good and easy to use jQuery Plugin for this is Waypoints
Here you can see a working example:
http://imakewebthings.github.com/jquery-waypoints/sticky-elements/
Position fixed alone is not enough to achieve this effect. Also, position:fixed does not work in IE7 or below, so you'll probably want to have fallback.
You need to use javascript (jQuery makes it easy) to dynamically change the position of the element based upon how far scrolled down the page you are.
Look into .scrollTop()
http://api.jquery.com/scrollTop/
var scrollTop = $(window).scrollTop();
May be this is what you are looking for
http://blog.geotitles.com/2011/10/creating-top-fixed-menu-bar-with-css3-buttons-found-in-gmail/
Here is a very simple trick to implement your requirement explained with example and a link to download.
http://itswadesh.wordpress.com/2012/02/24/google-like-top-bar-with-drop-down-menu-using-html-css-and-jquery/
How do I check if browser supports position:fixed using jQuery. I assume I have to use $.support I think, but how?
Thank you for your time.
The most reliable way would be to actually feature-test it. Browser sniffing is fragile and unreliable.
I have an example of such test in CFT http://kangax.github.com/cft/#IS_POSITION_FIXED_SUPPORTED. Note that the test should be run after document.body is loaded.
I find that mobile safari (specifically iOS 4.2 via the iOS Simulator on OSX) refuses to scroll anywhere unless you wait a few miliseconds. Hence the false positive.
I wrote a quick jquery plugin to work around it:
(function($) {
$.support.fixedPosition = function (callback) {
setTimeout(
function () {
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;
callback(isSupported);
}
else {
callback(null);
}
},
20
);
}
})(jQuery);
function fixedcheck () {
var fixedDiv = $('<div>').css('position', 'fixed').appendTo('body');
var pos1 = fixedDiv.offset().top;
$(window).scrollTop($(window).scrollTop() + 1);
var pos2 = fixedDiv.offset().top;
fixedDiv.remove();
return (pos1 != pos2)
}
/* Usage */
$(document).ready(function () {
if (!fixedcheck()) alert('Your browser does not support fixed position!')
});
You could check if position exists by making a code like this:
<html>
<script type="text/javascript">
test = function() {
if(!!document.getElementById("test").style.position) {
alert('true');
}
else{
alert('false');
}
}
</script>
<body>
<p id="test" onclick="test();" style="position:fixed;">Hi</p>
</body>
</html>
Since position exists in all main browser this will always return true. I imagine there isn't a way to check the possible values of position, so you'll have to check which browser and which version the user are viewing your page as Paolo Bergantino said.
position:fixed apparently works for all block elements in Mobile Safari (4.3.2) except body, so the CFT answer (http://kangax.github.com/cft/#IS_POSITION_FIXED_SUPPORTED) should have this in it:
var isSupported = (container.scrollTop === 500 && elementTop === 100);
The feature-test Position fixed support , mentioned above, returns a false-positive on Opera Mini (which does not support position: fixed).
I've created another check if position:fixed is really supported in browser. It creates fixed div and try to scroll and check if the position of div changed.
function isPositionFixedSupported(){
var el = jQuery("<div id='fixed_test' style='position:fixed;top:1px;width:1px;height:1px;'></div>");
el.appendTo("body");
var prevScrollTop = jQuery(document).scrollTop();
var expectedResult = 1+prevScrollTop;
var scrollChanged = false;
//simulate scrolling
if (prevScrollTop === 0) {
window.scrollTo(0, 1);
expectedResult = 2;
scrollChanged = true;
}
//check position of div
suppoorted = (el.offset().top === expectedResult);
if (scrollChanged) {
window.scrollTo(0, prevScrollTop);
}
el.remove();
return suppoorted;
}
This function was tested in Firefox 22, Chrome 28, IE 7-10, Android Browser 2.3.