Run CSS animation only once when regenerating a grid - javascript

function draw_flex (){
html_string = '';
for( let i=0; i < notes.length; i++) {
html_string += '<div class=" col-12 col-sm-12 col-md-4 col-lg-4 col-xl-2 ">'
html_string += '<div class="container">';
html_string += '<div class="text">' + notes[i].task + '</div>';
html_string += '<div class="date">' + notes[i].date + '</div>';
html_string += '<div class="time">' + notes[i].time + '</div>';
html_string += '<div class="button" onClick="delete_note_by_key(' + i + ')"><i class="fa fa-times"></i></div>';
html_string += '</div>';
html_string += '</div>';
}
html_string += '</div>';
document.getElementById('my-flex').innerHTML = html_string;
}
CSS class Container has an animation:
div.container {
background: url('notebg.png') no-repeat;
height: 250px;
animation-duration: 4s;
animation-name: fadeIn;
}
Draw_flex() function runs on form submit, so each time I submit a new Container, the animation runs once again. Ho to make it run only once?

you could look for a div.container element at the beginning of the function draw_flex: if the element exists add a no-animation class to the #my-flex container
function draw_flex() {
if (document.querySelectorAll('#my-flex div.container').length > 0) {
document.getElementById('my-flex').classList.add('no-animation');
}
...
}
and the CSS becomes
div.container {
background: url('notebg.png') no-repeat;
height: 250px;
}
#my-flex:not(.no-animation) div.container {
animation-duration: 4s;
animation-name: fadeIn;
}
so after the first call to the draw_flex function the animation will be disabled.

Related

How do i keep a set of elements wrapped in a div inline?

https://jsfiddle.net//2L4t9saq/61/ is my code
this is the output of one line of iterations
<span class="inline"><div class="pixels" x="1" y="1" style="background-color: red; width: 10px; height: 10px;"></div><div class="pixels" x="2" y="1" style="background-color: red; width: 10px; height: 10px;"></div><div class="pixels" x="3" y="1" style="background-color: red; width: 10px; height: 10px;"></div><div class="pixels" x="4" y="1" style="background-color: red; width: 10px; height: 10px;"></div><div class="pixels" x="5" y="1" style="background-color: red; width: 10px; height: 10px;"></div><div class="pixels" x="6" y="1" style="background-color: red; width: 10px; height: 10px;"></div><div class="pixels" x="7" y="1" style="background-color: red; width: 10px; height: 10px;"></div><div class="pixels" x="8" y="1" style="background-color: red; width: 10px; height: 10px;"></div><div class="pixels" x="9" y="1" style="background-color: red; width: 10px; height: 10px;"></div><div class="pixels" x="10" y="1" style="background-color: red; width: 10px; height: 10px;"></div></span>
this creates 10 divs with width/height of 10px with the background color red, all 10 divs are wrapped in the span with class inline. this process is then repeated 10 times to create the 10*10 array.
this can be configured, currently all that can be configured are the width and height of the array, and the width and height of each individual pixel
currently it is just a vertical 100 block line of red squares.
how would i make all element wrapped in classinline stay inline? as to turn it from a 1*100 line to a 10*10 square
thanks in advance
/*
$("#body").append(
"<div x='1'></div>"
);
$("div[x=1]").css("background-color","red")
$("div[x=1]").css("width","16")
$("div[x=1]").css("height","16")
*/
var createGrid = function(dimx, dimy, pixx, pixy) {
for (var n = 1; n < dimy + 1; n++) {
var str = "<div class='inline'>"
for (var i = 1; i < dimx + 1; i++) {
var opentag = "<div class='pixels' x='"
var midtag = "' y='"
var endtag = "'></div>"
str = str + opentag + i + midtag + n + endtag
}
str = str + "</div>"
$("#main").append(str)
}
$(".pixels").css("background-color", "red")
$(".pixels").css("width", pixx)
$(".pixels").css("height", pixy)
};
createGrid(10, 10, 10, 10)
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div canvas="canvas" id="main">
</div>
span should be inside the div and make them inline-block to be able to specify width/height
var createGrid = function(dimx,dimy,pixx,pixy){
for(var n = 1; n <dimy+1; n++){
var str = "<div>"
for(var i=1;i<dimx+1;i++){
var opentag = "<span class='pixels' x='"
var midtag = "' y='"
var endtag = "'></span>"
str = str+opentag+i+midtag+n+endtag
}
str=str+"</div>"
$("#main").append(str)
}
$(".pixels").css("background-color","red")
$(".pixels").css("width",pixx)
$(".pixels").css("height",pixy)
};
createGrid(10,10,10,10)
#main {
font-size:0; /* To fix white-space issue*/
}
.pixels {
display:inline-block;
border:1px solid;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div canvas="canvas" id="main">
</div>
Add display: flex on canvas div.
And no need of making the inline element as span, make it a div instead.
/*
$("#body").append(
"<div x='1'></div>"
);
$("div[x=1]").css("background-color","red")
$("div[x=1]").css("width","16")
$("div[x=1]").css("height","16")
*/
var createGrid = function(dimx, dimy, pixx, pixy) {
for (var n = 1; n < dimy + 1; n++) {
var str = "<div class='inline'>"
for (var i = 1; i < dimx + 1; i++) {
var opentag = "<div class='pixels' x='"
var midtag = "' y='"
var endtag = "'></div>"
str = str + opentag + i + midtag + n + endtag
}
str = str + "</div>"
$("#main").append(str)
}
$(".pixels").css("background-color", "red")
$(".pixels").css("width", pixx)
$(".pixels").css("height", pixy)
};
createGrid(10, 10, 10, 10)
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div canvas="canvas" id="main" style="display: flex;">
</div>
The parent element should be display: block and the inner elements could be display: inline-block for them to display in a grid-like manner. Changing only the CSS:
var createGrid = function(dimx, dimy, pixx, pixy) {
for (var n = 1; n < dimy + 1; n++) {
var str = "<span class='inline'>"
for (var i = 1; i < dimx + 1; i++) {
var opentag = "<div class='pixels' x='"
var midtag = "' y='"
var endtag = "'></div>"
str = str + opentag + i + midtag + n + endtag
}
str = str + "</span>"
$("#main").append(str)
}
$(".pixels").css("background-color", "red")
$(".pixels").css("width", pixx)
$(".pixels").css("height", pixy)
};
createGrid(10, 10, 10, 10)
.inline {
display: block;
height: 10px;
}
.pixels {
display: inline-block
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div canvas="canvas" id="main">
</div>
But it would be better to put spans inside divs, not the other way around (divs are display: block by default):
var createGrid = function(dimx, dimy, pixx, pixy) {
for (var n = 1; n < dimy + 1; n++) {
var str = "<div>"
for (var i = 1; i < dimx + 1; i++) {
var opentag = "<span class='pixels' x='"
var midtag = "' y='"
var endtag = "'></span>"
str = str + opentag + i + midtag + n + endtag
}
str = str + "</div>"
$("#main").append(str)
}
$(".pixels").css("background-color", "red")
$(".pixels").css("width", pixx)
$(".pixels").css("height", pixy)
};
createGrid(10, 10, 10, 10)
.pixels {
display: inline-block
}
#main > div {
height: 10px
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div canvas="canvas" id="main">
</div>

CSS doesn't work on HTML element

I have small piece of code written in JavaScript and CSS.
The problem is that the 'div column' is not affected by the CSS code. The border and background should appear and their color should be red.
What am I missing?
Here is the code:
https://codepen.io/orc2000/pen/VdEXVY
var text = "";
text += '<div class="row">';
text += '<div class="wrapper-elem"';
text += '<div class="column">';
text += '<h4> Column 1' + '</h4>';
text += '<img src="SomePicture 1"' + 'width="100" height="100" align = "center" > ';
text += '<p>' + 'Price 20' + '</p>';
text += '<p>' + 'DryFood' + '</p>';
text += '</div>';
text += '</div>';
text += '<div class="wrapper-elem"';
text += '<div class="column">';
text += '<h4> Column 2' + '</h4>';
text += '<img src = "SomePicture 2"' + 'width="100" height="100" align = "center" > ';
text += '<p>' + 'Pret 10' + '</p>';
text += '<p>' + 'DryFood' + '</p>';
text += '</div>';
text += '</div>';
text += '</div>';
document.getElementById("delta").innerHTML = text;
* {
box-sizing: border-box;
}
/* Create two equal columns that floats next to each other */
.wrapper-elem {
float: left;
width: 50 %;
background-color: white;
padding: 10px;
border: 2px solid blue;
}
.column {
border: 5px solid red;
background-color: red;
}
/* Clear floats after the columns */
.row: after {
content: "";
display: table;
clear: both;
}
<div id="delta"></div>
You had:
some missing HTML tag parts (2 closing >), when you constructed the HTML using JavaScript
a space in the CSS (width: 50_%)
var text = `
<div class="row">
<div class="wrapper-elem">
<div class="column">
<h4>Column 1</h4>
<img src="SomePicture 1" width="100" height="100" align="center">
<p>Price 20</p>
<p>DryFood</p>
</div>
</div>
<div class="wrapper-elem">
<div class="column">
<h4>Column2</h4>
<img src="SomePicture 2"width="100" height="100" align="center">
<p>Pret 10</p>
<p>DryFood</p>
</div>
</div>
`;
document.getElementById("delta").innerHTML = text;
* {
box-sizing: border-box;
}
/* Create two equal columns that floats next to each other */
.wrapper-elem {
float: left;
width: 50%;
background-color: white;
padding: 10px;
border: 2px solid blue;
}
.column {
border: 5px solid red;
background-color: red;
}
/* Clear floats after the columns */
.row: after {
content: "";
display: table;
clear: both;
}
<html>
<head>
<title>Test Page</title>
<link rel="stylesheet" type="text/css" href="test.css">
</head>
<body>
<div id="delta"> </div>
<script src="test.js"></script>
</body>
</html>
It's better to call your js, after DOM will be ready:)
Small refactoring
"use strict"
function generateText() {
var text = "";
text += '<div class="row">';
text += '<div class="wrapper-elem"';
text += '<div class="column">';
text += '<h4> Column 1' + '</h4>';
text += '<img src="SomePicture 1"' + 'width="100" height="100" align="center">';
text += '<p>' + 'Price 20' + '</p>';
text += '<p>' + 'DryFood' + '</p>';
text += '</div>';
text += '</div>';
text += '<div class="wrapper-elem"';
text += '<div class="column">';
text += '<h4> Column 2' + '</h4>';
text += '<img src = "SomePicture 2"' + 'width="100" height="100" align="center">';
text += '<p>' + 'Pret 10' + '</p>';
text += '<p>' + 'DryFood' + '</p>';
text += '</div>';
text += '</div>';
text += '</div>';
return text;
}
document.addEventListener("DOMContentLoaded", function(){
document.getElementById("delta").innerHTML = generateText();
});

How to flip a dynamically added image using jquery?

.html
<tbody id="item-determination" class="item-table">
</tbody>
.js
$('<td><img src="image/' + item['Group 1'].toLowerCase() + '.png"/></td>').appendTo(tr);
The image gets updated and appended to the table according to the data that comes from the service program.
On hovering over the image I want it to flip and show some text, like it happens here : https://www.ostraining.com/images/coding/jquery-flip/demo/
But as I am not using the similar structure of html, how can I get the same affect from the JQuery line that I am using?
Any kind of help would be greatly appreciated. Thanks.
$(function () {
//var $btnAdd = $('#btn-add-item');
//var $rbFlipType = $('input[name=flipType]');
var $tblItems = $('#tbl-items');
var $tbodyItems = $tblItems.children('tbody');
$(function () {
//var flipType = $rbFlipType.filter(':checked').val();
//var random = Math.random() * 9999999999999999;
var item = `<tr>
<td>
<div class="flippable-container">
<div class="flippable">
<img src="image/' + item['Group 1'].toLowerCase() + '.png" title=""/>
<h1>$('<td></td>').text(item['Group 1']).appendTo(tr)</h1>
</div>
</div>
</td>
</tr>`;
$tbodyItems.append(item);
});
});
</script>
You can do the flipping animation through CSS but you really have to restructure the HTML I guess.
$(function () {
var $btnAdd = $('#btn-add-item');
var $rbFlipType = $('input[name=flipType]');
var $tblItems = $('#tbl-items');
var $tbodyItems = $tblItems.children('tbody');
$btnAdd.click(function () {
var flipType = $rbFlipType.filter(':checked').val();
var random = Math.random() * 9999999999999999;
/* Template literal
var item = `<tr>
<td>
<div class="flippable-container">
<div class="flippable ${flipType}">
<img src="http://lorempixel.com/400/200/cats?randomQueryString=${random}" title="">
<h1>${flipType}</h1>
</div>
</div>
</td>
</tr>`;
*/
var item = '<tr>' +
'<td>' +
'<div class="flippable-container">' +
'<div class="flippable ' + flipType + '">' +
'<img src="http://lorempixel.com/400/200/cats?randomQueryString=' + random + '" title="">' +
'<h1>' + flipType + '</h1>' +
'</div>' +
'</div>' +
'</td>' +
'</tr>';
$tbodyItems.append(item);
});
});
* {
margin: 0;
padding: 0;
}
html, body {
font: normal 14px/1.8 Helvetica, Arial, sans-serif;
}
.flippable-container {
perspective: 1000px;
}
.flippable {
height: 200px;
position: relative;
transform-style: preserve-3d;
transition: 0.6s;
width: 400px;
}
.flippable img,
.flippable h1 {
backface-visibility: hidden; /* Don't show the backside of the element when rotated. */
height: 200px;
left: 0;
position: absolute;
top: 0;
width: 400px;
}
.flippable img {
z-index: 1; /* Keep the img in front. */
}
.flippable h1 {
background: #eee;
line-height: 200px;
text-align: center;
}
.flippable.vertical img {
transform: rotateX(0);
}
.flippable.vertical h1,
.flippable.vertical:hover {
transform: rotateX(180deg);
}
.flippable.horizontal img {
transform: rotateY(0);
}
.flippable.horizontal h1,
.flippable.horizontal:hover {
transform: rotateY(180deg);
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="container">
<label for="rb-flip-type-horizontal">
<input id="rb-flip-type-horizontal" type="radio" value="horizontal" name="flipType">
Horizontal
</label>
<label for="rb-flip-type-vertical">
<input id="rb-flip-type-vertical" type="radio" value="vertical" name="flipType">
Vertical
</label>
<button id="btn-add-item">
Add
</button>
<table id="tbl-items">
<tbody></tbody>
</table>
</div>
Based off of David Walsh's flip.

Change amount from px to percent based

I am trying to create a carousel with a sliding effect. The basic setup is I have 2 div's wrapping around the sliding content. The first div's width (the outerWrapper) is the size of all slides width together. The next div's width (the innerWrapper) is the size of 1 div.
When it's supposed to change slides, the innerWrapper get's a translation of x amount and it animates from the css transition.
I have everything working, but there's one thing I want to change. I want to change from pixel to percent.
Line 29:
innerWrapper.style.transform = 'translateX(-' + imgWidth * targetIndex + 'px)';
I tried a lot of things, but nothing worked. The only thing that worked was targetIndex * 20 + %, but that only works for 5 divs. It's not a concrete solution. How can I make the translateX percentage based?
JSFiddle
var trigger = document.getElementsByClassName('trigger'),
outerWrapper = document.createElement('div'),
innerWrapper = document.createElement('div'),
slide = document.getElementsByClassName('slide'),
parentElm = slide[0].parentNode,
imgWidth = slide[0].offsetWidth,
lastElm = trigger.length - 1,
previousSelectedIndex = 0;
innerWrapper.id = 'innerWrapper';
outerWrapper.id = 'outerWrapper';
trigger[0].className += ' selected';
innerWrapper.style.width = imgWidth * (lastElm + 1) + 'px';
while (slide.length) {
innerWrapper.appendChild(slide[0]);
}
for (var i = 0; i < trigger.length; i++) {
trigger[i].addEventListener('click', function(e) {
clickEvent(e);
})
}
function clickEvent(e) {
if (!hasClass(e.target, 'selected')) {
var targetIndex = [].slice.call(trigger).indexOf(e.target);
innerWrapper.style.transform = 'translateX(-' + imgWidth * targetIndex + 'px)';
e.target.className += ' selected';
removeClass(trigger[previousSelectedIndex], 'selected');
previousSelectedIndex = targetIndex;
}
}
outerWrapper.appendChild(innerWrapper);
parentElm.appendChild(outerWrapper);
function hasClass(element, cls) {
return (' ' + element.className + ' ').indexOf(' ' + cls + ' ') > -1;
}
function removeClass(ele, cls) {
if (hasClass(ele, cls)) {
var reg = new RegExp('(\\s|^)' + cls + '(\\s|$)');
ele.className = ele.className.replace(reg, ' ');
}
}
#outerWrapper {
float: left;
width: 270px;
height: 266px;
overflow: hidden;
}
#innerWrapper {
position: relative;
display: flex;
transition: transform 0.7s cubic-bezier(0.45, 0.05, 0.55, 0.95);
}
ul.triggers li {
float: left;
margin: 0 5px;
font: bold 16px arial;
cursor: pointer;
background-color: #ccc;
padding: 10px;
}
ul.triggers li.selected {
background-color: orange;
}
<img class="slide" width="270" src="http://i.imgur.com/XyWadkY.jpg" />
<img class="slide" width="270" src="http://i.imgur.com/OpP86hg.jpg" />
<img class="slide" width="270" src="http://i.imgur.com/oWbhwWT.jpg" />
<img class="slide" width="270" src="http://i.imgur.com/IXcqVB1.jpg" />
<img class="slide" width="270" src="http://i.imgur.com/OpP86hg.jpg" />
<ul class="triggers">
<li class="trigger">1</li>
<li class="trigger">2</li>
<li class="trigger">3</li>
<li class="trigger">4</li>
<li class="trigger">5</li>
</ul>
Try this,
innerWrapper.style.transform = 'translateX(-' + (targetIndex*(100/document.getElementsByClassName("slide").length)) + '%)';

Assigning a value to innerHTML not working

Looking for a second set of eyes here...
I am calling this function:
customPanel(map, "map2", dirn, document.getElementById("path2"), 1);
In customPanel, I am then building html, then trying to assign it to the page:
Here is the function, the innerHTML is near the very bottom. If I throw an alert before I try to assign the html to the innerHTML of div, it alerts correctly:
<script type="text/javascript">
var map = "";
function customPanel(map, mapname, dirn, div) {
var html = "";
function waypoint(point, type, address) {
var target = '"' + mapname + ".showMapBlowup(new GLatLng(" + point.toUrlValue(6) + "))" + '"';
html += '<table style="border: 1px solid silver; margin: 10px 0px; background-color: rgb(238, 238, 238); border-collapse: collapse; color: rgb(0, 0, 0);">';
html += ' <tr style="cursor: pointer;" onclick=' + target + '>';
html += ' <td style="padding: 4px 15px 0px 5px; vertical-align: middle; width: 20px;">';
html += ' <img src="http://maps.gstatic.com/intl/en_us/mapfiles/marker_green' + type + '.png">'
html += ' <\/td>';
html += ' <td style="vertical-align: middle; width: 100%;">';
html += address;
html += ' <\/td>';
html += ' <\/tr>';
html += '<\/table>';
}
function routeDistance(dist) {
html += '<div style="text-align: right; padding-bottom: 0.3em;">' + dist + '<\/div>';
}
function detail(point, num, description, dist) {
var target = '"' + mapname + ".showMapBlowup(new GLatLng(" + point.toUrlValue(6) + "))" + '"';
html += '<table style="margin: 0px; padding: 0px; border-collapse: collapse;">';
html += ' <tr style="cursor: pointer;" onclick=' + target + '>';
html += ' <td style="border-top: 1px solid rgb(205, 205, 205); margin: 0px; padding: 0.3em 3px; vertical-align: top; text-align: right;">';
html += ' <a href="javascript:void(0)"> ' + num + '. <\/a>';
html += ' <\/td>';
html += ' <td style="border-top: 1px solid rgb(205, 205, 205); margin: 0px; padding: 0.3em 3px; vertical-align: top; width: 100%;">';
html += description;
html += ' <\/td>';
html += ' <td style="border-top: 1px solid rgb(205, 205, 205); margin: 0px; padding: 0.3em 3px 0.3em 0.5em; vertical-align: top; text-align: right;">';
html += dist;
html += ' <\/td>';
html += ' <\/tr>';
html += '<\/table>';
}
function copyright(text) {
html += '<div style="font-size: 0.86em;">' + text + "<\/div>";
}
// === read through the GRoutes and GSteps ===
for (var i = 0; i < dirn.getNumRoutes(); i++) {
if (i == 0) {
var type = "A";
} else {
var type = "B";
}
var route = dirn.getRoute(i);
var geocode = route.getStartGeocode();
var point = route.getStep(0).getLatLng();
// === Waypoint at the start of each GRoute
waypoint(point, type, geocode.address);
routeDistance(route.getDistance().html + " (about " + route.getDuration().html + ")");
for (var j = 0; j < route.getNumSteps(); j++) {
var step = route.getStep(j);
// === detail lines for each step ===
detail(step.getLatLng(), j + 1, step.getDescriptionHtml(), step.getDistance().html);
}
}
// === the final destination waypoint ===
var geocode = route.getEndGeocode();
var point = route.getEndLatLng();
waypoint(point, "B", geocode.address);
// === the copyright text ===
copyright(dirn.getCopyrightsHtml());
// === drop the whole thing into the target div
div.innerHTML = html;
}
</script>
EDIT:
Here is the HTML as requested. It's just two divs:
<div class="mapWrapper">
<div id="path2"> </div>
<div id="map2"> </div>
</div>
To clarify, the path2 and map2 are being generated dynamically by looping through $_POST values in PHP. Here is a snippit:
foreach($post_entries as $e){
echo "
<div class=\"mapWrapper\">
<div id=\"path" . $increased_counter ."\"> </div>
<div id=\"map" . $increased_counter ."\"> </div>
</div>";
}
EDIT #2
As requested by #user1090190, a public version of the page:
http://qxxiv6yc.myutilitydomain.com/trip-planned
I suspect that path2 has not already been loaded when you call that function. It doesn't matter that you're generating it via PHP. You have to wait for the DOM to load in the browser first before you can reference specific elements. There are two solutions to this:
Call the function after page load. I.e.
<body onload="customPanel(map, "map2", dirn, document.getElementById("path2"), 1);">
Put all your Javascript at the bottom

Categories