Elements "jerk" back to right when I change their order - javascript

I am trying to create an infinite scroll of elements, and haven't found a plugin that was sufficiently lightweight/capable enough, so I'm trying to create my own.
So far it is working swimmingly, except for a slight jerkiness in the animation when I remove the first element and append it to the end of the parent. The example I've tossed up also has an issue where the elements lose their padding, for some reason, but that is not occurring in my actual code...
Fiddle:
http://jsfiddle.net/WtFWy/
Using the sample markup:
<section id="photos" class="bg-transparent-black">
<div class="red"></div>
<div class="blue"></div>
<div class="green"></div>
</section>​
#photos{
position:absolute;
bottom:1em;
width:100px;
height:225px;
padding:3px;
overflow:hidden;
white-space:nowrap;
}
#photos div{
height:100%;
width:50px;
padding:3px;
display:inline-block;
position:relative;
border:1px solid black;
}
.red{background:red;}
.blue{background:blue;}
.green{background:green;}
​
And JavaScript:
scrollImages = function(){
var photoArea = $('#photos');
var children = photoArea.children();
var firstChild = $(children[0])
var firstOffset=firstChild.offset();
if(document.elementLeft === false){
document.elementLeft = firstOffset.left;
}
if(document.elementWidth === false){
document.elementWidth=firstChild.outerWidth(true);
}
if(firstOffset.left < 0 && (Math.abs(firstOffset.left) > Math.abs(document.elementWidth))){
photoArea.append(firstChild);
firstChild.css('margin-left', 0 + 'px')
children = photoArea.children();
firstChild = $(children[0])
firstOffset=firstChild.offset();
document.elementLeft = firstOffset.left;
document.elementWidth=firstChild.outerWidth(true);
}else{
}
document.elementLeft -= 1;
firstChild.css('margin-left', document.elementLeft + 'px');
t = setTimeout(scrollImages, 100);
}
document.elementLeft = false;
document.elementWidth = false;
var t = setTimeout(scrollImages, 500);
$('#photos').mouseover(function(){clearTimeout(t)});
$('#photos').mouseout(function(){scrollImages()})
});
​

If you remove the padding: 3px from #photos the animation works properly.

Related

Making multilayer accordions with pure JS and using nextElementSibling

New to Javascript. I recently posted a question about creating multiple multilayer accordions. I got some great feedback, but someone mentioned that if my HTML was set up correctly, I could achieve the same goal by using nextElementSibling and thus have much cleaner JS.
I figured out how to do this using only queryselect. See the below example:
HTML:
<div class="mainAccordion">
<h2>dropdown one</h2>
<h3>dropdown two</h3>
<p>content content content content</p>
</div>
CSS:
.mainAccordion {
background-color:lightblue;
width:200px;
margin:auto;
padding:3%;
}
.mainAccordion :nth-child(1){
background-color: blue;
padding:3%;
cursor:pointer;
color:white;
}
.mainAccordion :nth-child(2){
background-color:yellow;
cursor:pointer;
max-height:0;
overflow:hidden;
}
.mainAccordion :nth-child(3){
font-weight:bold;
max-height:0;
overflow:hidden;
}
And the JS:
var mainAccordion = document.querySelector(".mainAccordion").addEventListener("click", function(e) {
if (e.target.nextElementSibling.style.maxHeight) {
e.target.nextElementSibling.style.maxHeight = null;
} else {
e.target.nextElementSibling.style.maxHeight = e.target.nextElementSibling.scrollHeight + "px";
}
});
This works as intended. However, when I introduce multiple multilayer accordions and switch to "querySelectorAll", it stops working. Also depending on the browser, I sometimes get an error message saying my "addEventListener" is not a function.
See below:
HTML:
<div class="mainAccordion">
<h2>dropdown one</h2>
<h3>dropdown two</h3>
<p>content content content content</p>
</div>
<div class="mainAccordion">
<h2>dropdown one</h2>
<h3>dropdown two</h3>
<p>content content content content</p>
</div>
CSS:
body {
display:flex;
width: 900px;
margin:auto;
}
.mainAccordion {
background-color:lightblue;
width:200px;
margin:auto;
padding:3%;
}
.mainAccordion :nth-child(1){
background-color: blue;
padding:3%;
cursor:pointer;
color:white;
}
.mainAccordion :nth-child(2){
background-color:yellow;
cursor:pointer;
max-height:0;
overflow:hidden;
}
.mainAccordion :nth-child(3){
font-weight:bold;
max-height:0;
overflow:hidden;
}
and JS:
var mainAccordion = document.querySelectorAll(".mainAccordion").addEventListener("click", function(e) {
if (e.target.nextElementSibling.style.maxHeight) {
e.target.nextElementSibling.style.maxHeight = null;
} else {
e.target.nextElementSibling.style.maxHeight = e.target.nextElementSibling.scrollHeight + "px";
}
});
I've tried changing "querySelectorAll(".mainAccordion") to getElementsByClassName("mainAccordion") but also doesn't work.
Is forEach somehow involved?
Note: I know you can also achieve the same goal by toggling a class that has the "max-height:0;overflow:hidden". However, this was how I was initially taught to do accordions.
This is for my own practice.
I appreciate the help.
Try this:
let accordionElements = document.querySelectorAll(".mainAccordion");
accordionElements.forEach(element => {
element.addEventListener("click", function(e) {
if (e.target.nextElementSibling.style.maxHeight) {
e.target.nextElementSibling.style.maxHeight = null;
} else {
e.target.nextElementSibling.style.maxHeight = e.target.nextElementSibling.scrollHeight + "px";
}
})
});
It's because with querySelector() an HTML Element is return. With querySelectorAll() it's a NodeList. In your sample code you try to attach an event to a node list which is not possible.
You need to loop inside and then attaching the event to each HTML Element inside.
i think that the problem is that the querySelector() returns the first Element within the document that matches the specified selector. then the event listener will be applied to the first element found.
the querySelectorAll() returns a list. you could use it with forEach like this
var mainAccordion = document.querySelectorAll(".mainAccordion");
console.log(mainAccordion);
mainAccordion.forEach(accordion => {
accordion.addEventListener("click", function(e) {
if (e.target.nextElementSibling.style.maxHeight) {
e.target.nextElementSibling.style.maxHeight = null;
} else {
e.target.nextElementSibling.style.maxHeight =
e.target.nextElementSibling.scrollHeight + "px";
}
});
});

Position 5 divs randomly

I'm completely stuck here. I'm trying to create a program where i have 5 different divs. They need to be placed at random position when running the program. And they need to switch position when i drag my mouse over them. So far i've done this. (which is completely wrong).
function Init()
{
div = document.getElementById("pixel");
div = document.getElementById("pixel1");
div = document.getElementById("pixel2");
div = document.getElementById("pixel3");
div = document.getElementById("pixel4");
spaceW = screen.height - div.height;
spaceH = screen.width - div.width;
setTimeout(moveIt, 0);
}
function moveIt()
{
div.style.top = (100*Math.random()) + "%";
div.style.left = (100*Math.random()) + "%";
}
<body onload="Init()">
<div id="pixel" style="background-color:blue; position:fixed; height:50px; width:50px; font-size:25px;"/>
<div id="pixel1" style="background-color:green; position:fixed; height:50px; width:50px; font-size:25px;"/>
<div id="pixel2" style="background-color:orange; position:fixed; height:50px; width:50px; font-size:25px;"/>
<div id="pixel3" style="background-color:yellow; position:fixed; height:50px; width:50px; font-size:25px;"/>
<div id="pixel4" style="background-color:red; position:fixed; height:50px; width:50px; font-size:25px;"/>
</body>
Can someone nudge me in the right direction because this clearly doesn't work.
check out after fix some syntax error like Pal Singh mention
AND
add all div(s) to one array so can be easy to control it
add [getRandomNum() , percentwidth() , percentHeight()] functions to keep div(s) in page
add moveIt() function to do some animation when move
function RandomIt()
{
var div_array = [];
div_array.push(document.getElementById("pixel"));
div_array.push(document.getElementById("pixel1"));
div_array.push(document.getElementById("pixel2"));
div_array.push(document.getElementById("pixel3"));
div_array.push(document.getElementById("pixel4"));
div_array.forEach(function(entry) {
moveIt(entry,getRandomNum(1,100 - percentwidth(entry)),getRandomNum(1,100 - percentwidth(entry)))
});
}
function getRandomNum(min, max) {
return Math.random() * (max - min) + min;
}
function percentwidth(elem){
return ((elem.offsetWidth/window.innerWidth)*100).toFixed(2);
}
function percentHeight(elem){
return ((elem.offsetHeight/window.innerHeight)*100).toFixed(2)+'%';
}
function moveIt(elem,target_x,target_y) {
var pos_x = 0;
var pos_y = 0;
var id = setInterval(frame, 5);
function frame() {
if (pos_x == target_x && pos_y == target_y) {
clearInterval(id);
} else {
if(pos_x < target_x){
pos_x++;
elem.style.left = pos_x + '%';
}
if(pos_y < target_y){
pos_y ++;
elem.style.top = pos_y + '%';
}
}
}
}
<body onload="RandomIt()">
<button onclick="RandomIt()">RandomIt</button>
<div id="pixel" style="background-color:blue; position:fixed; height:50px; width:50px; font-size:25px;"></div>
<div id="pixel1" style="background-color:green; position:fixed; height:50px; width:50px; font-size:25px;"></div>
<div id="pixel2" style="background-color:orange; position:fixed; height:50px; width:50px; font-size:25px;"></div>
<div id="pixel3" style="background-color:yellow; position:fixed; height:50px; width:50px; font-size:25px;"></div>
<div id="pixel4" style="background-color:red; position:fixed; height:50px; width:50px; font-size:25px;"></div>
</body>
I've added your code to fiddle: https://jsfiddle.net/x05b5suz/2/
Few things I would like to tell you:
div = document.getElementById("pixel");
div = document.getElementById("pixel1"); // This is wrong
div = document.getElementById("pixel2");
You should declare your variable with var keyword and their name should be unique in a scope of a function otherwise you are just overwriting them. So you can name them var div1, var div2 so on.
In HTML, you need to close your <div>...</div> tags, div are not supposed to be quick closed.
I hope this helps

Bootstrap- Automatically adjust the font inside a div

I have a div in which I can write any text up to 20 characters. But the text is getting out of the div.
I am setting it by decreasing font-size property on character count but it is not applicable on all cases.
Is there any way to do it by applying any twitter bootstrap rule?
<div id="overlay_image_text"></div>
if(cs < 6)
{
if(this.engravingFontCaseSenstiveOptions(cText) == "Lower")
{
$('#overlay_image_text').css({'margin-top':'-170px'});
$('#overlay_image_text').css({'font-size':68+'px'});
}
else if(this.engravingFontCaseSenstiveOptions(cText) == "Upper"){
$('#overlay_image_text').css({'margin-top':'-154px'});
$('#overlay_image_text').css({'font-size':48+'px'});
}
else{
$('#overlay_image_text').css({'margin-top':'-170px'});
$('#overlay_image_text').css({'font-size':64+'px'});
}
}
else if(cs > 5 && cs <= 7)
{
if(this.engravingFontCaseSenstiveOptions(cText) == "Lower")
{
$('#overlay_image_text').css({'margin-top':'-152px'});
$('#overlay_image_text').css({'font-size':47+'px'});
}
else if(this.engravingFontCaseSenstiveOptions(cText) == "Upper")
{
$('#overlay_image_text').css({'margin-top':'-140px'});
$('#overlay_image_text').css({'font-size':35+'px'});
}
else
{
$('#overlay_image_text').css({'margin-top':'-152px'});
$('#overlay_image_text').css({'font-size':47+'px'});
}
}
CSS for parent element
element.style {
display: block;
font-family: Cherokee;
}
Would need to see the CSS code of the parent element containing it but try
#overlay_image_text {
width:100%;
font-size: auto;
}
Hope you get the idea. Also, apply padding/margin in % as needed.
Are you looking for this?
Basically, I take advantage of the scale() in CSS and make the text fit in its parents. Please comment if you need further explanation ;)
$(function(){
$("#text").on("input", function(){
var thisWidth = $(this).width();
var parentWidth = $(this).parent().width();
var scalingFactor = parentWidth/thisWidth;
if (thisWidth > parentWidth) {
$(this).css("transform", "scale("+scalingFactor+")");
} else {
$(this).css("transform", "scale(1)");
}
});
})
#box {
width:400px;
background:#D8557F;
border:10px solid #D8557F;
height:100px;
}
#text {
font-size:54px;
white-space: nowrap;
float:left;
transform-origin:left;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<div id="box">
<div id="text" contenteditable="true">
Edit me!
</div>
</div>

Javascript slider, How to assign a max value for scrolling so it doesn't overflow?

I'm wanting to set a min and max value for scrolling that way it isn't possible to scroll beyond the content inside of the slider. Right now, the code allows for infinite scrolling. I'm fairly new to Javascript but I've been coding for several years at a University.
JSFiddle
JavaScript
$('#vcards').width(function(){
var width = 0;
$('.vcard').each(function(){
width += $(this).outerWidth(true);
});
return width;
}());
$('#next').on('click',function(){
$('#vcards').animate({left : "-=170"});
});
$('#prev').on('click',function(){
$('#vcards').animate({left : "+=170"});
});
CSS
#slider{
width:500px;
overflow:hidden;
position:relative;
border:1px solid black;
height:225px;
padding:10px;
}
.vcard{
width:150px;
margin: 0 10px;
height:200px;
float:left;
border:1px;
text-align:center;
font-weight:bold;
background-color:green;
}
#vcards{
position:absolute;
top:0;
left:-170px;
}
HTML
<div id="slider">
<div id="vcards">
<div class="vcard">1</div>
<div class="vcard">2</div>
<div class="vcard">3</div>
<div class="vcard">4</div>
<div class="vcard">5</div>
</div>
</div>
<div id="next">Next</div>
<div id="prev">Prev</div>
You could try this:
$('#next').on('click',function(){
var v_offset = $('#vcards').offset();
var v_width = $('#vcards').width();
var left = v_offset.left;
var total = v_width - Math.abs(left);
var cont_w = $('#slider').width();
if(total>=cont_w)
$('#vcards').animate({left : "-=170"});
});
$('#prev').on('click',function(){
var v_offset = $('#vcards').offset();
var left = v_offset.left;
if(left<=0)
$('#vcards').animate({left : "+=170"});
});

How to make images change automatically

I am new to javascript and I am trying to do a featured content slider something like the top banner in this website http://www.homeplus.co.kr
As you can see, the top big banner changes automatically & also will change when user hovers over one of the list at the right.
Right now I am able to do the hovering part, but I am still stuck at the automatic changing content part.
Here's a sample jsfiddle: http://jsfiddle.net/StormSdq/5tWPy/2/
<div class="pi">a</div>
<div class="pi">b</div>
<div class="pi">c</div>
<div class="pi">d</div>
<div class="c1">I DREAM</div>
<div class="c1">OF LLAMAS</div>
<div class="c1">JUMPING AROUND</div>
<div class="c1">EATING BUSHES</div>
css:
.pi {
font-size:12px;
color:#000;
font-weight:700;
width:30px;
height:25px;
margin-right:10px;
background:transparent;
border-bottom:solid 1px black;
}
.c1 {
border:1px solid blue;
background:lightskyblue;
width:200px;
height:200px;
float:right;
margin-right:430px;
margin-top:-100px;
color:red;
font-size:25px;
text-align:center;
display:none;
}
javascript:
div = document.getElementsByClassName('c1');
div[0].style.display = 'block'
B = document.getElementsByClassName('pi');
B[0].onmouseover = function () {
blip(0);
};
B[1].onmouseover = function () {
blip(1);
};
B[2].onmouseover = function () {
blip(2);
};
B[3].onmouseover = function () {
blip(3);
};
function blip(y) {
div = document.getElementsByClassName('c1');
for (x = 0; x < (div.length); x++) {
div[x].style.display = 'none';
}
div[y].style.display = 'block';
}
Any help will be greatly appreciated
Try this:
var cur = 0; // current index
setInterval(autoAnim, 2000); // auto change every 2s
function autoAnim(){
if(cur > 3) cur = 0;
blip(cur);
cur++;
}
Here is jsfiddle
You can use the function setTimeout to call something after XX miliseconds.
var number=0;
setTimeout(automatic,5000); // every 5 seconds
function automatic(){
blip(number);
number++;
if (number > 4)
number=0;
alert("Hello");
setTimeout(automatic,5000);
}
You will probably want to make the function sleep when mouse is hover and some others condtions

Categories