JS count number with thousands separator - javascript

This is my script for counting number given the final number (see html).
What I want to do is to add a thousands separator. As it is my code will count the number from 0 to eg. 100,000 but it will show : "100000" which doesn't look good.
PS: I've tried toLocaleString() but it didn't work in my code or I didn't use it correctly. The problem with this is that it will not show the thousands separator WHILE animating the counting.
JS
<script>
var a = 0;
$(window).scroll(function() {
var oTop = $('#counter').offset().top - window.innerHeight;
if (a == 0 && $(window).scrollTop() > oTop) {
$('.counter-value').each(function() {
var $this = $(this),
countTo = $this.attr('data-count');
$({
countNum: $this.text()
}).animate({
countNum: countTo
},
{
duration: 5000,
easing: 'swing',
step: function() {
$this.text(Math.floor(this.countNum));
},
complete: function() {
$this.text(this.countNum);
//alert('finished');
}
});
});
a = 1;
}
});
</script>
HTML
<div class="counter-value" data-count="100000">0</div>

Sometimes the answer is right before our eyes..
step: function() {
$this.text(Math.floor(this.countNum).toLocaleString());
},
complete: function() {
$this.text(Number(this.countNum).toLocaleString());;
//alert('finished');
I need to give all the credit to #PatrickEvans. Thank you.

Instead of using divs use elements that'll work for you:
Tag                                        Purpose
<input type='range'>          Store the current offset value: 0 to 100,000
<output></output>                Display the value of <input type='range'> formatted with                                               Intl.NumberFormat()
<form>                                   Listens for the input event and trigger()s a synthetic input                                                 event when user scrolls.
Details commented in Demo
Demo
* {
margin: 0;
padding: 0
}
html,
body {
overflow-x: hidden;
font: 600 16px/1.5 Consolas;
width: 100%;
height: 100%;
display: table;
margin: 0 auto;
}
#countDown {
position: relative;
width: 96vw;
height: 12600ch;
overflow-x: hidden;
overflow-y: scroll;
margin-top: 50vh;
z-index:-1;
}
/* The input is hidden because it cannot keep a text of numbers
and commas if it's a type='range'. Don't want to have it as a
type='text' because it's more work to validate */
#counter {
display: none
}
#set {
position: fixed;
width: 15%;
height: 96vh;
z-index: 1;
top: 2vh;
text-align: center;
}
#counterView {
display: block;
margin-top: calc(50vh - 8px);
}
<html>
<head></head>
<body>
<form id='countDown'>
<fieldset id='set'>
<input id='counter' type='range' min='0' max='100000' value='100000'>
<output id="counterView" for='counter'>100,000</output>
</fieldset>
</form>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script>
var a = 0;
$(document).scroll(function() {
/* label#0.mark is a fixed position at the top of viewport
|| The form#countDown is 12596ch high = window.innerHeight
*/
var oTop = $('#set').offset().top + window.innerHeight;
// As the distance between top of viewport decrease...
if ($(window).scrollTop() < (oTop)) {
// The form fires an input event
$('#countDown').trigger('input');
// The input records the distance
$('#counter').val(100315 - Math.round(oTop));
}
});
// The form is bound to input event
$('#countDown').on('input', function(e) {
// Create a special built-in Object
var commas = new Intl.NumberFormat('us-US');
// Get the input's value and convert it into a number
var c = Number($('#counter').val());
// The value of output = value of input
var cV = Number($('#counterView').val());
// Display formatted value in output
$('#counterView').val(commas.format(c));
});
</script>
</body>
</html>

Related

use jQuery setInterval to decreases the width of element but from only one side (left or right )

here are my codes for decreasing the width of an selected element(class = "life_bar"), but as my attached pictures show, I want it to decrease its width from left or right( let's do left as example), but it always goes from both side, what should I do?
here are jQuery codes
$(function () {
var timmer;
gocount();
function gocount(){
timmer = setInterval(function () {
var life_bar_width = $(".life_bar").width();
life_bar_width -= 100;
$(".life_bar").css( {width: life_bar_width,
left: '-50px'})
},1000);
}
});
here are css codes
.life_bar{
width: 500px;
height: 10px;
background: crimson;
margin: 100px auto;
}
here are html codes
<body>
<div class="life_bar"></div>
</body>
using translate negative on X every interval tick:
$(function () {
var timmer;
gocount();
let counter = 1
function gocount(){
timmer = setInterval(function () {
var life_bar_width = $(".life_bar").width();
life_bar_width -= 100;
$(".life_bar").css({
width: life_bar_width,
left: '-50px',
transform: `translate(${-50*counter}px)`
})
counter++
},1000);
}
});
.life_bar{
width: 500px;
height: 10px;
background: crimson;
margin: 100px auto;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="life_bar"></div>

How do you create 3 adjustable divs?

What I want:
| A | | B | | C |
^ ^
When you move the handles left and right A, B, and C resize accordingly
| A | | B | | C |
What I have is the || between B and C sliding, but not resizing B and all I get on the other one is the resize cursor. Basically C is a curtain and covers A and B. I did get min size working for C.
| A | C |
I broke somebody else's perfectly good code to get this far:
var isResizing = false,
who='',
lastDownX = 0;
$(function () {
var container = $('#container'),
left = $('#left'),
right = $('#right'),
middle = $('#middle'),
hand2 = $('#hand2'),
handle = $('#handle');
handle.on('mousedown', function (e) {
isResizing = true;
who=e.target.id;
lastDownX = e.clientX;
});
$(document).on('mousemove', function (e) {
var temp, min;
// we don't want to do anything if we aren't resizing.
if (!isResizing)
return;
min=container.width() * 0.1;
temp = container.width() - (e.clientX - container.offset().left);
if (temp < min)
temp = min;
if (who == 'handle')
right.css('width', temp);
if (who == 'hand2')
left.css('width', temp);
}).on('mouseup', function (e) {
// stop resizing
isResizing = false;
});
});
body, html {
width: 100%;
height: 100%;
margin: 0;
padding: 0;
}
#container {
width: 100%;
height: 100%;
/* Disable selection so it doesn't get annoying when dragging. */
-webkit-touch-callout: none;
-webkit-user-select: none;
-khtml-user-select: none;
-moz-user-select: moz-none;
-ms-user-select: none;
user-select: none;
}
#container #left {
width: 40%;
height: 100%;
float: left;
background: red;
}
#container #middle {
margin-left: 40%;
height: 100%;
background: green;
}
#container #right {
position: absolute;
right: 0;
top: 0;
bottom: 0;
width: 200px;
background: rgba(0, 0, 255, 0.90);
}
#container #handle {
position: absolute;
left: -4px;
top: 0;
bottom: 0;
width: 80px;
cursor: w-resize;
}
#container #hand2 {
position: absolute;
left: 39%;
top: 0;
bottom: 0;
width: 80px;
cursor: w-resize;
}
<div id="container">
<!-- Left side -->
<div id="left"> This is the left side's content!</div>
<!-- middle -->
<div id="middle">
<div id="hand2"></div> This is the middle content!
</div>
<!-- Right side -->
<div id="right">
<!-- Actual resize handle -->
<div id="handle"></div> This is the right side's content!
</div>
</div>
Been playing with it here: https://jsfiddle.net/ju9zb1he/5/
I was looking for a solution that required less extensive CSS. It does have one minor bug(FIXED), but hopefully this should get you started. Here is a DEMO.
Also I aimed to use DOM Traversal methods like .next() and .prev() that way it wouldn't be so attribute dependent, and would be easily reusable if you needed a feature like this multiple times on a page.
Edit - Further Explanation
The idea here is onClick of a .handle we want to gather the total width (var tWidth) of the .prev() and .next() divs relative to the .handle in the DOM. We can then use the start mouse position (var sPos) to substract the amount of pixels we've moved our mouse (e.pageX). Doing so gives us the correct width that the .prev() div should have on mousemove. To get the width of the .next() div we need only to subtract the width of the .prev() div from the total width (var tWidth) that we stored onClick of the .handle. Hope this helps! Let me know if you have any further questions, however I will likely be unavailable till tomorrow.
HTML
<div class="container">
<div id="left"></div>
<div id="l-handle" class="handle"></div>
<div id="middle"></div>
<div id="r-handle" class="handle"></div>
<div id="right"></div>
</div>
CSS
#left, #middle, #right {
display: inline-block;
background: #e5e5e5;
min-height: 200px;
margin: 0px;
}
#l-handle, #r-handle {
display: inline-block;
background: #000;
width: 2px;
min-height: 200px;
cursor: col-resize;
margin: 0px;
}
jQuery
var isDragging = false,
cWidth = $('.container').width(),
sPos,
handle,
tWidth;
$('#left, #middle, #right').width((cWidth / 3) - 7); // Set the initial width of content sections
$('.handle').on('mousedown', function(e){
isDragging = true;
sPos = e.pageX;
handle = $(this);
tWidth = handle.prev().width() + handle.next().width();
});
$(window).on('mouseup', function(e){
isDragging = false;
});
$('.container').on('mousemove', function(e){
if(isDragging){ // Added an additional condition here below
var cPos = sPos - e.pageX;
handle.prev().width((tWidth / 2) - cPos); // This was part of the bug...
handle.next().width(tWidth - handle.prev().width());
// Added an update to sPos here below
}
});
Edit
The bug was caused by 2 things.
1) On mousemove we were dividing the total width by two, instead of an updated mouse offset.
2) The sPos was not updating on mousemove, and stayed a static number based off of the click location.
Resolution
Update the sPos on mousemove that way the mouse offset is accurately based off of the previous mousemove position, rather than the click position. When this is done we can then subtract the .next() div's width from the total width. Then we subtract our current mouse position from the remaining width. The fiddle has been updated as well.
$('.container').on('mousemove', function(e){
var cPos = sPos - e.pageX;
if(isDragging && ((tWidth - handle.next().width()) - cPos) <= tWidth){
handle.prev().width((tWidth - handle.next().width()) - cPos);
handle.next().width(tWidth - handle.prev().width());
sPos = e.pageX;
}
});
Edit
Added an additional condition on mousemove to prevent the drag from exceeding the total width (var tWidth).
Can you please explain what you're trying to accomplish?
I don't believe you need to use position: absolute. The premise of absolute positioning is to override the margin and padding imposed on an element by its parent.
You don't need to do this, all elements have relative positioning by default which makes them push eachother around and don't allow overlapping.
I'm probably missing something, but I think this is what you want with nothing but some very basic CSS: http://jsfiddle.net/3bdoazpk/
<div class='first'>
asdf
</div><div class='second'>
dasdf
</div><div class='third'>
sadf
</div>
body {
margin: 0;
}
div {
display: inline-block;
height: 100%;
}
.first, .third {
width: 40%;
}
.first {
background-color: red;
}
.second {
background-color: blue;
width: 20%;
}
.third {
background-color: green;
}

Keep selected div centered when zooming

I have this HTML code:
<div class="inner">
<div class="nhood">
<div class="image"></div>
</div>
</div>
And this CSS:
.image {
width: 4000px;
height: 4000px;
background: beige;
margin: 150px;
position: absolute;
}
.nhood {
overflow: hidden;
width: 100%;
height: 100%;
box-sizing: border-box;
position: relative;
background: black;
}
The .image div is filled with 400 divs, all floating left, creating a huge 'chess'-pattern, the code is the following:
.image > div {
border: 1px dotted;
width: 5%;
height: 5%;
float: left;
box-sizing:border-box;
text-indent: 100%;
white-space: nowrap;
overflow: hidden;
position: relative;
user-select: none;
}
You are able to click on any cell to show its info, and the whole .image div is draggable. Now if you have selected a cell and you ZOOM (which basically only shrinks/extends the 4000x4000 div to 2000x2000 or the other way round) it zooms in ANYWHERE but I want to keep focus on the cell that was selected earlier.
I have made an image of this:
http://smimoo.lima-city.de/zoom.png
I hope this was any clear...
EDIT:
JS
function zoomIn() {
$(draggable).animate({
height: '4000',
width: '4000',
borderWidth: 0
}, 600, function() {
$divs.animate({
borderWidth: 0
});
});
}
function zoomOut() {
$(draggable).animate({
height: '2000',
width: '2000',
borderWidth: 0
}, 600, function() {
$divs.animate({
borderWidth: 1
});
});
EDIT2:
This is my js to center the function (written before Mario helped me out):
function centerField() {
var myObject = $(draggable).find('.selected');
var docWidth = ($(viewport).width() / 2) - (myObject.outerWidth()/2);
var docHeight = ($(viewport).height() / 2) - (myObject.outerWidth()/4);
var myOff = myObject.offset();
var distanceTop = myOff.top - docHeight;
var distanceLeft = myOff.left - docWidth;
var position = $(draggable).position();
var left = position.left;
var top = position.top;
var right = left - $(viewport).width() + draggable.outerWidth(true);
var bottom = top - $(viewport).height() + draggable.outerHeight(true);
if(left - distanceLeft > 0) {
distanceLeft = left;
}
if(right - distanceLeft < 0) {
distanceLeft = right;
}
if(top - distanceTop > 0) {
distanceTop = top;
}
if(bottom - distanceTop < 0) {
distanceTop = bottom;
}
$(draggable).animate({
left: '-=' + distanceLeft,
top: '-=' + distanceTop
}, { duration: 200, queue: false });
}
Assume that the selected div has the class .selected, this function will center the div:
function centerSelected() {
var selectedElement = $('.image .selected');
var p = selectedElement.position();
var w = $('.nhood').width();
var h = $('.nhood').height();
var offsetX = (w/2)-p.left - (selectedElement.width() / 2);
var offsetY = (h/2)-p.top - (selectedElement.height() / 2);
if(offsetX > 0) offsetX = 0;
if(offsetY > 0) offsetY = 0;
$('.image').css('left', offsetX + 'px');
$('.image').css('top', offsetY + 'px');
}
Just call centerSelected after every zoom operation.
Here is a jsfiddle with slightly modified css to get the presentation work:
http://jsfiddle.net/q1r95w3g/3/
Edit
If you want the div to get centered during jQuery animation, you can call centerSelected in the step callback of the animate method, e.g.:
function zoomIn() {
$(draggable).animate({
height: '4000',
width: '4000',
borderWidth: 0
},{
duration: 600,
complete: function() {
$divs.animate({
borderWidth: 0
});
},
step: function(now, fx) {
centerSelected();
}
});
}

First image in Juicyslider don't fit to width page

I work on my personnal website and I've a problem with the plugin Juicyslider. I work on it for 3 days but I can't find the solution ... I'm a beginner :/
So, I put images of the problem below.
I use Juicyslider to make gallery image of my work. Everything is ok but except one thing. The first image load don't fit to the page. BUT, after using the navigation (previous or after) and when I go back to the first image, this one fit to page ... First of all I thought that was a problem with position:absolute, display:none and width:100%, and after I thought that was a problem in JS with the order of functions. But everything I try don't work
HTML
<div class="description-project">
<div id="myslider_project" class="juicyslider">
<ul>
<li><img src="img.jpg"></li>
<li><img src="img1.jpg"></li>
<li><img src="im2.jpg"></li>
</ul>
<div class="nav prev"></div>
<div class="nav next"></div>
</div>
</div>
CSS
.juicyslider {
position: relative;
padding:0;
margin: 0;
border: 0;
}
.juicyslider ul {
width: 100%;
height: 100%;
position: absolute;
overflow: hidden;
list-style: none outside none;
padding:0;
margin:0;
}
.juicyslider li {
width: 100%;
height: 100%;
position: absolute;
top: 0px;
left: 0px;
display: none; /* all hidden initially */
}
.juicyslider li:first-child {
position: absolute;
width: 100%;
height: 100%;
right: 0;
left: 0;
display: block;
}
.juicyslider .nav {
position: absolute;
top: 45%;
padding: 20px;
cursor: pointer;
z-index: 500;
background-image: url(../img/nav-40.png);
.juicyslider img.maxw {
width: 100%;
height: auto;
position: absolute;
filter: inherit; /* for ie8 to inherit parent opacity */
}
.juicyslider img.maxh {
width: auto;
height: 100%;
position: absolute;
filter: inherit; /* for ie8 to inherit parent opacity */
}
And the JS file
(function($) {
$.fn.juicyslider = function(options) {
var
settings = $.extend({
// these are the defaults.
mode: "cover", // "cover" or "contain"
width: 'null', // set null to make the slider as wide/tall as the window,
height: 'null', // otherwise set any other values in px or % unit
mask: "none", // "raster", "square", "strip" or "none"
bgcolor: "#000",
autoplay: 0, // 0 for no autoplay, any other postive number for play interval in (ms)
shuffle: false, // set true to shuffle the picture order
show: {effect: 'fade', duration: 300}, // effect params refer to jQuery UI
hide: {effect: 'fade', duration: 300}, // try 'puff' or 'drop' for the effect arg
}, options),
slides = this.find('li'),
amount = slides.length,
current = 0,
theWindow = $(window),
viewport = this;
turnSlide = function(event) {
var step = 1;
if (event) {
event.preventDefault();
step = event.data.step;
}
if (settings.shuffle)
step = Math.floor(Math.random()*(amount - 1) + 1);
$(slides[current]).hide(settings.hide);
current = (((current + step) % amount) + amount) % amount;
// must make displayable before detecting the dimension
$(slides[current]).css({display: 'block', overflow: 'hidden'});
resizeImg();
$(slides[current]).css({display: 'none'});
$(slides[current]).show(settings.show);
},
// set bg color
this.css('background-color', settings.bgcolor);
// set the next button
this.find('.nav.next').click({step:1}, turnSlide);
this.find('.nav.prev').click({step:-1}, turnSlide);
// set autoplay interval
if (settings.autoplay > 0)
setInterval(turnSlide, settings.autoplay);
/*
* handling bg images resize
*/
function resizeImg() {
// set width and height of the slider
viewport.width(settings.width == null ? theWindow.width() : settings.width);
viewport.height(settings.height == null ? theWindow.height() : settings.height);
vieww = viewport.width();
viewh = viewport.height();
viewRatio = vieww / viewh;
bgimg = $(slides[current]).find("img"); // the current visible image
var doResize = function() {
imgRatio = bgimg.width() / bgimg.height();
if ((viewRatio < imgRatio && settings.mode == 'contain') || (viewRatio >= imgRatio && settings.mode == 'cover')) {
bgimg.removeClass('maxh').addClass('maxw').css({
/* get new height after adjust above */
top: (viewh - vieww / imgRatio) / 2,
left: 0
});
} else {
bgimg.removeClass('maxw').addClass('maxh').css({
/* get new width after adjust above */
top: 0,
left: (vieww - imgRatio * viewh) / 2
});
}
};
bgimg.get(0).complete ? doResize() : bgimg.load(doResize);
}
theWindow.resize(resizeImg).trigger('resize');
And to finish, here images :
Before using navigation (the slider fit perfectly in the page but a part of the image is cropped because don't fit in the slider)
http://i.stack.imgur.com/jbbpb.jpg
After using navigation and go back to the first image (everything work ...)
http://i.stack.imgur.com/ScXTE.jpg
So I think something happen during the navigation event which not happen during the loading of the slider (the resize function for example ...)
Thanks !
Ok, after few days I found a solution, not the perfect one but it works.
I just add theWindow.load(resizeImg).trigger('resize'); at the end of JS file ...
The easier solution may be the best.
If you are any better solution, do not hesitate !

Scrolling vertical text in 2 different divs

I want to scroll 2 divs when I start the page. I add to the onload the events, but it stops here:
var cross_marquee=document.getElementById(marque)
cross_marquee.style.top=0
Can someone help me?
The code is:
var delayb4scroll=2000
var marqueespeed=1
var pauseit=0
var copyspeed=marqueespeed
var pausespeed=(pauseit==0)? copyspeed: 0
var actualheight=''
var actualheightDiv2=''
function scrollmarquee(){
if (parseInt(cross_marquee.style.top)>(actualheight*(-1)+8))
cross_marquee.style.top=parseInt(cross_marquee.sty le.top)-copyspeed+"px"
else
cross_marquee.style.top=parseInt(marqueeheight)+8+ "px"
}
function initializemarquee(marque, container){
var cross_marquee=document.getElementById(marque)
cross_marquee.style.top=0
marqueeheight=document.getElementById(container).o ffsetHeight
actualheight=cross_marquee.offsetHeight
if (window.opera || navigator.userAgent.indexOf("Netscape/7")!=-1){ //if Opera or Netscape 7x, add scrollbars to scroll and exit
cross_marquee.style.height=marqueeheight+"px"
cross_marquee.style.overflow="scroll"
return
}
setTimeout('lefttime=setInterval("scrollmarquee()" ,30)', delayb4scroll)
}
window.onload=initializemarquee('wtvmarquee', 'wtmarqueecontainer')
window.onload=initializemarquee("wtvmarqueeDiv2", "wtmarqueecontainerDiv2")
You're overwriting the onload event.
Create a function that initializes both marquees:
window.onload = function(e)
{
initializemarquee('wtvmarquee', 'wtmarqueecontainer');
initializemarquee("wtvmarqueeDiv2", "wtmarqueecontainerDiv2");
}
Additionally, shouldn't be cross_marquee.style.top="0px" ?
Just found another code and modified it to my situation, and its working :)
Tks for the help joel ;)
<style type="text/css">
.scrollBox {
/* The box displaying the scrolling content */
position: absolute;
top: 30px;
left: 200px;
width: 180px;
height: 200px;
border: 1px dashed #aaaaaa;
overflow: hidden;
}
.scrollTxt {
/* the box that actually contains our content */
font: normal 12px sans-serif;
position: relative;
top: 200px;
}
.scrollBox2 {
/* The box displaying the scrolling content */
position: absolute;
top: 300px;
left: 200px;
width: 180px;
height: 200px;
border: 1px dashed #aaaaaa;
overflow: hidden;
}
.scrollTxt2 {
/* the box that actually contains our content */
font: normal 12px sans-serif;
position: relative;
top: 470px;
}
</style>
<script type="text/javascript">
var scrollSpeed =1; // number of pixels to change every frame
var scrollDepth =200; // height of your display box
var scrollHeight=0; // this will hold the height of your content
var scrollDelay=38; // delay between movements.
var scrollPos=scrollDepth; // current scroll position
var scrollMov=scrollSpeed; // for stop&start of scroll
var scrollPos2=scrollDepth; // current scroll position
var scrollMov2=scrollSpeed; // for stop&start of scroll
function doScroll() {
if(scrollHeight==0) { getHeight(); }
scrollPos-=scrollMov;
if(scrollPos< (0-scrollHeight)) { scrollPos=scrollDepth; }
document.getElementById('scrollTxt').style.top=scrollPos+'px';
setTimeout('doScroll();', scrollDelay);
}
function getHeight() {
scrollHeight=document.getElementById('scrollTxt').offsetHeight;
}
function doScroll2() {
if(scrollHeight==0) { getHeight2(); }
scrollPos2 -= scrollMov2;
if(scrollPos2< (0-scrollHeight)) { scrollPos2=scrollDepth; }
document.getElementById('scrollTxt2').style.top=scrollPos2 +'px';
setTimeout('doScroll2();', scrollDelay);
}
function getHeight2() {
scrollHeight=document.getElementById('scrollTxt2').offsetHeight;
}
window.onload = function(e)
{
doScroll();
doScroll2();
}
</script>

Categories

Resources