How to find current div element's id on scrolling container - javascript

We have a div with fixed size with scroll auto, inside it we have another div bigger than the parent (wrapper) and inside it, more div elements(See example)
Is there a ready solution to find the div element's id in the position we scrolled to?
<div id="main">
<div id="content">
<div id="1" class="inner-content">1</div>
<div id="2" class="inner-content">2</div>
<div id="3" class="inner-content">3</div>
<div id="4" class="inner-content">4</div>
<div id="5" class="inner-content">5</div>
<div id="6" class="inner-content">6</div>
<div id="7" class="inner-content">7</div>
<div id="8" class="inner-content">8</div>
</div>
</div>
#main {
width: 700px;
height: 400px;
border: 1px solid black;
overflow: auto;
}
#content {
width: 10000px;
height: 10000px;
overflow: hidden;
}
.inner-content {
width: 900px;
height: 300px;
border: 1px solid black;
display: inline-block;
}
jsfiddle.net/VJ3QC/4/
For example I scrolled right on div element with id 4, is it possible to return, with JavaScript or JQuery, the id of this element? After that I scrolled left on element with id 7 can I return this element's id?
Thx!

If each of your inner-content divs are always going to be the same width you could work out which one is visible using the offset() property/function when the user scrolls the element.
Something like this..
var prev_id;
$('#main').scroll(function(){
var element_width = 400;
var offset = $('#content').offset();
var positive = Math.abs(offset.left)
var divided = positive / element_width;
var round = Math.round(divided);
var current_element = $('#content').children().eq(round);
var id = current_element.attr('id');
if(id != prev_id){
prev_id = id;
alert(id);
}
});
The little prev_id var and the if statement just make it so that it only alerts once when the id changes.
The example isn't perfect as there are margins and borders which mean the id changes before the element is completely visible. but the logic is there - http://jsfiddle.net/VJ3QC/9/

It is easy. Just use my code. When you will scroll each element will be determined and then will set class "active" to current element .
scrollspy = function(settings) {
var That = this;
elS = [];
Options = {
class: "scrollspy",
classActive: "active",
paddingTop: 0,
infinity: false
};
Options.paddingTop = window.innerHeight - Options.paddingTop;
Object.assign(Options, settings);
$(document).find('.'+Options.class).each(function(e) {
elS.push($(this)[0]);
});
$(document).on('scroll', function(){
if(Options.infinity){
$('.'+Options.class+'.'+Options.classActive).removeClass(Options.classActive);
}
for(var i=0; i<elS.length; i++){
if($(this).scrollTop() + Options.paddingTop >= That.elS[i].offsetTop && $(this).scrollTop() <= (That.elS[i].offsetTop + That.elS[i].offsetHeight)){
if(!$(That.elS[i]).hasClass(Options.classActive)){
$(That.elS[i]).addClass(Options.classActive);
}
}
}
});
}
scrollspy();

Related

How to create a horizontal, circular/scrollable menu?

How can we make a horizontal row of link elements (with variable width/text length) with overflow hidden (or without, depending on how this is usually done..) function so that the last element is positioned behind the first and so on in each left or right direction, to create a circular scroll?
I have this so far:
const horizontalContainer = document.querySelector('.horizontal-container')
const horizontalLinks = document.querySelectorAll('.horizontal-link')
let touchStart = 0
let touchX = 0
let isDragging = false
const handleTouchStart = (e) => {
touchStart = e.clientX || e.touches[0].clientX
isDragging = true
}
const handleTouchMove = (e) => {
if (!isDragging) return
touchX = e.clientX || e.touches[0].clientX
touchStart = touchX
horizontalLinks.forEach(element => {
element.style.transform = "translate(" + (touchStart) + "px," + "0px)";
})
}
const handleTouchEnd = () => {
isDragging = false
}
horizontalContainer.addEventListener('mousedown', handleTouchStart)
horizontalContainer.addEventListener('mousemove', handleTouchMove)
horizontalContainer.addEventListener('mouseleave', handleTouchEnd)
horizontalContainer.addEventListener('mouseup', handleTouchEnd)
horizontalContainer.addEventListener('selectstart', () => { return false })
.horizontal-container {
display: flex;
overflow-x: hidden;
width: 100%;
}
.horizontal-container::-webkit-scrollbar {
display: none;
}
.horizontal-link {
padding-left: 20px;
padding-right: 20px;
right: 0;
}
<div class="horizontal-container">
<div class="horizontal-link">
ONE
</div>
<div class="horizontal-link">
TWO
</div>
<div class="horizontal-link">
THREE
</div>
<div class="horizontal-link">
FOUR
</div>
<div class="horizontal-link">
FIVE
</div>
</div>
Edit: Unless you have the time to show me an example, I'm more than happy with just an explanation for how this can be done calculating translate: transform(x,y) to reposition the links when the left or right position of a link div of variable width reaches the right or left position of the screen depending on the screen width, which can also be variable, so that what the exact amount of overflow that peeks outside the viewport on the right will peek out the same amount on the left side of the viewport.
Edit2: Even though I know little about programming or the Javascript language (yet) I do know that this is not a "carousel" which is much easier to implement, that I already have created on my own so I know every detail of it. And a scrollbar is also programmed to move between a left end or right end position - this cannot be used here without a lot of ugly hacks so a new scrolling function needs to be implemented from scratch. I also know that jQuery will not help me to understand or learn more, and that this is nothing one would use - ever - whether you are an amateur or not.
What you are requesting is a carousel pattern. You can configure a carousel to show multiple slides at once. In this case each "slide" would be a menu item.
I have mocked up an example using https://kenwheeler.github.io/slick/
The only downfall is that it snaps to each slide, which may or may not be what you want. If it is not what you want then you would be best looking at other slider alternatives.
But the main point is that what you are requesting is normally done with a slider/carousel pattern. You just need to look at it differently, and you are not limited to show one "slide" at a time.
<link rel="stylesheet" type="text/css" href="//cdn.jsdelivr.net/npm/slick-carousel#1.8.1/slick/slick.css"/>
<div class="menu-slider" style="width: 400px;">
<div style="padding:20px;">Link 1</div>
<div style="padding:20px;">Another Link 2</div>
<div style="padding:20px;">Yet Another Link 3</div>
<div style="padding:20px;">Menu Link 4</div>
<div style="padding:20px;">Link 5</div>
<div style="padding:20px;">Menu Link 6</div>
</div>
<script type="text/javascript" src="https://code.jquery.com/jquery-1.11.0.min.js"></script>
<script type="text/javascript" src="https://code.jquery.com/jquery-migrate-1.2.1.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/slick-carousel#1.8.1/slick/slick.min.js"></script>
<script type="text/javascript">
$(document).ready(function(){
$('.menu-slider').slick({
dots: false,
infinite: true,
centerMode: false,
variableWidth: true
});
});
</script>
Here's a working solution for one that will "fill" its parent in order to create the effect.
I was working on an alternative that didn't fill but it still needs more work.
$(function () {
init();
});
let base_width = 0;
function init() {
setupMenu();
}
function handleScroll(event) {
if (base_width === 0) {
// no need to do anything
return;
}
const $menu = $(event.currentTarget);
const scroll_left = $menu[0].scrollLeft;
// check backwards scroll
if (scroll_left <= base_width) {
const new_left = 2 * base_width - (base_width - scroll_left);
$menu[0].scrollLeft = new_left;
return;
}
if (scroll_left < base_width * 2) {
return;
}
// get remainder
const new_left = scroll_left % (base_width * 2);
$menu[0].scrollLeft = new_left + base_width;
}
function setupMenu() {
const $menu = $("#menu-fill");
const $parent = $menu.parent();
const menu_width = $menu.width();
const parent_width = $parent.width();
if (menu_width >= parent_width) {
// no need to duplicate
return;
}
base_width = menu_width;
// setup a base to clone
const $template = $menu.clone();
// get num times to duplicate to "fill" menu (i.e. allow scrolling)
// NOTE: we duplicate 1 "extra" so that we can scroll "backwards"
const num_duplicate = Math.ceil(parent_width / menu_width) + 2;
for (let i = 0; i < num_duplicate; i++) {
const $new_menu = $template.clone();
$menu.append($new_menu.children());
$new_menu.remove();
}
$menu[0].scrollLeft = base_width;
$menu.scroll(handleScroll)
}
* {
box-sizing: border-box;
font-family: sans-serif;
}
*::-webkit-scrollbar {
background-color: transparent;
height: 6px;
width: 6px;
border-radius: 3px;
}
*::-webkit-scrollbar-thumb {
background-color: #ccc;
border-radius: 3px;
}
html,
body {
width: 100%;
height: 100%;
padding: 0;
margin: 0;
}
.wrap {
width: 250px;
height: 100px;
border: 2px solid #777;
margin: 0 auto 20px auto;
}
.wrap.fill {
width: 500px;
}
.menu {
display: inline-flex;
max-width: 100%;
overflow: auto;
}
.item {
padding: 5px 10px;
background-color: #426ac0;
color: #fff;
border-right: 1px solid #1d3464;
white-space: nowrap;
}
.item:last-child {
border-right: none;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="wrap fill">
<div class="menu" id="menu-fill">
<div class="item">Item 1</div>
<div class="item">Number 2</div>
</div>
</div>

How to use scrollTo() function in Vanilla JS?

What's wrong with my code? scrollTo() goes to the wrong position when I click and anchor with href value using hash # (div element ID).
This is my code, I just want to scroll to the comment element, but still overlap on the fixed header (bootstrap 5 fixed header).
if (document.querySelectorAll('a').length) {
document.querySelectorAll('a').forEach( anchor => {
anchor.addEventListener('click', event => {
let URL = event.target.href.split('#');
if (typeof URL[1] != undefined) {
let element = document.getElementById(URL[1]);
let offset = element.offsetTop;
let navigation = document.getElementById('main-navigation').clientHeight
let scroll = offset - navigation;
window.scrollTo(0, scroll);
}
});
});
}
Anyone can help me?
Call event.preventDefault() in the click handler, otherwise after your call to scrollTo, the page's hash will change, with an automatic scroll to the anchored element overriding yours.
document.querySelectorAll('a').forEach( anchor => {
anchor.addEventListener('click', event => {
let URL = event.target.href.split('#');
if (typeof URL[1] != undefined) {
let element = document.getElementById(URL[1]);
let offset = element.offsetTop;
let navigation = document.querySelector('.over').clientHeight
let scroll = offset - navigation;
window.scrollTo(0, scroll);
event.preventDefault(); // avoid internal scroll to anchor
}
});
});
.over {
height: 50px;
background: salmon;
position: sticky;
top: 0;
}
#foo {
margin-top: 250vh;
height: 250vh;
}
#foo
<div class="over"></div>
<div id="foo">Target element</div>
You can achieve that by using the scrollIntoView() function. see the below example. you have to target the element to scroll:
let i = 0;
function myFunction() {
if(i === 0){
const elmnt = document.getElementById("content");
elmnt.scrollIntoView();
i += 1
}
else {
const elmnt = document.getElementById("content2");
elmnt.scrollIntoView();
}
}
#myDIV {
height: 250px;
width: 250px;
overflow: auto;
background: green;
}
#content {
margin:500px;
height: 800px;
width: 2000px;
background-color: coral;
}
#content2 {
margin:500px;
height: 800px;
width: 2000px;
background-color: red;
}
<p>Click the button to scroll to section.</p>
<button onclick="myFunction()">Scroll</button>
<div id="myDIV">
<div id="content">
Some text inside an element.
</div>
<div id="content2">
Some text inside an element.
</div>
</div>
Most importantly you need to stop the default behavior. When an internal link is clicked the default action is to jump to that link. You need to override that.
Next, we can make a couple of little tweaks. First, only select internal links with an attribute selector that selects a tags where the href start with "#". Next, instead of splitting the url from the href, grab the raw value directly from the attribute.
//Get internal links
document.querySelectorAll("a[href^='#']").forEach(function(el) {
el.addEventListener("click", function(e) {
//Stops the inbuild scroll
e.preventDefault();
//Get the id straight from the attribute
let selector = this.getAttribute("href");
//Get the target element
let element = document.querySelector(selector);
//you know the rest
let offset = element.offsetTop;
let navigation = document.getElementById('main-navigation').clientHeight
let scroll = offset - navigation;
window.scrollTo(0, scroll);
});
});
/*CSS Purely for demo purposes.*/
.fixed-top {
background-color: #EEE;
padding: 15px;
}
article:first-of-type{
margin-top:90px;
}
article {
min-height: 50vh;
border-bottom: 1px solid black;
}
nav {
background-color: #ECECEC;
}
<link href="https://cdn.jsdelivr.net/npm/bootstrap#5.0.2/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-EVSTQN3/azprG1Anm3QDgpJLIm9Nao0Yz1ztcQTwFspd3yD65VohhpuuCOmLASjC" crossorigin="anonymous">
<div class="fixed-top" id="main-navigation">Some Top Stuff
<nav>
Article 1
Article 2
Article 3
</nav>
</div>
<article id="art1">
<h1>Article 1</h1>
</article>
<article id="art2">
<h1>Article 2</h1>
</article>
<article id="art3">
<h1>Article 3</h1>
</article>

How detect which child element is visible after scrolling the parent div?

I would like to emulate something like "current page" using divs (like a PDF reader)
document.addEventListener("DOMContentLoaded", function(event) {
var container = document.getElementById("container");
container.onscroll = function() {
let position = container.scrollTop;
let divs = document.querySelectorAll('.page');
for (div of divs) {
//???
}
}
});
#container {
width: 400px;
height: 600px;
overflow: auto;
}
.page {
width: 400px;
}
.red {
background-color: red;
height: 600px;
}
.blue {
background-color: blue;
height: 400px;
}
Current page: <span id="page-counter">1</span>
<div id='container'>
<div id="div-1" class="page red"></div>
<div id="div-2" class="page blue"></div>
<div id="div-3" class="page red"></div>
<div id="div-4" class="page blue"></div>
</div>
So, I would like to know the best way to, for example, change span page-counter text to "3" when the third div "appears".
Something like this: https://i.imgur.com/rXQ2Bw8.png
Thanks in advance
Celso
Since this question never tagged jQuery, here's a pure Javascript solution that simulates the behavior you're looking for to the best of my knowledge. The solution calculates the amount of pixels of each child element currently visible within the container. If the amount is bigger or equal to half the size of the container, it assumes this is the page your visitor is looking at.
function getVisibleHeight(element){
const container = document.getElementById("container");
let scrollTop = container.scrollTop;
let scrollBot = scrollTop + container.clientHeight;
let containerRect = container.getBoundingClientRect();
let eleRect = element.getBoundingClientRect();
let rect = {};
rect.top = eleRect.top - containerRect.top,
rect.right = eleRect.right - containerRect.right,
rect.bottom = eleRect.bottom - containerRect.bottom,
rect.left = eleRect.left - containerRect.left;
let eleTop = rect.top + scrollTop;
let eleBot = eleTop + element.offsetHeight;
let visibleTop = eleTop < scrollTop ? scrollTop : eleTop;
let visibleBot = eleBot > scrollBot ? scrollBot : eleBot;
return visibleBot - visibleTop;
}
document.addEventListener("DOMContentLoaded", function(event) {
const container = document.getElementById("container");
const divs = document.querySelectorAll('.page');
container.addEventListener("scroll", () => {
for(let i=0; i<divs.length; i++){
const containerHeight = container.clientHeight;
// Gets the amount of pixels currently visible within the container
let visiblePageHeight = getVisibleHeight(divs[i]);
// If the amount of visible pixels is bigger or equal to half the container size, set page
if(visiblePageHeight >= containerHeight / 2){
document.getElementById('page-counter').innerText = i+1;
}
}
}, false);
});
#container {
width: 400px;
height: 300px;
overflow: auto;
}
.page {
width: 380px;
}
.red {
background-color: red;
height: 300px;
}
.blue {
background-color: blue;
height: 200px;
}
Current page: <span id="page-counter">1</span>
<div id='container'>
<div id="div-1" class="page red"></div>
<div id="div-2" class="page blue"></div>
<div id="div-3" class="page red"></div>
<div id="div-4" class="page blue"></div>
</div>
The general approach here would be to write a function that determines if a given HTML element is in the viewport. You could run the check as the user scrolls. See the snippet below for an example with jQuery. I'm not necessarily saying this is the best way to do this, but it seems to be working. Start scrolling to see the IDs appear.
function isInViewPort(element) {
// Function will determine if any part of the element is in the viewport.
let $el = $("#" + element);
let windowScrollTop = $(window).scrollTop();
let windowHeight = $(window).height();
let windowBottom = windowScrollTop + windowHeight;
let elementTop = $el.offset().top;
let elementOuterHeight = $el.outerHeight();
let elementBottom = elementTop + elementOuterHeight;
let isAboveViewPort = elementBottom < windowScrollTop;
let isBelowViewPort = windowBottom < elementTop;
return !(isAboveViewPort || isBelowViewPort);
}
let currentDiv;
$("#container").on("scroll", function() {
$("#container").find("div").each(function() {
if (isInViewPort(this.id) && currentDiv !== this.id) {
$("#page").html("Current ID is " + this.id)
currentDiv = this.id;
}
});
});
#container {
overflow: auto;
height: 300px;
}
.red {
background-color: red;
height: 600px;
}
.blue {
background-color: blue;
height: 400px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<span id="page"></span>
<div id='container'>
<div id="div-1" class="page red"></div>
<div id="div-2" class="page blue"></div>
<div id="div-3" class="page red"></div>
<div id="div-4" class="page blue"></div>
</div>
you can use the is visible feature in jQuery. Just give each div a unique ID or class.
if( $("#uniqueIdHere").is(':visible'))
$(".page3Selector").addClass('active');
and then to remove the active class you could pair it up with an else statement to remove the class of the inactive div.

js vertical slider with arrows

The thing is that I need to make a vertical images slider,so that when i press arrow down/arrow up every image changes it's position (the highest one goes bottom,the previous take it's place)
what it should look like:
what i have got so far:
$(function(){
var $vsliderboxes = $('#vsliderboxes'),
$vslidernav = $('#vslidernav'),
boxHeight = $vsliderboxes.height(),
current_index = 0;
function clickslide(){
clearInterval(intervalTimer);
clearTimeout(timeoutTimer);
timeoutTimer = setTimeout(function () {
intervalTimer = window.setInterval(autoslide, 2000);
}, 2500);
var index = $(this).index();
current_index = index;
$vsliderboxes.children().stop().animate({
top : (boxHeight * index * -1)
}, 500);
}
function autoslide(){
current_index++;
if (current_index >= $vsliderboxes.children().children().length) {
current_index = 0;
}
$vslidernav.find('a').eq(current_index).trigger('click');
}
$vslidernav.find('a').click(clickslide);
var intervalTimer = window.setInterval(autoslide, 2000),
timeoutTimer = null;
});
#vslidernav ul {
list-style: none;
padding: 0;
}
#vslidernav ul a {
padding: 0;
cursor: pointer;
height: 50px;
}
#vslidernav ul a:active {
color: #9C9A99;
}
#vslidernav ul a li {
height: 50px;
}
#vslidernav ul .active li {
}
.#vslidernav ul a:active {
background: transparent;
color: #9C9A99;
}
.vslider {
display: inline-block;
}
#vslidernav {
float: left;
width: 100px;
z-index: 1;
height: 250px;
}
#vsliderboxes {
position : relative;
overflow : hidden;
}
#vsliderboxes div {
height: 250px;
width: 900px;
}
#vsliderboxs-inner {
position : relative;
width : 900px;
height : 250px;
}
<div class="vslider">
<div id="vslidernav">
<ul>
<a id="1">
<li><img src="img/arrtop.gif"></li>
</a>
<a id="2">
<li><img src="img/arrdown.gif"></li>
</a>
<a id="3">
<li></li>
</a>
</ul>
</div>
<div id="vsliderboxes">
<div id="vsliderboxs-inner">
<div id="box1" class="active"><img src="img/slide1.gif"></div>
<div id="box2" class="inactive"><img src="img/slide2.gif"></div>
<div id="box3" class="inactive"><img src="img/slide3.gif"></div>
</div>
</div>
</div>
thanks for any advice
I think, that it isn't possible to solve this issue like you try to.
Because, when you work with the "top" property, you can't take one image from the top and append it to the other end because appending the image, will move the other images to another place --> the top property wouldn't be correct any more.
I think the contributed sliders (e.g. http://www.jssor.com/demos/vertical-slider.slider) work with the transform CSS property.
transform: translate3d()
Try to research about this property.
Roko C. Buljan answered on this page: loop carousel jquery
He uses a scrollTop loop for your problem.
I've also written a simple slider some time ago. I have now implemented the Roku C. Buljan method. Feel free to look at my code on Bitbucket.
https://bitbucket.org/d-stone/jqueryslider
An excerpt may help you:
value = prev_or_next == 'next' ? self.globals.slide_height : 0;
last = $('#container').find('> div:last');
first = $('#container').find('> div:first');
if(prev_or_next == 'prev') { // click on "next"-button
first.before(last); // put last element before first
settings.elements.inner.scrollTop(self.globals.slide_height); // set the scrollTop to 1 slide-height
}
// animation itself:
$('#container').stop().animate({scrollTop: value}, {
duration: settings.slide_speed,
done: function() {
if(prev_or_next == 'next') {
// put first item after last
last.after(first);
}
}
});
I'd advise you to validate your HTML (W3C Validator). There are some errors inside.
Invalid HTML can be the reason for some CSS and Javascript Errors.

How to dinamically update the child div width after insert other elements in the parent div

I have a main div (with fixed height and scroll-x and scroll-y):
<div style="position:relative;border:solid 2px #000;overflow-y:scroll;overflow-x:scroll; height:200px; width:100%;" id="pippo">
</div>
and a bunch of child div created dynamically in js and inserted in the parent div with absolute position:
<div style='z-index:3;position:absolute; top: 50px; left: "+pos+"px;border:solid 1px;'>m</div>
This divs can be created everywhere, also beyond the parent div height and width (I don't care because I get the scrollbars).
My problem is:
there are other child divs (created in js) that represent a background like a chart. The divs have a border and a width of 100%. An example of one of them:
<div style='z-index:2;border-bottom:solid 1px #ccc; color:#ccc;position:absolute;width:100%;bottom:"+yyy+"px;'>0</div>
When javascript create dynamically the divs, the background don't update his width to the new one (if the divs go beyond the parent measures).
So, if you scroll on the right, you don't see the background.
How can I do to give the right width (100%) to the background when the parent width is dynamically changed?
http://jsfiddle.net/4x2KP/157/
Thanks everybody!
I've do an work around to it, if you can add specific class to the axis divs.
You can listen to the scroll event on the #pippo and adjust the offset of the axis, as its fixed horizontally inside the #pippo. But you may have to separate the digit part and axis-line part to make the digit part movable by the scrollbar.
var t = 250;
var $axis;
var offsets;
$(document).ready(function(){
crea_bg();
setTimeout(function(){ pippo(); }, t);
});
var pos = 0;
function pippo(){
pos = pos + 30;
$("#pippo").append("<div style='z-index:3;position:absolute; top: 50px; left: "+pos+"px;border:solid 1px;'>m</div>");
setTimeout(function(){ pippo(); }, t);
}
function crea_bg(){
var yyy = 0;
$("#pippo").append("<div class='axis' style='z-index:2;border-bottom:solid 1px #ccc; color:#ccc;position:absolute;width:100%;bottom:"+yyy+"px;'>0</div>");
for (i = 25; i <= 300; i=i+25) {
$("#pippo").append("<div class='axis' style='z-index:2;border-bottom:solid 1px #ccc; color:#ccc;position:absolute;width:100%;bottom:"+(yyy+(-i))+"px;'>"+(-i)+"</div>");
$("#pippo").append("<div class='axis' style='z-index:2;border-bottom:solid 1px #ccc; color:#ccc;position:absolute;width:100%;bottom:"+(yyy+(i))+"px;'>"+i+"</div>");
}
$axis = $('.axis').css('left', 0);
}
$('#pippo').scroll(function() {
//var currentLeft = parseFloat($axis.css('left'));
//console.log($axis.css('left'), currentLeft, $axis.position().left);
//$axis.css('left', currentLeft - $axis.position().left);
$axis.css('left', '-=' + $axis.position().left);
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.6.4/jquery.min.js"></script>
<div style="position:relative;border:solid 2px #000;overflow-y:scroll;overflow-x:scroll; height:200px; width:100%;" id="pippo">
</div>
I'm not sure if this is what you are asking for, but this code creates those background lines at the same time that the letters are written.
You can adjust it easily changing the "width" var.
var t = 250;
$(document).ready(function(){
crea_bg();
setTimeout(function(){ pippo(); }, t);
});
var pos = 0;
function pippo(){
pos = pos + 30;
crea_bg();
$("#pippo").append("<div style='z-index:3;position:absolute; top: 50px;"
+" left: "+pos+"px;border:solid 1px;'>m</div>");
setTimeout(function(){ pippo(); }, t);
}
function crea_bg(){
var yyy = 0;
var width = pos + 30;
$("#pippo").append("<div style='z-index:2;border-bottom:solid 1px #ccc;"
+"color:#ccc;position:absolute;width:"+width+"px;bottom:"+yyy+"px;'>0</div>");
for (i = 25; i <= 300; i=i+25) {
$("#pippo").append("<div style='z-index:2;border-bottom:solid 1px #ccc;"
+" color:#ccc;position:absolute;width:"+width+"px;bottom:"+(yyy+(-i))+"px;'>"+(-i)+"</div>");
$("#pippo").append("<div style='z-index:2;border-bottom:solid 1px #ccc;"
+ "color:#ccc;position:absolute;width:"+width+"px;bottom:"+(yyy+(i))+"px;'>"+i+"</div>");
}
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.6.4/jquery.min.js"></script>
<div style="position:relative;border:solid 2px #000;overflow-y:scroll;overflow-x:scroll; height:200px; width:100%;" id="pippo">
</div>
Avoiding the typical document flow
If you must avoid the typical document flow, you'll need to insert another container between <div id="pippo"> and its child elements, then manually update the new container's width/height as needed.
Staying within the typical document flow
If you don't need to work around the normal document flow and are just searching for any possible way to make a parent expand, use a combination of display: inline-block and white-space: nowrap:
$(document).ready(function() {
setInterval(function() {
$('#pippo').append('<div class="childDiv">m</div>')
}, 250);
});
#pippo {
border: solid 2px #000;
height: 200px;
width: 100%;
overflow-y: scroll;
overflow-x: scroll;
white-space: nowrap;
}
.childDiv {
display: inline-block;
border: solid 1px #000;
margin: 5px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.6.4/jquery.min.js"></script>
<div id="pippo"></div>

Categories

Resources