I have a a page with a textarea in between fixed headers and a fixed footer. I use some jquery to ensure the viewport shows the new textarea lines at the bottom as you type. Without the fixed footer (white background), the jquery works as it supposed to and the new lines stay in view as you type at the bottom. But with the fixed footer, I have to manually scroll to see the new content at the bottom. It is hidden behind the footer. I have found that if I hit enter while I type however, it will auto scroll the content to stay in view even with the footer. But if I type continuously, I have to scroll to see the new hidden content. I want to have the fixed footer and auto scroll down in the textarea so the new content is always showing above the fixed footer, no matter how much is typed. How can I accomplish this?
$(document).ready(function() {
$('#close-post-modal').click(function() {
$("#main-container").load("mobile/mobile.view.php");
$("#main-content-mobile").load("mobile/feed.php");
document.location.hash = "feed";
});
$('#post-comment-textarea-mobile').on('input', function() {
this.style.height = 'auto';
this.style.height = (this.scrollHeight) + 'px';
});
});
#post-comment-textarea-mobile {
border: none;
overflow: auto;
outline: none;
resize: none;
width: 100%;
}
#post-modal-header {
position: fixed;
top: 0;
}
#post-modal-sub-header {
position: fixed;
}
#post-modal-footer {
position: fixed;
bottom: 0;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="width-100p">
<div id="post-modal-header" class="bg-white width-100p height-2r space-evenly-x padding-top-1">
<div id="close-post-modal">X</div>
<div>New Post</div>
<div id="save-post-modal">Save</div>
</div>
<div id="post-modal-sub-header" class="bg-white padding-left-1 width-100p height-2r left padding-top-2">
<div class="padding-right-5px">Image</div>
<div>Username</div>
</div>
<div class="padding-left-2 padding-right-2 padding-bottom-1 padding-top-5">
<textarea id="post-comment-textarea-mobile" placeholder="Your Thoughts?"></textarea>
</div>
<div id="post-modal-footer" class="bg-white width-100p space-evenly-x padding-top-2 padding-bottom-1">
<div>Image</div>
<div>Video</div>
<div>Tag</div>
</div>
</div>
I was able to get it to work by adding 100 to the scroll height for the textarea height AND window.scrollTo on input to the textarea's ScrollHeight.
I'm not sure if the 100 is the needed number, you can play with that with your design, its one that worked for me.
$(document).ready(function() {
$('#close-post-modal').click(function() {
$("#main-container").load("mobile/mobile.view.php");
$("#main-content-mobile").load("mobile/feed.php");
document.location.hash = "feed";
});
$('#post-comment-textarea-mobile').on('input', function() {
this.style.height = 'auto';
this.style.height = (this.scrollHeight + 100) + 'px';
window.scrollTo(0,document.querySelector("#post-comment-textarea-mobile").scrollHeight);
});
});
body{padding:0;}
#post-comment-textarea-mobile {
border: none;
overflow: auto;
outline: none;
resize: none;
width: 100%;
}
#post-modal-header {
position: fixed;
top: 0;
}
#post-modal-sub-header {
position: fixed;
background:#000;
}
#post-modal-footer {
position: fixed;
bottom: 0;
width:100%;
background:#000;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="width-100p">
<div id="post-modal-header" class="bg-white width-100p height-2r space-evenly-x padding-top-1">
<div id="close-post-modal">X</div>
<div>New Post</div>
<div id="save-post-modal">Save</div>
</div>
<div id="post-modal-sub-header" class="bg-white padding-left-1 width-100p height-2r left padding-top-2">
<div class="padding-right-5px">Image</div>
<div>Username</div>
</div>
<div class="padding-left-2 padding-right-2 padding-bottom-1 padding-top-5">
<textarea id="post-comment-textarea-mobile" placeholder="Your Thoughts?"></textarea>
</div>
<div id="post-modal-footer" class="bg-white width-100p space-evenly-x padding-top-2 padding-bottom-1">
<div>Image</div>
<div>Video</div>
<div>Tag</div>
</div>
</div>
It's the same problem as with fixed header and html anchors. Properties like fixed, absolute and relative pulls an element out of page flow and places it in another dimension (not a professional term).
Just tell jquery where is the end of view. It believes the view ends at screen end.
Related
I'm trying to make a sticky, transparent div, that changes color based on the div behind it. So, I've got a couple of dark and light div's, and the sticky div should change text-color (white on the dark, black on the light).
In HTML
<div id="sticky">Menu</div>
<div class="content light"></div>
<div class="content dark"></div>
<div class="content light"></div>
<div class="content dark"></div>
<div class="content light"></div>
I've already found a partial solution here:
var stickyOffset = $("#sticky").offset();
var $contentDivs = $(".content");
$(document).scroll(function() {
$contentDivs.each(function(k) {
var _thisOffset = $(this).offset();
var _actPosition = _thisOffset.top - $(window).scrollTop();
if (_actPosition < stickyOffset.top && _actPosition + $(this).height() > 0) {
$("#current").html("Current div under sticky is: " + $(this).attr("class"));
$("#sticky").removeClass("light dark").addClass($(this).hasClass("light") ? "light" : "dark");
return false;
}
});
});
No the problem is, that when my stikcy div get's property top:50%, it doesn't work.
Anyone got a solution?
You don't need JavaScript to do this. Just use mix-blend-mode:
#sticky {
position: fixed;
top: 10px;
left: 10px;
right: 10px;
height: 50px;
color: #fff;
mix-blend-mode: exclusion;
}
I'm currently trying to implement a horizontal scroll. It works, but I'm trying to make some changes:
Since the web-app is a one screener and solely consists of this horizontal scroll, I'd like to convert vertical scroll to horizontal scroll. But how? What's the approach?
I've tried the following js library, but this one solely works if overflow is set to visible, which kind of breaks my app.
My horizontal scroll:
<div class="scroll-container align-self-center d-flex">
<div class="cart-container align-self-center" *ngFor="let cart of carts; let i = index">
<div class="cart-item cursor-hover position-relative" [ngStyle]="{'background-image': 'url(' + cart.image + ')'}" [class.cart-item-even]="i % 2 !== 0"
(mouseenter)="changeBackgroundColor(i)">
<h1 class="hover-title">{{cart.title}}</h1>
</div>
</div>
</div>
CSS:
.cart-item {
background-size: cover;
background-position: center;
background-repeat: no-repeat;
width: 22.5vw;
height: 65vh;
}
.cart-item-even {
height: 55vh;
width: 20vw;
}
.cart-container {
display: inline-block;
}
.scroll-container {
padding: 0 15vw 0 15vw;
box-sizing: border-box;
overflow: auto;
white-space: nowrap;
}
//ts
scroll = () => {
function scrollHorizontally(e) {
e = window.event || e;
var delta = Math.max(-1, Math.min(1, (e.wheelDelta || -e.detail)));
document.getElementById('main-content').scrollLeft -= (delta*40); // Multiplied by 40
e.preventDefault();
}
if (document.getElementById('main-content').addEventListener) {
// IE9, Chrome, Safari, Opera
document.getElementById('main-content').addEventListener("mousewheel", scrollHorizontally, false);
// Firefox
document.getElementById('main-content').addEventListener("DOMMouseScroll", scrollHorizontally, false);
} else {
// IE 6/7/8
// document.getElementById('main-content').attachEvent("onmousewheel", scrollHorizontally);
}
}
ngOnInit(): void {
this.scroll();
}
For an horizontal scrolling you can do whatever you want inside a div like that :
.mydiv {
overflow-x: scroll;
display: -webkit-box;
}
I hope this gonna help you :)
I am using this for my header that changes in a one page scroll up and down page. I noticed that it's not responsive so i am asking you if you maybe know a way to make that responsive. Like changing the 0-690 into a percentage so that it will work on mobile and also on a tv screen.
HTML
<div class="header header-1" data-visible-range="0-690">Portfolio</div>
<div class="header header-2" data-visible-range="691-2100">Services</div>
<div class="header header-3" data-visible-range="2101-">Contact</div>
CSS
.header-1 {
background-color:dimgray;
display: block;
}
.header-2 {
background-color:dimgray;
}
.header-3 {
background-color:dimgray;
}
.header {
position: fixed;
top: 0;
left: 0;
height:8vmax;
width: 100%;
display: none;
visibility:hidden;
transition: visibility .4s, opacity .4s ease-in-out;opacity:0;
font-size:4vmax;padding:1.58vmax;color:white;
}
What if, instead of basing it off pixels, you just checked to see if an element hit the top of the page, and then changed the header?
We'll call these elements "triggers." See my code below for an example of how they work.
let updateHeader = () => {
let scrollTop = $(window).scrollTop(),
triggerTitle = "Hi";
$('.trigger').each((i, el) => {
let topPos = $(el).offset().top,
distance = topPos - scrollTop;
if (distance < 0)
triggerTitle = $(el).data('title');
});
$('header h2').text(triggerTitle);
}
$(window).scroll(updateHeader);
$(window).on('touchmove', updateHeader);
body {
margin: 0;
}
#container {
height: 1000px;
}
header {
width: 100%;
position: fixed;
top: 0;
background-color: red;
}
p {
margin: 200px 10px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="container">
<header><h2>Hi</h2></header>
<p class="trigger" data-title="section1">
trigger1
</p>
<p class="trigger" data-title="section2">
trigger2
</p>
<p class="trigger" data-title="section3">
trigger3
</p>
</div>
As you scroll down the page, each trigger hits the top of the page, and the text in the header will change to the the value of the latest trigger's data-title. You could position these triggers appropriately above each of your website's sections, so that, no matter what size the screen, the header should update at the right time. Here's a codepen.
EDIT
Try this JS instead for maximum compatibility (no es6 involved).
function updateHeader() {
var scrollTop = $(window).scrollTop(),
triggerTitle = "Hi";
$('.trigger').each(function(i, el) {
var topPos = $(el).offset().top,
distance = topPos - scrollTop;
if (distance < 0)
triggerTitle = $(el).data('title');
});
$('header h2').text(triggerTitle);
}
$(window).scroll(updateHeader);
$(window).on('touchmove', updateHeader);
So I have a chat UI that is a box where messages go, and at the bottom of the box of messages is a text input element. It works fine at the beginning, but once enough messages appear then the text input element scrolls up, along with the messages, and will not stay positioned at the bottom. How can I do this? Any useful thoughts would be appreciated.
<html>
<body>
<div id="chatui">
<div id="chatmsgs"></div>
<input type="text" id="chatbox">
</div>
</body>
</html>
Here is my CSS:
#chatui {
z-index:3;
position:absolute;
bottom:5px;
width: 380px;
height: 150px;
border: 3px solid #8AC007;
margin-left:5px;
overflow:auto;
}
#chatbox {bottom:3px;position:absolute;width:378px;}
#chatmsgs {position:absolute;}
Here is my Javascript:
This just says when you press "Enter" on your keyboard to display the text you typed into the "chatmsgs" div.
$(window).keydown(function(e){
if (e.keyCode == 13) {
if (document.activeElement.id == 'chatbox') {
var msg = document.getElementById('chatbox').value;
document.getElementById('chatbox').value = '';
var ms = '<p>'+msg+'</p>';
$('#chatmsgs').append(ms);
}
}
});
Check out this fiddle to see what I am talking about:
https://jsfiddle.net/ev3uymw6/
You have to add overflow:auto and appropriate height to the chatmsgs div, so that it doesn't grow beyond the size of chatui and make it scroll alltogether.
$(window).keydown(function(e) {
if (e.keyCode == 13) {
if (document.activeElement.id == 'chatbox') {
var msg = document.getElementById('chatbox').value;
document.getElementById('chatbox').value = '';
var ms = '<p>' + msg + '</p>';
$('#chatmsgs').append(ms);
}
}
});
#chatui {
z-index: 3;
position: absolute;
bottom: 5px;
width: 380px;
height: 150px;
border: 3px solid #8AC007;
margin-left: 5px;
}
#chatbox {
bottom: 3px;
position: absolute;
width: 378px;
}
#chatmsgs {
position: absolute;
height: 130px;
overflow: auto;
width: 378px
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<body>
<div id="chatui">
<div id="chatmsgs">
</div>
<input type="text" id="chatbox">
</div>
</body>
The site below uses a fixed background-image in each section, but how do I add fixed content (text, images) to each sections and keep the same scrolling effect?
http://tympanus.net/Blueprints/ScrollingLayout/
Have a look at my example to get a better idea of what I want:
http://jsfiddle.net/w919y0gb/
My try:
#wrapper {
position: relative;
height: 500px;
width: 500px;
overflow: scroll;
}
.section {
position: relative;
height: 100%;
width: 100%;
}
.content {
position: fixed;
}
#s1 {
background-color: #f00;
}
#s2 {
background-color: #0f0;
}
#s3 {
background-color: #00f;
}
#s1 .content {
}
#s2 .content {
margin-top: -400px;
}
#s3 .content {
margin-top: -800px;
}
<div id="wrapper">
<div class="section" id="s1">
<div class="content">hello1</div>
</div>
<div class="section" id="s2">
<div class="content">hello2</div>
</div>
<div class="section" id="s3">
<div class="content">hello3</div>
</div>
</div>
What I want:
The first section (red) should only display "hello1"
The second (green) only "hello2"
The third (blue) only "hello3"
something like this maybe? little hacky, but does the trick if you have set section heights:
$(document).ready(function(){
$('.div3').hide();
$('.div2').hide();
$('.div1').show();
$('#wrapper').scroll(function(){
console.log($('#wrapper').scrollTop());
if($('#wrapper').scrollTop() > 945){
$('.div3').show();
$('.div2').hide();
$('.div1').hide();
}
else if ($('#wrapper').scrollTop() > 465) {
$('.div3').hide();
$('.div2').show();
$('.div1').hide();
}
else {
$('.div3').hide();
$('.div2').hide();
$('.div1').show();
}
});
});
updated fiddle: http://jsfiddle.net/w919y0gb/3/
with this, you could also modify the placement of the "hello1/hello2/hello3" to be in the same position instead of in different places. or you could just have one div in which you modify/replace the text from hello1/hello2/hello3 depending on the scroll position. hope this helps!
That reference site is simply using a background-image set to fixed like so:
FIDDLE
UPDATE
Ok I understand. You would need to do something like this with jquery and $(window).scroll() function:
NEW FIDDLE
using positon: fixed just breaks the element out of the flow of the document and it can't be contained by a parent so you need to use absolute and position it based on the scrollTop to give the appearance that it's fixed.
You could also set the height of your webpage, and then make divs appear as you scroll up or down.
Heres a working example: http://jsfiddle.net/ZyKar/1738/
$(document).scroll(function () {
var y = $(this).scrollTop();
if (y > 0 && y < 400) {
$('#s1').fadeIn();
$('#s3').fadeOut();
$('#s2').fadeOut();
} else if (y > 400 && y < 800) {
$('#s1').fadeOut();
$('#s2').fadeIn();
$('#s3').fadeOut();
}else if (y > 800) {
$('#s3').fadeIn();
$('#s2').fadeOut();
}
});
After you scroll a certain amount of pixels, divs will begin to appear and replace each other.
You may alter the value of y by setting the height of your body in css, as shown in the fiddle. You can then set the pixels conditions in the jQuery to whatever you like.