How can I increase marginLeft onclick in Javascript? - javascript

I want to begin my onclick() function in javascript style.marginLeft=0 to be like start from '0px' to '-100%' to '-200%' and then at the end with '-200%', when It become '-200%' If you click It again, It will bring you back to .marginLeft='0'
Code on Jsfiddle
var x = document.getElementsByClassName('box')[0];
var u = -100;
function addMargin() {
var current = x.style.marginLeft = u + '%';
if (x.style.marginLeft == -200) {
x.style.marginLeft = '0';
} else {}
}
#container { display: inline-block; position: relative; width: 100%; height: 150px; white-space:
nowrap; overflow: hidden; }
.box { width: 100%; height: 150px;
display: inline-block; position: relative; }
.box:nth-child(1) { background: lightblue; }
.box:nth-child(2) { background: red; }
.box:nth-child(3) { background: green; }
<div id='container'>
<div class='box'>1</div>
<div class='box'>2</div>
<div class='box'>3</div>
</div>
<input type="button" value="Next>" onclick="addMargin()" />

You can step-down with 100 at each iteration and use modulo operator (% 400) for a reset
Here is an example:
var x = document.getElementsByClassName('box')[0];
var u = -100;
function addMargin() {
x.style.marginLeft = u + '%';
u -= 100
u %= 400
console.log("margin-left:", x.style.marginLeft)
}
#container {
display: inline-block;
position: relative;
width: 100%;
height: 150px;
white-space: nowrap;
overflow: hidden;
}
.box {
width: 100%;
height: 150px;
display: inline-block;
position: relative;
}
.box:nth-child(1) {
background: lightblue;
}
.box:nth-child(2) {
background: red;
}
.box:nth-child(3) {
background: green;
}
.as-console-wrapper {
max-height: 20px !important;
}
<div id='container'>
<div class='box'>1</div>
<div class='box'>2</div>
<div class='box'>3</div>
</div>
<input type="button" value="Next>" onclick="addMargin()" />

Condition match was wrong you need validate with some external count variable instead of matching marginLeft
var x = document.getElementsByClassName('box')[0];
var u = -100;
var count = 1;
function addMargin() {
count = count%3;
x.style.marginLeft = count * u + '%';
count++;
}
#container {
display: inline-block;
position: relative;
width: 100%;
height: 150px;
white-space: nowrap;
overflow: hidden;
}
.box {
width: 100%;
height: 150px;
display: inline-block;
position: relative;
transition:all 0.8s ease;
}
.box:nth-child(1) {
background: lightblue;
}
.box:nth-child(2) {
background: red;
}
.box:nth-child(3) {
background: green;
}
<div id='container'>
<div class='box'>1</div>
<div class='box'>2</div>
<div class='box'>3</div>
</div>
<input type="button" value="Next>" onclick="addMargin()" />

This is the cleanest/most compact implementation I could think right now. As other people said, the key is to use the Remainder Operator.
Additionally, please use addEventListener/removeEventListener API as it has been by many years the correct way to handle events.
const box0 = document.getElementsByClassName('box')[0];
box0._current = 0;
function addMargin() {
box0.style.marginLeft = `-${++box0._current % 4 * 100}%`;
}
document.getElementById('button').addEventListener('click', addMargin);
#container {
display: inline-block;
position: relative;
width: 100%;
height: 150px;
white-space:
nowrap; overflow: hidden;
}
.box {
width: 100%; height: 150px;
display: inline-block;
position: relative;
}
.box:nth-child(1) {
background: lightblue;
}
.box:nth-child(2) {
background: red;
}
.box:nth-child(3) {
background: green;
}
<div id='container'>
<div class='box'>0</div>
<div class='box'>1</div>
<div class='box'>2</div>
</div>
<input id='button' type="button" value="Next>" />

Related

Showing the div after scrolling down the website

I want to set the animation of the element while scrolling down the page. I want to use only JavaScript to achieve that.
I wanted it to work like this: There is no animation, but when you scroll down to second container, the JS sets the animation and the content inside the container is shown.
The problem is, when I load the page, there is no animation (That's good). When I scroll down, there is still no animation (That's bad!) but when I refresh the page with F5 while being on the bottom of the site, the animation shows up but still not showing my element with blue background.
Here is my full code for this part:
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<style>
* {
margin: 0;
padding: 0;
}
.main {
display: block;
margin: auto;
height: 1000px;
width: 100%;
background-color: grey;
}
.main-inner1 {
display: block;
margin: auto;
height: 600px;
width: 100%;
background-color: orange;
}
.main-inner2 {
display: block;
margin: auto;
height: 600px;
width: 100%;
background-color: green;
}
.main-inner2-container {
display: block;
position: relative;
height: 50px;
width: 200px;
overflow: hidden;
margin: auto;
}
.main-inner2-content1 {
display: block;
position: absolute;
top: 100%;
margin: auto;
height: 50px;
width: 200px;
background-color: blue;
}
#keyframes FadeIn {
{ from: top: 100%; }
{ to: top: 0; }
}
</style>
<script>
document.addEventListener("DOMContentLoaded", function(){
var y = window.scrollY;
var x = document.querySelector(".main-inner2-container").getBoundingClientRect().top;
if (y >= x) {
document.querySelector(".main-inner2-content1").style.animation = "FadeIn 1s linear 0s 1 forwards";
}
});
</script>
<body>
<div class="main">
<div class="main-inner1"></div>
<div class="main-inner2">
<div class="main-inner2-container">
<div class="main-inner2-content1">
</div>
</div>
</div>
</div>
I'm learning JS so it's important to me to not use any libraries :P
Thanks a lot
I modified your code a bit. You were listening for DOMContentLoaded event which is fired only once (after the DOM is completely loaded), instead of window scroll event.
window.onscroll = function() {
var y = window.scrollY;
var x = document.querySelector(".main-inner2-container").getBoundingClientRect().top;
if (y >= x) {
document.querySelector(".main-inner2-content1").style.animation = "FadeIn 1s linear 0s 1 forwards";
}
}
* {
margin: 0;
padding: 0;
}
.main {
display: block;
margin: auto;
height: 1000px;
width: 100%;
background-color: grey;
}
.main-inner1 {
display: block;
margin: auto;
height: 600px;
width: 100%;
background-color: orange;
}
.main-inner2 {
display: block;
margin: auto;
height: 600px;
width: 100%;
background-color: green;
}
.main-inner2-container {
display: block;
position: relative;
height: 50px;
width: 200px;
overflow: hidden;
margin: auto;
}
.main-inner2-content1 {
display: block;
position: absolute;
top: 100%;
margin: auto;
height: 50px;
width: 200px;
background-color: blue;
}
#keyframes FadeIn {
from { top: 100%; }
to {top: 0; }
}
<div class="main">
<div class="main-inner1"></div>
<div class="main-inner2">
<div class="main-inner2-container">
<div class="main-inner2-content1">
</div>
</div>
</div>
</div>
Also, your syntax for defining keyframe was incorrect. It is
#keyframes FadeIn {
from { top: 100%; }
to {top: 0; }
}
And not
#keyframes FadeIn {
{ from: top: 100%; }
{ to: top: 0; }
}

How to add inline CSS to dynamically created elements with Javascript?

I would like to add inline CSS to the left and right messages that are generated, for example the left text is red and the right text is blue. (I know it's best to style in the CSS, but I'm testing something else). So I will have this HTML:
<ul class="messages">
<li class="message left appeared">
<div class="text_wrapper">
<p class="text" style="color:red;">blabla</p>
</div>
</li>
<li class="message right appeared">
<div class="text_wrapper">
<p class="text" style="color:blue;">blabla</p>
</div>
</li>
</ul>
Please see the code as reference for the functionality. Many thanks for your help.
(function() {
var Message;
Message = function({
text: text1,
message_side: message_side1
}) {
this.text = text1;
this.message_side = message_side1;
this.draw = () => {
var $message;
$message = $($('.message_template').clone().html());
$message.addClass(this.message_side).find('.text').html(this.text);
$('.messages').append($message);
return setTimeout(function() {
return $message.addClass('appeared');
}, 0);
};
return this;
};
$(function() {
var getMessageText, message_side, sendMessage;
message_side = 'right';
getMessageText = function() {
var $message_input;
$message_input = $('.message_input');
return $message_input.val();
};
sendMessage = function(text) {
var $messages, message;
if (text.trim() === '') {
return;
}
$('.message_input').val('');
$messages = $('.messages');
message_side = message_side === 'left' ? 'right' : 'left';
message = new Message({text, message_side});
message.draw();
return $messages.animate({
scrollTop: $messages.prop('scrollHeight')
}, 300);
};
$('.send_message').click(function(e) {
return sendMessage(getMessageText());
});
$('.message_input').keyup(function(e) {
if (e.which === 13) { // enter key
return sendMessage(getMessageText());
}
});
});
}).call(this);
* {
box-sizing: border-box;
}
.chat_window {
position: absolute;
width: calc(100% - 20px);
max-width: 600px;
height: 440px;
background-color: #fff;
left: 50%;
top: 50%;
transform: translateX(-50%) translateY(-50%);
border: 1px solid #ddd;
overflow: hidden;
}
.messages {
position: relative;
list-style: none;
padding: 20px 10px 0 10px;
margin: 0;
height: 347px;
overflow: scroll;
}
.messages .message {
clear: both;
overflow: hidden;
margin-bottom: 20px;
transition: all 0.5s linear;
opacity: 0;
}
.messages .message.left .text_wrapper {
background-color: #ddd;
margin-left: 20px;
}
.messages .message.left .text_wrapper::after, .messages .message.left .text_wrapper::before {
right: 100%;
border-right-color: #ddd;
}
.messages .message.left .text,
.messages .message.right .text {
color: #000;
margin: 0;
}
.messages .message.right .text_wrapper {
background-color: #ddd;
margin-right: 20px;
float: right;
}
.messages .message.right .text_wrapper::after, .messages .message.right .text_wrapper::before {
left: 100%;
border-left-color: #ddd;
}
.messages .message.appeared {
opacity: 1;
}
.messages .message .text_wrapper {
display: inline-block;
padding: 20px;
width: calc(100% - 85px);
min-width: 100px;
position: relative;
}
.messages .message .text_wrapper::after, .messages .message .text_wrapper:before {
top: 18px;
border: solid transparent;
content: " ";
height: 0;
width: 0;
position: absolute;
pointer-events: none;
}
.messages .message .text_wrapper::after {
border-width: 13px;
margin-top: 0px;
}
.messages .message .text_wrapper::before {
border-width: 15px;
margin-top: -2px;
}
.messages .message .text_wrapper .text {
font-size: 18px;
font-weight: 300;
}
.bottom_wrapper {
position: relative;
width: 100%;
background-color: #fff;
padding: 20px 20px;
position: absolute;
bottom: 0;
}
.bottom_wrapper .message_input_wrapper {
display: inline-block;
height: 50px;
border: 1px solid #bcbdc0;
width: calc(100% - 160px);
position: relative;
padding: 0 20px;
}
.bottom_wrapper .message_input_wrapper .message_input {
border: none;
height: 100%;
box-sizing: border-box;
width: calc(100% - 40px);
position: absolute;
outline-width: 0;
color: gray;
}
.bottom_wrapper .send_message {
width: 140px;
height: 50px;
display: inline-block;
background-color: #ddd;
border: 2px solid #ddd;
color: #000;
cursor: pointer;
transition: all 0.2s linear;
text-align: center;
float: right;
}
.bottom_wrapper .send_message:hover {
color: #000;
background-color: #fff;
}
.bottom_wrapper .send_message .text {
font-size: 18px;
font-weight: 300;
display: inline-block;
line-height: 48px;
}
.message_template {
display: none;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="chat_window">
<ul class="messages"></ul>
<div class="bottom_wrapper clearfix">
<div class="message_input_wrapper">
<input class="message_input" placeholder="Type here..." />
</div>
<div class="send_message">
<div class="icon"></div>
<div class="text">
Send
</div>
</div>
</div>
</div>
<div class="message_template">
<li class="message">
<div class="text_wrapper">
<p class="text"></p>
</div>
</li>
</div>
You can also add:
$(".left").css("color", "yellow");
$(".right").css("color", "blue");
$("li.message.left > div.text_wrapper > p").css('color', 'red');
$("li.message.right > div.text_wrapper > p").css('color', 'blue');
Using jQuery you can add inline style to an element
$(".left").attr("style","whatever");
$(".right").attr("style","whatever");
You can use the classList of every HTML component. Simply, select the DOM element with class left (or right) and use the add method to assign whatever class:
var elementLeft = $('.left')
elementLeft.classList.add('yourClass')
You can also use the methods remove to remove any class, or toggle to toggle some class..
elementLeft.classList.remove('yourClass')
elementLeft.classList.toggle('yourClass')
The Element.classList contains more examples. This solution works without jQuery or others javascript library, but use the standard API.

Scroll Horizontally on hover only runs once?

I'm trying to make a simple scroll left and right div on hover. I'm really not sure what I'm doing wrong, I hover, but it only moves the 50 specified in the if statement. Do I need to add some kind of loop while I'm still hovering? Any help would be greatly appreciated.
Basically, I want to be able to hover over the two black boxes right and left and while it's hovered move right or left, when I remove the mouse it should stop.
$("#left").hover(function() {
var leftPos = $('#wrapper').scrollLeft();
$("#wrapper").animate({
scrollLeft: leftPos - 50
}, 1);
});
$("#right").hover(function() {
var leftPos = $('#wrapper').scrollLeft();
$("#wrapper").animate({
scrollLeft: leftPos + 50
}, 1);
});
html,
body {
background-color: #eeeeee;
margin: 0;
overflow-x: scroll;
overflow-y: hidden;
}
#left {
position: absolute;
width: 10vw;
height: 100vh;
top: 0;
left: 0;
z-index: 1;
background-color: black;
}
#right {
position: absolute;
width: 10vw;
height: 100vh;
top: 0;
right: 0;
z-index: 1;
background-color: black;
}
#wrapper {
width: 100%;
height: 100vh;
white-space: nowrap;
overflow-y: hidden;
overflow-x: scroll;
}
#inner_wrap {
width: 4000px;
height: 100vh;
align-items: center;
display: flex;
}
#firstcontent {
align-items: center;
display: flex;
vertical-align: middle;
color: white;
float: left;
margin-left: 20vw;
width: 400px;
height: 250px;
background-color: #2d2d2d;
}
.thumbone {
width: 400px;
height: 250px;
background-color: lightgrey;
display: inline-block;
}
.thumbtwo {
width: 400px;
height: 250px;
background-color: grey;
display: inline-block;
}
<script src="https://corporate3.bdjobs.com/js/jquery.min.js"></script>
<div id="left"></div>
<div id="right"></div>
<div id="wrapper">
<div id="inner_wrap">
<div id="firstcontent">hover or scroll</div>
<div class="thumbone"></div>
<div class="thumbtwo"></div>
<div class="thumbone"></div>
<div class="thumbtwo"></div>
<div class="thumbone"></div>
<div class="thumbtwo"></div>
<div class="thumbone"></div>
<div class="thumbtwo"></div>
</div>
</div>
Link to script
jsfiddle
[also a side note, why does this work only on jsfiddle and no where else?]
Your issue is because the mouseenter and mouseleave events (which underpin the hover() logic) only fire once, when the mouse enters/leaves the targeted element. If you want to repeatedly perform an action whilst the element is over those elements you'll need to implement your own logic.
To achieve this you can use an interval within the mouseenter handler of the hover() to repeatedly shift the scroll position of the required element. Then in the mouseleave you can clear that timer.
Also note that you can DRY up your code by using a common class on both elements along with a data attribute to govern the movement increment per tick of the interval. Try this:
var timer;
$('.hover-scroll').hover(function() {
var increment = $(this).data('pos');
timer = setInterval(function() {
var leftPos = $("#wrapper").scrollLeft();
$("#wrapper").animate({
scrollLeft: leftPos + increment
}, 1);
}, 50);
}, function() {
clearInterval(timer);
});
html,
body {
background-color: #eeeeee;
margin: 0;
overflow-x: scroll;
overflow-y: hidden;
}
#left {
position: absolute;
width: 10vw;
height: 100vh;
top: 0;
left: 0;
z-index: 1;
background-color: black;
}
#right {
position: absolute;
width: 10vw;
height: 100vh;
top: 0;
right: 0;
z-index: 1;
background-color: black;
}
#wrapper {
width: 100%;
height: 100vh;
white-space: nowrap;
overflow-y: hidden;
overflow-x: scroll;
}
#inner_wrap {
width: 4000px;
height: 100vh;
align-items: center;
display: flex;
}
#firstcontent {
align-items: center;
display: flex;
vertical-align: middle;
color: white;
float: left;
margin-left: 20vw;
width: 400px;
height: 250px;
background-color: #2d2d2d;
}
.thumbone {
width: 400px;
height: 250px;
background-color: lightgrey;
display: inline-block;
}
.thumbtwo {
width: 400px;
height: 250px;
background-color: grey;
display: inline-block;
}
<script src="https://corporate3.bdjobs.com/js/jquery.min.js"></script>
<div id="left" class="hover-scroll" data-pos="-50"></div>
<div id="right" class="hover-scroll" data-pos="50"></div>
<div id="wrapper">
<div id="inner_wrap">
<div id="firstcontent">hover or scroll</div>
<div class="thumbone"></div>
<div class="thumbtwo"></div>
<div class="thumbone"></div>
<div class="thumbtwo"></div>
<div class="thumbone"></div>
<div class="thumbtwo"></div>
<div class="thumbone"></div>
<div class="thumbtwo"></div>
</div>
</div>
If you want to speed up or slow down the scroll, change the delay on the interval

How can I define a set of CSS rules that can be added as class using JavaScript?

I am trying to use the addClass function to add class via JavaScript, but I just can't add the class. Is there a special way to define a class that will be added to an element onclick?
This is what I have tried:
var input = document.querySelector('.sb-input');
var image = document.querySelector('.sb-label img');
image.addEventListener('click', function() {
if (classie.has(input, 'open'))
classie.remove(input, 'open')
else
classie.add(input, 'open');
console.log('I am back')
});
.search-bar {
position: absolute;
top: 30px;
right: 60px;
width: 300px;
height: 40px;
overflow: hidden;
}
.sb-label {
position: absolute;
right: 0px;
display: block;
width: 50px;
height: 40px;
background-color: #32ab32;
text-align: center;
z-index: 10;
cursor: pointer;
}
.sb-label img {
display: block;
z-index: 30;
cursor: pointer;
}
.sb-input {
position: absolute;
right: 0px;
width: 50px;
height: 40px;
border: none;
backface-visibility: hidden;
transition: left 0.7s;
z-index: 5;
}
.sb-input .open {
z-index: 90;
}
.sb-input .open {
width: 100%;
transition: left 0.7s;
}
<div class="search-bar">
<form>
<label class="sb-label" id="sb-label">
<img src="search-icon01.png" width="35px" height="35px">
</label>
<input type="search" class="sb-input" id="sb-input" placeholder="Enter Search Word">
</form>
</div>
I added a callback and I got a message on my console, indicating that the function is ok, and when I did this, it works:
var input = document.querySelector('.sb-input');
var image = document.querySelector('.sb-label img');
image.addEventListener('click', function() {
input.style.zIndex = 90;
input.style.width = '100%';
console.log('I did it')
});
Apparently the problem is with my stylesheet. Could somebody please help me to correct this anomaly?
I'm curious where did you get classie from? Use classList, I think classie is too classy for us lowly developers:P
SNIPPET
<!doctype html>
<html>
<head>
<meta charset='utf-8'>
<style>
.search-bar {
position: absolute;
top: 30px;
right: 60px;
width: 300px;
height: 40px;
overflow: hidden;
}
.sb-label {
position: absolute;
right: 0px;
display: block;
width: 50px;
height: 40px;
background-color: #32ab32;
text-align: center;
z-index: 10;
cursor: pointer;
}
.sb-label img {
display: block;
z-index: 30;
cursor: pointer;
}
.sb-input {
position: absolute;
right: 0px;
width: 50px;
height: 40px;
border: none;
backface-visibility: hidden;
transition: left 0.7s;
z-index: 5;
}
.sb-input .open {
z-index: 90;
}
.sb-input .open {
width: 100%;
transition: left 0.7s;
}
</style>
</head>
<body>
<div class="search-bar">
<form>
<label class="sb-label" id="sb-label">
<img src="search-icon01.png" width="35px" height="35px">
</label>
<input type="search" class="sb-input" id="sb-input" placeholder="Enter Search Word">
</form>
</div>
<script>
var input = document.querySelector('.sb-input');
var image = document.querySelector('.sb-label img');
image.addEventListener('click', function() {
if (input.classList.contains('open')) {
input.classList.remove('open');
} else {
input.classList.add('open');
console.log('i am back')
}
});
var input = document.querySelector('.sb-input');
var image = document.querySelector('.sb-label img');
image.addEventListener('click', function() {
input.style.zIndex = 90;
input.style.width = '100%';
console.log('did i do it')
});
</script>
</body>
</html>

How to extend sidebar and content to full height even without content

Here is a sample of what I got so far. Click Here
In my HTML, I have this :
<div id="mainContainer">
<div id="header">
<p>header here</p>
</div>
<div id="centerRightColumnContainer">
<div id="centerRightColumnPositioner">
<div id="centerColumnContainer">
<div id="centerColumn">
<p>menu here</p>
</div>
</div>
</div>
</div>
<div id="sideBarLeft">
<p>side bar</p>
</div>
</div>
In my css i have :
body
{
margin: 0;
padding: 0;
height: 100%;
}
#bg
{
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
min-width: 960px;
z-index: -1;
}
body > #bg
{
position: relative;
z-index: 1;
}
#mainContainer
{
position: relative;
min-width: 960px;
top: 0;
left: 0;
z-index: 2;
}
#header
{
background-color: black;
margin: 0;
padding: 10px;
}
#centerRightColumnContainer
{
margin: 0;
padding: 0;
float: left;
width: 100%;
}
#centerRightColumnPositioner
{
margin-left: 190px;
padding: 0;
}
#sideBarLeft
{
float: left;
width: 190px;
margin-left: -100%;
padding: 0;
background-color : maroon;
}
#centerColumnContainer
{
float: left;
width: 100%;
background-color : gray;
}
#centerColumn
{
/* margin-right: 260px; */
padding: 10px;
}
body
{
font-family: Verdana, Arial, Helvetica, sans-serif;
font-size: 13px;
line-height: 17px;
margin: 0;
padding: 0;
}
p
{
margin-top: 0px;
margin-bottom: 20px;
}
.clear_both
{
clear: both;
}
#sideBarLeft p
{
margin: 10px auto;
width: 170px;
}
#rightColumnBg > #sideBarLeft
{
height: auto;
}
lastly in JS :
function resize_bg_div(){
var var_bg_offset = document.getElementById('header').offsetHeight;
array_colHeights = new Array( );
array_colHeights.push( document.getElementById("sideBarLeft").offsetHeight );
array_colHeights.push( document.getElementById("centerColumn").offsetHeight );
array_colHeights.push( window.innerHeight - var_bg_offset );
array_colHeights.sort( function( a, b ){ } );
document.getElementById('bg').style.height = array_colHeights[0] + "px";
delete array_colHeights;
delete var_bg_offset;
}
window.onload = resize_bg_div;
window.onresize = resize_bg_div;
Now, I want to set the side bar and the content to maximum height even when it has no text or any content in it.. Any help would be appreciated. Thanks!
If you are ok with jquery than use below code...
$(document).ready(function(){
var header_height = $('#header').height();
var content_height = $(window).height() - header_height;
var container_height = $('#centerRightColumnContainer').height();
var sidebar_height = $('#sideBarLeft').height();
if(container_height > sidebar_height)
var main_height = container_height;
else
var main_height = sidebar_height;
if(content_height > main_height)
var main_height = content_height;
$('#centerRightColumnContainer,#sideBarLeft').css('height',main_height);
});
I would not recommend doing this with JavaScript.
This is a well known problem in web design.
You can use a flex to achieve this:
fiddle
The wrapper does the magic:
#wrapper { display: flex; }
Flexbox is not supported by old browsers. Read this article.

Categories

Resources