Is it possible programatically block scrolling - javascript

I write datagrid with lazy loading, and for some reason I need stop scrolling, when user achieve area without data, to load it. I'm would like to know how I can stop scrolling on page from my code. I have tried e.preventDefault, return false from event handler and that solution also almost working solution.
But problem is all of that solutions actually don't block scrolling, just emulate it. e.g. I want to block scrolling when user scroll up to 5000px
$(function() {
var container = $(".container");
var info = $(".info > .position");
container.scroll(function(e) {
var topPosition = container.scrollTop();
if (topPosition >= 5000) {
disableScroll();
}
info.text("scrollTop: " + topPosition);
});
$(".info > .disable").click(disableScroll);
$(".info > .enable").click(enableScroll);
});
/*
* Code from solution which was mentioned above
* https://stackoverflow.com/questions/4770025/how-to-disable-scrolling-temporarily
*/
const keys = {
37: 1,
38: 1,
39: 1,
40: 1
};
function preventDefault(e) {
e = e || window.event;
if (e.preventDefault)
e.preventDefault();
e.returnValue = false;
}
function preventDefaultForScrollKeys(e) {
if (keys[e.keyCode]) {
preventDefault(e);
return false;
}
}
function disableScroll() {
$(".info > .state").text("Disable");
if (window.addEventListener) // older FF
window.addEventListener('DOMMouseScroll', preventDefault, false);
window.onwheel = preventDefault; // modern standard
window.onmousewheel = document.onmousewheel = preventDefault; // older browsers, IE
window.ontouchmove = preventDefault; // mobile
document.onkeydown = preventDefaultForScrollKeys;
}
function enableScroll() {
$(".info > .state").text("Enable");
if (window.removeEventListener)
window.removeEventListener('DOMMouseScroll', preventDefault, false);
window.onmousewheel = document.onmousewheel = null;
window.onwheel = null;
window.ontouchmove = null;
document.onkeydown = null;
}
html,
body,
.page {
overflow: hidden;
height: 100%;
width: 100%;
padding: 0;
margin: 0;
}
.header {
box-sizing: border-box;
position: fixed;
padding: 0 15px;
display: table;
top: 0;
left: 0;
height: 50px;
width: 100%;
}
.info {
background-color: #cdcdcd;
border: 1px dashed blue;
vertical-align: middle;
display: table-cell;
text-align: center;
margin: 0 15px;
height: 50px;
}
.container {
height: calc(100% - 60px);
width: calc(100% - 30px);
margin: 60px 15px 0 15px;
box-sizing: border-box;
border: 1px solid red;
overflow: auto;
}
.content {
height: 100000px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="page">
<div class="header">
<div class="info">
|<label class="position">Initial</label> |
<label class="state">Enable</label>
<button class="enable" type="button">Enable</button>
<button class="disable" type="button">Disable</button>
</div>
</div>
<div class="container">
<div class="content">
</div>
</div>
</div>
it solution almost work, except cases when user use scrollbar or wheel-click scrolling. e.g. not working use case I want scroll will be stopped when achieve limit (in the example 5000px) and allow scrolling after some event. Is it possible?
UPDATE
Actually question is how to stop scrolling during scrolling example. Scrolling was disabled when user achieve 5000px, but current scrolling process didn't stopped. And I would like to know is is possible to stop scrolling in progress i.e. in other words how to stop scrolling in the example when position become greater than 5000px (change color in header to red)

Add a class
.stop-scrolling{
overflow : hidden;
}
when you need to stop scroll over page
$('html').addClass('stop-scrolling');
and when you want to enable it again:
$('html').removeClass('stop-scrolling');
OR do the same thing like below without adding any class:
$('html').css('overflow','hidden');
$('html').css('overflow','auto');

Okay i see. Then to disable the scrollbar you should try ,
$("body").css("overflow", "hidden");
Then to cancel mousewheel scrolling you should try,
document.addEventListener("mousewheel", function(evt){
evt.preventDefault();
return false;
}, false);

Related

Replicating nested and togglable <frameset> in HTML5

I'm given to understand that the <frameset> tag is deprecated as of HTML5. Thankfully, Chrome still supports rendering it, and unfortunately, it's currently the only thing I've found that fits my use case.
The important element of the <frameset> tag that other frame-like objects lack is draggable borders, which I haven't been able to get working with iframes even with a prohibitive amount of javascript assistance.
The other important thing in my case is that one of the frames contains a button/link that causes the other frame to disappear or reappear. When that happens, the frames should resize appropriately to fill the space.
My current HTML looks like the following MCVE:
index.html
<html>
<head>
<script language="javascript">
function toggleBottomFrame() {
var bottomFrame = document.getElementById("bottomFrame");
var horizFrameset = document.getElementById("horizFrameset");
if (bottomFrame.style.display == "none") {
bottomFrame.style.display = "";
horizFrameset.rows = "*,25%";
} else {
bottomFrame.style.display = "none";
horizFrameset.rows = "*,0px";
}
}
document.toggleBottomFrame = toggleBottomFrame;
</script>
</head>
<frameset id="horizFrameset" rows="*,0px">
<frameset id="vertFrameset" cols="300px,*">
<frame id="topLeftFrame" src="buttonpage.html"></frame>
<frame id="topRightFrame"></frame>
</frameset>
<frame id="bottomFrame" style="display:none"></frame>
</frameset>
</html>
buttonpage.html
<html>
<head></head>
<body>
<button onclick="parent.frameElement.ownerDocument.toggleBottomFrame();">
</body>
</html>
This works both in the IE11 that the code was initially written for (and needs to continue to support), as well as in Chrome.
How do I implement the exact same functionality (including, most importantly, the ability to drag around the borders of the frames with my mouse to expand or shrink one of the frames) using non-deprecated functionality?
If possible, I'd like a solution in standard client-side JS or HTML, without needing to import another library like resize.js. This is meant for a very lightweight frontend, and I don't want to bloat it down with libraries I don't need.
You should be able to achieve the shrink and grown functionality using the flex layout. Below 2 approaches may work. Both the approaches has the right section and bottom section as iframe and the left section has button to show and hide the right and bottom sections.
Option 1
Using flex and using the css resize property.
Drawback is that you will need to resize using the resize button shown at the bottom right corners. The left section's bottom right corner can be used for horizontal resizing and the right section's bottom right corner can be used for vertical resizing. Note that due to the iframe contents the right section's bottom right corner resize button may not be visible, but if you bring the cursor to the bottom right you will see the cursor changing to resize and allowing you to resize.
function toggleBottom() {
if (document.getElementById('bottomFrame').clientHeight > 0) {
document.getElementById('topFrame').style.height = '100%';
} else {
document.getElementById('topFrame').style.height = '80%';
}
}
function toggleRight() {
if (document.getElementById('topRightFrame').clientWidth > 0) {
document.getElementById('topLeftFrame').style.width = '100%';
} else {
document.getElementById('topLeftFrame').style.width = '50%';
}
}
html,
body {
height: 98%;
}
.page-container {
display: flex;
flex-direction: column;
}
.container {
display: flex;
flex-direction: row;
resize: vertical;
border: 1px solid #000;
overflow: hidden;
}
.container-top {
height: 80%;
}
.container-bottom {
flex: 1 1;
overflow: hidden;
}
.container-left {
width: 30%;
border: 1px solid #000;
resize: horizontal;
overflow: hidden;
}
.container-right {
flex: 1 1;
height: 100%;
border: 1px solid #000;
overflow: hidden;
display: flex;
}
.frame-right {
flex: 1 1;
}
.frame-bottom {
flex: 1 1 100%;
border: 1px solid #000;
}
<html>
<body class="page-container">
<div class="container container-top" id="topFrame">
<div class="container-left" id="topLeftFrame">
<button onclick="toggleBottom()">Toggle Bottom</button>
<button onclick="toggleRight()">Toggle Right</button>
</div>
<div class="container-right" id="topRightFrame" >
<iframe src="https://stackoverflow.com" class="frame-right">
</iframe>
</div>
</div>
<div class="container container-bottom" id="bottomFrame">
<iframe class="frame-bottom" src="https://stackoverflow.com"></iframe>
</div>
</body>
</html>
Option 2
Using flex and using some scripting we should be able to make the whole border draggable. This is inspired from the answer in https://stackoverflow.com/a/53220241/2772300
const topRightFrame = document.getElementById("topRightFrame");
const topLeftFrame = document.getElementById("topLeftFrame");
const bottomFrame = document.getElementById("bottomFrame");
const topFrame = document.getElementById("topFrame");
const borderSize = 4;
function toggleBottom() {
if (bottomFrame.clientHeight > borderSize) {
topFrame.style.height = '100%';
} else {
topFrame.style.height = '80%';
}
}
function toggleRight() {
if (topRightFrame.clientWidth > borderSize) {
topLeftFrame.style.width = '100%';
} else {
topLeftFrame.style.width = '50%';
}
}
let mousePosition;
function resizeHorizontal(e){
const dx = mousePosition - e.x;
mousePosition = e.x;
topLeftFrame.style.width = (parseInt(getComputedStyle(topLeftFrame, '').width) - dx) + "px";
}
topRightFrame.addEventListener("mousedown", function(e){
if (e.offsetX < borderSize) {
mousePosition = e.x;
document.addEventListener("mousemove", resizeHorizontal, false);
}
}, false);
document.addEventListener("mouseup", function(){
document.removeEventListener("mousemove", resizeHorizontal, false);
}, false);
function resizeVertical(e){
const dy = mousePosition - e.y;
mousePosition = e.y;
topFrame.style.height = (parseInt(getComputedStyle(topFrame, '').height) - dy) + "px";
}
bottomFrame.addEventListener("mousedown", function(e){
if (e.offsetY < borderSize) {
mousePosition = e.y;
document.addEventListener("mousemove", resizeVertical, false);
}
}, false);
document.addEventListener("mouseup", function(){
document.removeEventListener("mousemove", resizeVertical, false);
}, false);
html,
body {
height: 98%;
}
.page-container {
display: flex;
flex-direction: column;
}
.container {
display: flex;
flex-direction: row;
overflow: hidden;
}
.container-top {
height: 80%;
}
.container-left {
width: 50%;
overflow: hidden;
height: 100%;
}
.container-right {
flex: 1 1;
height: 100%;
overflow: hidden;
display: flex;
padding-left: 4px;
background-color: #ccc;
cursor: ew-resize;
}
.frame-right {
flex: 1 1;
}
.container-bottom {
flex: 1 1;
overflow: hidden;
padding-top: 4px;
background-color: #ccc;
cursor: ns-resize;
}
.frame-bottom {
flex: 1 1 100%;
}
iframe {
border: 0;
}
<html>
<body class="page-container">
<div class="container container-top" id="topFrame">
<div class="container-left" id="topLeftFrame">
<button onclick="toggleBottom()">Toggle Bottom</button>
<button onclick="toggleRight()">Toggle Right</button>
</div>
<div class="container-right" id="topRightFrame" >
<iframe src="https://stackoverflow.com" class="frame-right">
</iframe>
</div>
</div>
<div class="container container-bottom" id="bottomFrame">
<iframe class="frame-bottom" src="https://stackoverflow.com"></iframe>
</div>
</body>
</html>
Have you looked a Golden Layout to do the resizing? You could then place iframes inside to match the size of the containing div.
Sorry this not a more complete answer, but though this might be an area worth exploring that is not likely to come up.

When I touch my JavaScript slider on mobile, I can't scroll down the page

I've built a slider using pure JavaScript. On mobile screen when I touch the slider I can only change slides but can not scroll down the page.
Under the hood when the slider element is touched, a "touchstart" event fires and the corresponding event handler function, features event.preventDefault() to stop scrolling the page, then when "touchmove" event fires, the code uses difference between first and new horizontal coordinates and CSS left propery to move the slider.
I made a minimal code below. Also click to see code on online editor.
const slides = document.querySelector(".slides");
let posX1, posX2, dX;
slides.addEventListener("touchstart", dragStart);
slides.addEventListener("touchmove", dragAction);
function dragStart(e) {
e.preventDefault();
posX1 = e.touches[0].clientX;
}
function dragAction(e) {
posX2 = e.touches[0].clientX;
dX = posX2 - posX1;
posX1 = e.touches[0].clientX;
slides.style.left = (slides.offsetLeft + dX) + "px";
}
body {
padding-bottom: 1000px;
}
.slider {
width: 200px;
height: 100px;
margin: 0 auto;
border: 1px solid black;
position: relative;
overflow: hidden;
}
.slides {
width: 600px;
height: 100px;
display: flex;
position: absolute;
}
.slide {
width: 200px;
height: 100px;
display: flex;
justify-content: center;
align-items: center;
}
.slide:nth-child(1) {
background-color: rgb(200, 200, 200);
}
.slide:nth-child(2) {
background-color: rgb(150, 150, 150);
}
.slide:nth-child(3) {
background-color: rgb(100, 100, 100);
}
<!DOCTYPE html>
<html>
<body>
<div class="slider">
<div class="slides">
<div class="slide">Slide 1</div>
<div class="slide">Slide 2</div>
<div class="slide">Slide 3</div>
</div>
</div>
</body>
</html>
Thanks for your time :)
I think nobody has checked my question but me, however, assuming there's a hypothetical person having the same problem as mine, I could fix that:
I figured out how to make a JavaScript slider using this post in which the author has used preventDefault() inside "touchstart" EventListener and I stuck to it, but the solution is to simply call preventDefault() method on "touchmove" event itself not "touchstart", off course if you need (which is if the user's trying to change slides). and if user's trying to scroll the page then remove "touchend" EventListener.
const slides = document.querySelector(".slides");
let posX1,
posX2,
posY1,
posY2,
dX,
dY,
dirDetected = false;
//feature detection
//-------------Note 1-----------//
let passiveIfSupported = false;
try {
window.addEventListener("test", null, Object.defineProperty({}, "passive", {
get: function() {passiveIfSupported = {passive: false};}
}));
} catch(err) {}
slides.addEventListener("touchstart", dragStart, passiveIfSupported);
slides.addEventListener("touchmove", dragAction, passiveIfSupported);
slides.addEventListener("touchend", dragEnd, false);
function dragStart(e) {
posX1 = e.touches[0].clientX;
posY1 = e.touches[0].clientY;
}
function dragAction(e) {
//-------------Note 2-----------//
e.preventDefault();
posX2 = e.touches[0].clientX;
posY2 = e.touches[0].clientY;
dX = posX2 - posX1;
posX1 = e.touches[0].clientX;
dY = posY2 - posY1;
if (!dirDetected) {
if (Math.abs(dY) > Math.abs(dX)) {
slides.removeEventListener("touchmove", dragAction, passiveIfSupported);
return;
}
dirDetected = true;
}
slides.style.left = (slides.offsetLeft + dX) + "px";
}
function dragEnd() {
if (!dirDetected) {
slides.addEventListener("touchmove", dragAction, passiveIfSupported);
}
dirDetected = false;
}
body {
padding-bottom: 1000px;
}
.slider {
width: 200px;
height: 100px;
margin: 0 auto;
border: 1px solid black;
position: relative;
overflow: hidden;
}
.slides {
width: 600px;
height: 100px;
display: flex;
position: absolute;
}
.slide {
width: 200px;
height: 100px;
display: flex;
justify-content: center;
align-items: center;
}
.slide:nth-child(1) {
background-color: rgb(200, 200, 200);
}
.slide:nth-child(2) {
background-color: rgb(150, 150, 150);
}
.slide:nth-child(3) {
background-color: rgb(100, 100, 100);
}
<!DOCTYPE html>
<html>
<body>
<div class="slider">
<div class="slides">
<div class="slide">Slide 1</div>
<div class="slide">Slide 2</div>
<div class="slide">Slide 3</div>
</div>
</div>
</body>
</html>
Note 1. (addEventListener's third parameter): note the third parameter of addEventListener() method. there's something I realized in my searches from this question. I'm going to use preventDefault() inside "touchmove" EventListener but in some versions of Chrome and Firefox for "touchstart" and "touchmove" events if you don't specify passive property of options object (the third parameter of addEventListener()) the default value would be set to true and this doesn't let the EventListener to call preventDefault() so you have to set the third parameter to {passive: false} but if the browser loading your script is an old one which requires a third boolean parameter for addEventListener() then you need to provide a boolean value not object. So you can use feature detection to provide an appropraite parameter.
Note 2. Firefox and chrom android handle "touchmove" preventDefault() differently: Here's another point I found (from this question), if you run the above code on Chrome Android it works well, you can scroll the page or change slides but on Firefox Android you can't scroll. Actually I think it's a Chrome's fault because according to Specs for "touchmove" event if the first "touchmove" event is prevented the subsequent "touchmove" events bound to the same touch point are prevented and in the code above at the very first line of "touchmove" event handler function I used preventDefault() so I need to call it after the if block so ensure default behaviour is prevented when needed.
const slides = document.querySelector(".slides");
let posX1,
posX2,
posY1,
posY2,
dX,
dY,
dirDetected = false;
//feature detection
let passiveIfSupported = false;
try {
window.addEventListener("test", null, Object.defineProperty({}, "passive", {
get: function() {passiveIfSupported = {passive: false};}
}));
} catch(err) {}
slides.addEventListener("touchstart", dragStart, passiveIfSupported);
slides.addEventListener("touchmove", dragAction, passiveIfSupported);
slides.addEventListener("touchend", dragEnd, false);
function dragStart(e) {
posX1 = e.touches[0].clientX;
posY1 = e.touches[0].clientY;
}
function dragAction(e) {
posX2 = e.touches[0].clientX;
posY2 = e.touches[0].clientY;
dX = posX2 - posX1;
posX1 = e.touches[0].clientX;
dY = posY2 - posY1;
if (!dirDetected) {
if (Math.abs(dY) > Math.abs(dX)) {
slides.removeEventListener("touchmove", dragAction, passiveIfSupported);
return;
}
e.preventDefault();
}
dirDetected = true;
slides.style.left = (slides.offsetLeft + dX) + "px";
}
function dragEnd() {
if (!dirDetected) {
slides.addEventListener("touchmove", dragAction, passiveIfSupported);
}
dirDetected = false;
}
body {
padding-bottom: 1000px;
}
.slider {
width: 200px;
height: 100px;
margin: 0 auto;
border: 1px solid black;
position: relative;
overflow: hidden;
}
.slides {
width: 600px;
height: 100px;
display: flex;
position: absolute;
}
.slide {
width: 200px;
height: 100px;
display: flex;
justify-content: center;
align-items: center;
}
.slide:nth-child(1) {
background-color: rgb(200, 200, 200);
}
.slide:nth-child(2) {
background-color: rgb(150, 150, 150);
}
.slide:nth-child(3) {
background-color: rgb(100, 100, 100);
}
<!DOCTYPE html>
<html>
<body>
<div class="slider">
<div class="slides">
<div class="slide">Slide 1</div>
<div class="slide">Slide 2</div>
<div class="slide">Slide 3</div>
</div>
</div>
</body>
</html>

Vertical dragBar for resizing two divs

I wanted a vertical dragBar for resizing two divs. I have created an example for the same but I am facing an issue.
Actual : As and when I resize the the upper div and move the slider down, the area of parent div increases and hence a scroll bar is given.
Expected: When Resizing, if the slider is moved down, it should only show the data contained in the upper div and when slider is moved up, it should show the content of lower div and should not increase the over all length of the parent div.
var handler = document.querySelector('.handler');
var wrapper = handler.closest('.wrapper');
var boxA = wrapper.querySelector('.box1');
var boxB = wrapper.querySelector('.box2');
var isHandlerDragging = false;
document.addEventListener('mousedown', function(e) {
// If mousedown event is fired from .handler, toggle flag to true
if (e.target === handler) {
isHandlerDragging = true;
}
});
document.addEventListener('mousemove', function(e) {
// Don't do anything if dragging flag is false
if (!isHandlerDragging) {
return false;
}
// Get offset
var containerOffsetTop= wrapper.offsetTop;
var containerOffsetBottom= wrapper.offsetBottom;
// Get x-coordinate of pointer relative to container
var pointerRelativeXpos = e.clientY - containerOffsetTop;
var pointerRelativeXpos2 = e.clientY - e.offsetTop + e.offsetHeight;
var boxAminWidth = 30;
boxA.style.height = (Math.max(boxAminWidth, pointerRelativeXpos - 2)) + 'px';
boxA.style.flexGrow = 0;
boxB.style.height = (Math.max(boxAminWidth, pointerRelativeXpos2 - 8)) + 'px';
boxB.style.flexGrow = 0;
});
document.addEventListener('mouseup', function(e) {
// Turn off dragging flag when user mouse is up
isHandlerDragging = false;
});
body {
margin: 40px;
}
.wrapper {
background-color: #fff;
color: #444;
/* Use flexbox */
}
.box1, .box2 {
background-color: #444;
color: #fff;
border-radius: 5px;
padding: 20px;
font-size: 150%;
margin-top:2%;
/* Use box-sizing so that element's outerwidth will match width property */
box-sizing: border-box;
/* Allow box to grow and shrink, and ensure they are all equally sized */
}
.handler {
width: 20px;
height:7px;
padding: 0;
cursor: ns-resize;
}
.handler::before {
content: '';
display: block;
width: 100px;
height: 100%;
background: red;
margin: 0 auto;
}
<div class="wrapper">
<div class="box1">A</div>
<div class="handler"></div>
<div class="box2">B</div>
</div>
Hope I was clear in explaining the issue I am facing in my project. Any help is appreciated.
It looks like your on the right track. You just need to make the wrapper a flexbox with the flex direction column and assign it a height. Also box 2 needs to have a flex of 1 so it can grow and shrink as needed. Finally I needed to remove the code that set the flex grow to 0 in the JavaScript. Here is the result.
var handler = document.querySelector('.handler');
var wrapper = handler.closest('.wrapper');
var boxA = wrapper.querySelector('.box1');
var boxB = wrapper.querySelector('.box2');
var isHandlerDragging = false;
document.addEventListener('mousedown', function(e) {
// If mousedown event is fired from .handler, toggle flag to true
if (e.target === handler) {
isHandlerDragging = true;
}
});
document.addEventListener('mousemove', function(e) {
// Don't do anything if dragging flag is false
if (!isHandlerDragging) {
return false;
}
e.preventDefault();
// Get offset
var containerOffsetTop= wrapper.offsetTop;
var containerOffsetBottom= wrapper.offsetBottom;
// Get x-coordinate of pointer relative to container
var pointerRelativeXpos = e.clientY - containerOffsetTop;
var pointerRelativeXpos2 = e.clientY - e.offsetTop + e.offsetHeight;
var boxAminWidth = 30;
boxA.style.height = (Math.max(boxAminWidth, pointerRelativeXpos - 2)) + 'px';
boxB.style.height = (Math.max(boxAminWidth, pointerRelativeXpos2 - 8)) + 'px';
});
document.addEventListener('mouseup', function(e) {
// Turn off dragging flag when user mouse is up
isHandlerDragging = false;
});
body {
margin: 40px;
}
.wrapper {
background-color: #fff;
color: #444;
/* Use flexbox */
display: flex;
flex-direction: column;
height: 200px;
}
.box1, .box2 {
background-color: #444;
color: #fff;
border-radius: 5px;
padding: 20px;
font-size: 150%;
margin-top:2%;
/* Use box-sizing so that element's outerwidth will match width property */
box-sizing: border-box;
/* Allow box to grow and shrink, and ensure they are all equally sized */
}
.box2 {
flex: 1;
}
.handler {
width: 20px;
height:7px;
padding: 0;
cursor: ns-resize;
}
.handler::before {
content: '';
display: block;
width: 100px;
height: 100%;
background: red;
margin: 0 auto;
}
<div class="wrapper">
<div class="box1">A</div>
<div class="handler"></div>
<div class="box2">B</div>
</div>

Show logo if site has scrolled

I have a header with a logo. This logo should appear only if the site has been scrolled.
I tried this in javascript:
if(document.getElementById("div").scrollTop != 0){
document.write("<img src='logo.jpg'>");
}
But this did not work.
How to achieve it?
Use window.addEventListener('scroll', callback) and then set the value "block" to the img's property.
window.addEventListener('scroll', function(e) {
if (document.getElementsByTagName("html")[0].scrollTop > 5) {
document.getElementsByClassName('imgHeader')[0].style.display = "block";
} else {
document.getElementsByClassName('imgHeader')[0].style.display = "none";
}
});
.imgHeader {
height: 100px;
width: 100px;
display: none;
}
div {
height: 1000px;
}
header {
position: fixed;
top: 0;
width: 100%;
}
<header><img class="imgHeader" src="https://material.angular.io/assets/img/examples/shiba1.jpg" /></header>
<div></div>
Try this one
$(document).on("scroll", function() {
if ($(document).scrollTop() > 5) {
$(".below-top-header").addClass("show-class");
} else {
$(".below-top-header").removeClass("show-class");
}
});
.content {
height: 500px;
}
.show-class {
position: fixed;
display: block !important;
}
.hide-class {
display: none;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="content">
<div class="below-top-header hide-class">
Image
</div>
</div>
Unfortunately, I think you must use some JavaScript to make it work like you want.
Here is an easy snippet to show the principle I used:
Start with the logo already in the html, but with display: none in its CSS,
Use window.addEventListener('scroll', callback) to change display: none to display: block when the page is scrolled down (i.e. document.documentElement.scrollTop > 0).
var logo = document.getElementById('logo');
window.addEventListener('scroll', function(e) {
if (document.documentElement.scrollTop > 0) {
logo.style.display = 'block';
}else logo.style.display = 'none';
});
#logo {
display: none;
position: fixed;
top: 0;
background: #aaa;
}
#page {
background: #ddd;
height: 2000px;
}
<div id='logo'><img src='http://placekitten.com/200/50'></div>
<div id='page'>Start of page<br>Try to scroll down</div>
Hope it helps.
You need to add an scrollListener to the window in order to execute code when the user scrolls.
Your code only gets executed on page load.
Informations on Eventlisteners: https://developer.mozilla.org/de/docs/Web/API/EventTarget/addEventListener
window.addEventListener('scroll', function(e) {
//do something as soon as the window was scrolled
});
Be aware that the event will be triggered each time the user scrolls.

Img resize on scroll

How can i resize a logo( es width: 100px ) in a header on mouse scrolling?
$('.logo').scroll(function() {
$(this).width(100);
$(this).off(); //removes the handler so that it only resizes once...
})
.header {
background-color: black;
}
.logo {
height:100px;
width: 100%;
background-image: url("http://unika.myarmah.it/skin/frontend/sns_simo/default/images/logo.png");
background-repeat: no-repeat;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="header">
<div class="logo"></div>
</div>
Just use javascript:
Why? - Because its just as short as using jQuery.
Update #1 -
after seeing the comments to the previous answer from the author, I have adjusted my example to include animation and reset when at the top of the page. Again - just use javascript, and for better performance benefits use CSS classes so that all paints are done in one cycle.
Update #1 jsfiddle - https://jsfiddle.net/113dn29z/16/
var logo = document.querySelector('.logo');
var handleResize = function(e) {
if (document.body.scrollTop === 0) {
logo.classList.remove("resize");
} else {
logo.classList.add("resize");
}
};
document.addEventListener('scroll', handleResize);
<div class="header">
<div class="logo">
</div>
</div>
body {
height: 9999px;
overflow: auto;
}
.header {
background-color: black;
}
.logo {
margin-top: 200px;
height:100px;
width: 100%;
background-color: red;
background-repeat: no-repeat;
transition: width 0.2s ease;
}
.logo.resize {
width: 100px;
}
old jsFiddle example - https://jsfiddle.net/113dn29z/10/
var logoHasResized = false;
$(document).on('scroll', function (e) {
if (window.scrollY == 0) {
$('.logo').animate({'width': '100%'}, 250);
logoHasResized = false;
} else if (logoHasResized == false) {
$('.logo').animate({'width': 100}, 250);
logoHasResized = true;
}
});
edit: Since you want it to go back when you scroll to the top of the page, i've added in a check to see if the animation has happened, as you don't want it to fire constantly.

Categories

Resources