Swapping mutlidimensional arrays every 5 seconds in Javascript - javascript

I have made 2 multidimensional arrays with a push for data insertion, and I would like to have the 1st array shown when I open the page, and then have the 2 of them swap every 5 seconds.
Both of them show 3 pictures with some info under them, and I want the 1st one to appear, after 5 seconds, it disappears, and the second one appears, and after 5 seconds it happens again, like a loop. Any ideas?
<html>
<head>
<title>Galerija</title>
<style>
#container {
position: relative;
display: grid;
align-content: center;
padding-left: 210px;
flex-direction: column;
height: 98vh;
width: 98vw;
grid-template-columns: 1fr 1fr 1fr 1fr;
grid-gap: 6vh;
}
img {
height: 600px;
}
</style>
</head>
<body>
<div id="container">
</div>
<script>
let container = document.querySelector("#container");
let slikeniz = [];
let slikeniz2 = [];
function slike(slika, brslike, autor, cena) {
this.slika = slika;
this.brslike = brslike;
this.autor = autor;
this.cena = cena;
};
slikeniz.push(new slike("https://i.pinimg.com/736x/90/7f/f7/907ff7b31d7de2f5430cfee79ded14d2.jpg", "slika1", "nekitamo", "200e"));
slikeniz.push(new slike("https://archziner.com/wp-content/uploads/2020/01/abstract-painting-ideas-woman-with-hair-in-a-bun-dancing-flamenco-with-lon-red-skirt-blue-top.jpg", "slika2", "nekitamo2", "500e"));
slikeniz.push(new slike("https://s3.amazonaws.com/showflipper/product/69601536314088.jpg", "slika3", "nekitamo3", "1000e"));
slikeniz.forEach(t => {
container.innerHTML += "<div class = 'item'><img src = " + t.slika + ">" +
"<h1>" + t.brslike + " " + t.autor + "</h1>" +
"<h2>" + t.cena + "</h2>"
"</div>"
});
//----------------------------------------------------------------------------------
function slike2(slika2, brslike2, autor2, cena2) {
this.slika2 = slika2;
this.brslike2 = brslike2;
this.autor2 = autor2;
this.cena2 = cena2;
};
slikeniz2.push(new slike2("https://3.imimg.com/data3/VO/EN/MY-787774/power-of-nature-500x500.jpg", "slika1", "nekitamo", "400e"));
slikeniz2.push(new slike2("https://cdna.artstation.com/p/assets/images/images/030/002/140/large/tara-pogancev-lake2.jpg?1599291124&dl=1", "slika2", "nekitamo2", "1500e"));
slikeniz2.push(new slike2("https://joanabrown.art/wp-content/uploads/2019/11/sierra_h_waitingongod-book_post-img-445x555.jpg", "slika3", "nekitamo3", "1300e"));
slikeniz2.forEach(t => {
container.innerHTML += "<div class = 'item'><img src = " + t.slika2 + ">" +
"<h1>" + t.brslike2 + " " + t.autor2 + "</h1>" +
"<h2>" + t.cena2 + "</h2>"
"</div>"
});
</script>
</body>
</html>

Presented below is one possible way to achieve the desired objective.
Code Snippet
let container = document.querySelector("#container");
let slikeniz = [];
let slikeniz2 = [];
let showNow = 1, counter = 0; // flag to toggle, counter to stop
const threshold = 50; // stop after 50 toggles, for demo
function slike(slika, brslike, autor, cena) {
this.slika = slika;
this.brslike = brslike;
this.autor = autor;
this.cena = cena;
};
slikeniz.push(new slike("https://i.pinimg.com/736x/90/7f/f7/907ff7b31d7de2f5430cfee79ded14d2.jpg", "slika1", "nekitamo", "200e"));
slikeniz.push(new slike("https://archziner.com/wp-content/uploads/2020/01/abstract-painting-ideas-woman-with-hair-in-a-bun-dancing-flamenco-with-lon-red-skirt-blue-top.jpg", "slika2", "nekitamo2", "500e"));
slikeniz.push(new slike("https://s3.amazonaws.com/showflipper/product/69601536314088.jpg", "slika3", "nekitamo3", "1000e"));
// method to render the first set of images
const show1 = () => (
container.innerHTML = '',
slikeniz.forEach(t => {
container.innerHTML += "<div class = 'item'><img src = " + t.slika + ">" +
"<h1>" + t.brslike + " " + t.autor + "</h1>" +
"<h2>" + t.cena + "</h2>"
"</div>"
})
);
//----------------------------------------------------------------------------------
function slike2(slika2, brslike2, autor2, cena2) {
this.slika2 = slika2;
this.brslike2 = brslike2;
this.autor2 = autor2;
this.cena2 = cena2;
};
slikeniz2.push(new slike2("https://3.imimg.com/data3/VO/EN/MY-787774/power-of-nature-500x500.jpg", "slika1", "nekitamo", "400e"));
slikeniz2.push(new slike2("https://cdna.artstation.com/p/assets/images/images/030/002/140/large/tara-pogancev-lake2.jpg?1599291124&dl=1", "slika2", "nekitamo2", "1500e"));
slikeniz2.push(new slike2("https://joanabrown.art/wp-content/uploads/2019/11/sierra_h_waitingongod-book_post-img-445x555.jpg", "slika3", "nekitamo3", "1300e"));
// method to render the first set of images
const show2 = () => (
container.innerHTML = '',
slikeniz2.forEach(t => {
container.innerHTML += "<div class = 'item'><img src = " + t.slika2 + ">" +
"<h1>" + t.brslike2 + " " + t.autor2 + "</h1>" +
"<h2>" + t.cena2 + "</h2>"
"</div>"
})
);
// method to toggle between the two sets
const toggleSlikeniz = () => {
const id = setTimeout(() => {
if (showNow === 1) {
// if flag says to show images in set-1
// toggle the flag & invoke "show1()"
showNow = 2;
show1();
} else {
// else (flag says 2, so) show images in set-2
// toggle the flag & invoke "show2()"
showNow = 1;
show2();
};
// a sanity-checking for demo only
// stop recursive call if counter >= threshold (ie, 50)
if (counter++ < threshold) toggleSlikeniz();
}, 3500);
// clear the timeout
return () => clearTimeout(id);
};
// invoke the toggle method to begin rendering
toggleSlikeniz();
<html>
<head>
<title>Galerija</title>
<style>
#container {
position: relative;
display: grid;
align-content: center;
padding-left: 210px;
flex-direction: column;
height: 98vh;
width: 98vw;
grid-template-columns: 1fr 1fr 1fr 1fr;
grid-gap: 6vh;
}
img {
height: 600px;
}
</style>
</head>
<body>
<div id="container">
</div>
</body>
</html>
Explanation
Inline comments added to the snippet above.

Related

Javascript for loop innerhtml doesn't work

class GenerateArray {
constructor() {
this.arrayCode = document.getElementById('code');
this.BaseCode = document.getElementById('preCode');
this.startCode = document.getElementById('startC');
this.endCode = document.getElementById('endC');
this.question = "";
this.prefix = "";
this.description = "";
this.answer = "";
this.id = "";
this.Name = "";
this.answerDIV = "";
this.count = 0;
}
generateQuestionPart() {
this.question = document.createElement('input');
this.question.setAttribute('type', 'text');
this.question.id = 'question' + this.count;
this.question.className = 'question';
this.question.placeholder = 'What is the question?'
this.prefix = document.createElement('input');
this.prefix.setAttribute('type', 'text');
this.prefix.className = 'prefix';
this.prefix.id = 'prefix' + this.count;
this.prefix.placeholder = 'The prefix of the question that belongs to the link'
this.description = document.createElement('input');
this.description.setAttribute('type', 'text');
this.description.id = 'description' + this.count;
this.description.className = 'description';
this.description.placeholder = 'Add the description that is going to be in the info pop up';
this.answerDIV = document.createElement('div');
this.answerDIV.className = 'answerDIV' + this.count;
this.answerDIV.id = 'AnswerDivId';
this.answer = document.createElement('button');
this.answer.setAttribute('type', 'button');
this.answer.id = 'answer';
this.answer.className = 'answerN' + this.count;
this.answer.innerHTML = 'Add Answer';
this.answer.onclick = function (e) {
for (let i = 0; i < NewArray.count; i++) {
if (e.target.className.endsWith(i)) {
NewArray.id = document.createElement('input');
NewArray.id.setAttribute('type', 'text');
NewArray.id.id = 'id' + i;
NewArray.id.classList.add('id');
NewArray.id.placeholder = 'Add the ID of the answer';
NewArray.Name = document.createElement('input');
NewArray.Name.setAttribute('type', 'text');
NewArray.Name.id = 'Name' + i;
NewArray.Name.className = 'name';
NewArray.Name.placeholder = 'Add the text that is on the answer button';
// console.log(e.target.className);
document.getElementsByClassName('answerDIV' + i)[0].appendChild(NewArray.id);
document.getElementsByClassName('answerDIV' + i)[0].appendChild(NewArray.Name);
}
}
}
document.getElementsByClassName('create')[0].appendChild(this.question);
document.getElementsByClassName('create')[0].appendChild(this.prefix);
document.getElementsByClassName('create')[0].appendChild(this.description);
document.getElementsByClassName('create')[0].appendChild(this.answerDIV);
document.getElementsByClassName('create')[0].appendChild(this.answer);
this.count++;
// console.log(NewArray.answer.length)
}
writeArray() {
let basis = document.createElement('p');
basis.innerHTML =
" class QuizPart {\n" +
" constructor(questionText, chosenAnswer, prefix, questionDescription) {\n" +
" this.questionText = questionText;\n" +
" this.chosenAnswer = chosenAnswer;\n" +
" this.prefix = prefix;\n" +
" this.questionDescription = questionDescription;\n" +
" }\n" +
" }\n" +
"\n" +
" class ChosenAnswer {\n" +
" constructor(id, name) {\n" +
" this.id = id;\n" +
" this.name = name;\n" +
" }\n" +
" }";
this.BaseCode.appendChild(basis);
let startC = document.createElement('p');
startC.innerHTML = "let Quiz = [";
for (let i = 0; i < this.count; i++) {
let code = document.createElement('p');
let output = "new QuizPart('" + document.getElementById('question' + i).value + "', [";
let answers = document.querySelectorAll("input#Name" + i)
console.log(answers.length);
for (let y = 0; y < answers.length; y++) {
output += "new ChosenAnswer('" + document.getElementById('id' + i).value + "', '" + document.getElementById('Name' + i).value + "'),"
}
output += "], '" + document.getElementById('prefix' + i).value + "',";
output += "'" + document.getElementById('description' + i).value + "',";
code.innerHTML = output;
this.arrayCode.appendChild(code);
}
let endC = document.createElement('p');
endC.innerHTML = "]"
this.startCode.appendChild(startC);
this.endCode.appendChild(endC);
// console.log(this.count.length);
}
}
NewArray = new GenerateArray();
NewArray.generateQuestionPart();
body {
margin: 0;
padding: 0;
}
.container{
height: 1000px;
width: 800px;
position: relative;
margin-top: 5px;
left: 50%;
-ms-transform: translate(-50%, 5%);
transform: translate(-50%, 5%);
}
.QPB{
width: 50px;
height: 50px;
margin-bottom: 10px;
background-color: orange;
font-size: 40px;
}
.question{
width: 100%;
height: 20px;
margin-bottom: 10px;
}
#answer{
width: 100px;
height: 35px;
margin-bottom: 50px;
}
.prefix{
width: 100%;
height: 20px;
margin-bottom: 10px;
}
.description{
width: 100%;
height: 20px;
margin-bottom: 10px;
}
.id{
position: relative;
width: 90%;
height: 20px;
margin-bottom: 10px;
margin-left: 10%;
}
.name{
position: relative;
width: 90%;
height: 20px;
margin-bottom: 20px;
margin-left: 10%;
}
.CreateArray{
width: 100px;
height: 35px;
}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<link rel="stylesheet" href="./style.css">
<title>Hoi</title>
</head>
<body>
<div class="container">
<div class="create">
<button id="QuestionPartBtn" class="QPB" type="button" onclick="NewArray.generateQuestionPart()">+</button>
</div>
<div class="result">
<button id="CreateArray" class="CreateArray" type="button" onclick="NewArray.writeArray()">Create Array</button>
</div>
<div class="preCode" id="preCode"></div>
<div class="startC" id="startC"></div>
<div class="code" id="code"></div>
<div class="endC" id="endC"></div>
</div>
I created this system that makes an array with information that a user fills in in input fields.
The input fields are dynamically generated, so I use a for loop to show them all in an innerHTML that eventually creates the array.
My code:
this.answerDIV = document.createElement('div');
this.answerDIV.className = 'answerDIV' + this.count;
this.answerDIV.id = 'AnswerDivId';
this.answer = document.createElement('button');
this.answer.setAttribute('type', 'button');
this.answer.id = 'answer';
this.answer.className = 'answerN' + this.count;
this.answer.innerHTML = 'Add Answer';
this.answer.onclick = function (e) {
for (let i = 0; i < NewArray.count; i++) {
if (e.target.className.endsWith(i)) {
NewArray.id = document.createElement('input');
NewArray.id.setAttribute('type', 'text');
NewArray.id.id = 'id' + i;
NewArray.id.classList.add('id');
NewArray.id.placeholder = 'Add the ID of the answer';
NewArray.Name = document.createElement('input');
NewArray.Name.setAttribute('type', 'text');
NewArray.Name.id = 'Name' + i;
NewArray.Name.className = 'name';
NewArray.Name.placeholder = 'Add the text that is on the answer button';
// console.log(e.target.className);
document.getElementsByClassName('answerDIV' + i)[0].appendChild(NewArray.id);
document.getElementsByClassName('answerDIV' + i)[0].appendChild(NewArray.Name);
}
}
}
For loop:
for (let i = 0; i < this.count; i++) {
let code = document.createElement('p');
let output = "new QuizPart('" + document.getElementById('question' + i).value + "', [";
let answers = document.querySelectorAll("input#Name" + i)
console.log(answers.length);
for (let y = 0; y < answers.length; y++) {
output += "new ChosenAnswer('" + document.getElementById('id' + i).value + "', '" + document.getElementById('Name' + i).value + "'),"
}
output += "], '" + document.getElementById('prefix' + i).value + "',";
output += "'" + document.getElementById('description' + i).value + "',";
code.innerHTML = output;
this.arrayCode.appendChild(code);
}
The problem is with the second loop. Whenever I create 3 input fields for one question and I generate the innerHTML code it does show me all 3, except that they are all the first input field and the second and third aren't used as seen in the following screenshot:The problem
if i change i to y: Problem 2
(My FiddleJS link):https://jsfiddle.net/thijsl0705/1s98gumk/1/
I entered a,b,c then add answer, d,e then hit the plus sign and add f,g,h,i,j then create array. then hit the plus sign and add 1,2,3,4,5 and create the array and get:
let Quiz = [
let Quiz = [
new QuizPart('a', [new ChosenAnswer('d', 'e'),], 'b','c',
new QuizPart('f', [new ChosenAnswer('i', 'j'),], 'g','h',
new QuizPart('a', [new ChosenAnswer('d', 'e'),], 'b','c',
new QuizPart('f', [new ChosenAnswer('i', 'j'),], 'g','h',
new QuizPart('1', [new ChosenAnswer('4', '5'),], '2','3',
]
]
what exactly is the problem? what do you want to do? Looks like you might be missing a closing ) for each new QuizPart

How can I add a bubble chat icon on my website?

I'm having trouble customizing this code to have a bubble chat icon that stays within my website when I scroll down. Anyone with an idea of how I can improve it?
Here is my code so far:
<!-- Add this script tag without any modification to the target webpage -->
<script type="application/javascript">
var ciscoBubbleChat = (function() {
var smHost = 'socialminer.uonbi.ac.ke';
var widgetId = '1';
var msgMustAcceptCert = 'Certificate must be accepted to start the conversation.';
var msgAcceptCertButtonLabel = 'Accept Certificate';
var msgCloseButtonLabel = 'Close';
var msgWaitingCertAcceptance = 'Waiting for certificate acceptance.';
var msgConnectivityIssues = 'We are experiencing connectivity issues. Try later.';
var appId = 'cisco_bubble_chat';
var appMargin = 15;
var appUrl = 'https://' + smHost + '/ccp/ui/BubbleChat.html?host=' + smHost + '&wid=' + widgetId;
var connectivityCheckUrl = 'https://' + smHost + '/ccp/ui/ConnectivityCheck.html';
var messageEventListener;
var addNoCacheQueryParam;
return {
showChatWindow: function(injectedData) {
var logPrefix = 'CISCO_BUBBLE_CHAT: ';
if (document.getElementById(appId)) {
console.log(logPrefix + 'Not loading BubbleChat as it is already loaded');
return;
}
var validateInjectedData = function(formData) {
// browser compatible way to check whether it is an object with 10 fields and all the values are strings
var result = true;
if (formData && typeof formData === 'object' && formData.constructor === Object) {
var counter = 0;
for (var key in formData) {
if (!(typeof formData[key] === 'string' || formData[key] instanceof String)) {
result = false;
break;
}
counter++;
if (counter > 10) {
result = false;
break;
}
}
} else {
result = false;
}
return result;
};
if (injectedData) {
if (validateInjectedData(injectedData.formData)) {
appUrl += '&injectedFormData=' + encodeURIComponent(JSON.stringify(injectedData.formData));
} else {
if (typeof injectedData.validationErrorCallback === 'function') {
injectedData.validationErrorCallback();
} else {
console.log(logPrefix + 'Could not invoke validationErrorCallback as it is not a function');
}
}
}
var iframe = document.createElement('iframe');
iframe.setAttribute('sandbox', 'allow-scripts allow-same-origin allow-forms allow-popups');
iframe.setAttribute('id', appId);
iframe.setAttribute('style', 'position: fixed; width: 312px; height: 410px; border: none; bottom: 0px; right: 0; z-index:999;');
document.body.appendChild(iframe);
var frameWindow = iframe.contentWindow ? iframe.contentWindow : iframe;
var frameDoc = frameWindow.document;
// Trigger a page load for iframe inline content loading to work in Firefox
frameDoc.open();
frameDoc.close();
frameDoc.body.innerHTML = '<div id="secure-connectivity-check-container" style="position: fixed; width: 300px; height: 395px; ' +
'bottom: 10px; right: 10px; font-family: Helvetica; font-size: 14px; color: #4F5051;' +
'box-shadow: 0 0 3px #000; background: #fff; display: flex; flex-direction: column; display: none;">' +
'<div style="height: 25%;"></div>' +
'<div style="height: 25%; display: flex; align-items: flex-start; justify-content: center; text-align: center;">' +
'<div style="padding: 0 15% 0 15%;">' +
'<div id="secure-connectivity-check-msg"></div>' +
'<a id="accept-cert-button" style="display:none; padding-top: 10px" href="#" onclick="acceptCertificate(); return void(0);">' +
msgAcceptCertButtonLabel +
'</a>' +
'</div>' +
'</div>' +
'<div style="height: 25%; display: flex; align-items: flex-end; justify-content: center; text-align: center;">' +
'<div style="padding: 0 15% 0 15%;">' +
'<a href="#" onclick="window.parent.postMessage({messageType: \'unmount\'}, \'*\'); return void(0);">' +
msgCloseButtonLabel +
'</a>' +
'</div>' +
'</div>' +
'<div style="height: 25%;"></div>' +
'</div>';
frameWindow.acceptCertificate = function() {
frameDoc.getElementById('secure-connectivity-check-msg').innerHTML = msgWaitingCertAcceptance;
frameDoc.getElementById('accept-cert-button').style.display = 'none';
window.open(addNoCacheQueryParam(connectivityCheckUrl), 'SM_CERT_PAGE');
};
if (!addNoCacheQueryParam) {
addNoCacheQueryParam = function(url) {
return url + (url.indexOf("?") === -1 ? '?' : '&') + 'nocache=' + new Date().getTime();
}
}
if (!messageEventListener) {
messageEventListener = function(event) {
console.log(logPrefix + 'Received event from origin: ' + event.origin);
console.log(logPrefix + 'Received event data: ' + JSON.stringify(event.data));
switch (event.data.messageType) {
case 'resize':
document.getElementById(appId).style.height = event.data.height + appMargin + 'px';
console.log(logPrefix + 'Successfully resized');
break;
case 'unmount':
document.body.removeChild(document.getElementById(appId));
window.removeEventListener('message', messageEventListener);
console.log(logPrefix + 'Successfully unmounted BubbleChat and removed event listener for message');
break;
case 'bubblechat-cert-accepted':
document.getElementById(appId).setAttribute('src', addNoCacheQueryParam(appUrl));
console.log(logPrefix + 'Successfully validated certificate acceptance and loaded BubbleChat');
break;
default:
console.log(logPrefix + 'Unknown message type');
}
};
}
window.addEventListener('message', messageEventListener);
console.log(logPrefix + 'Event listener for message added');
// Check HTTPS connectivity and show appropriate screen
var showConnectivityIssue = function(message, showAcceptCertLink) {
window.postMessage({
messageType: 'resize',
height: 395
}, '*');
frameDoc.getElementById('secure-connectivity-check-container').style.display = 'block';
frameDoc.getElementById('secure-connectivity-check-msg').innerHTML = message;
frameDoc.getElementById('accept-cert-button').style.display = showAcceptCertLink ? 'block' : 'none';
};
var xhr = new XMLHttpRequest();
xhr.onreadystatechange = function() {
if (this.readyState === 4) {
console.log(logPrefix + 'Connectivity check status: ' + this.status);
switch (this.status) {
case 200:
iframe.setAttribute('src', addNoCacheQueryParam(appUrl));
break;
case 0:
showConnectivityIssue(msgMustAcceptCert, true);
break;
default:
showConnectivityIssue(msgConnectivityIssues, false);
}
}
};
console.log(logPrefix + 'Checking connectivity to: ' + connectivityCheckUrl);
xhr.open('GET', addNoCacheQueryParam(connectivityCheckUrl), true);
xhr.send();
}
};
})();
</script>
<!--
Use the function 'ciscoBubbleChat.showChatWindow() as the event handler for initiating chat.
eg: <button onclick="ciscoBubbleChat.showChatWindow()">Start Chat</button>
Optionally, invisible form data can be submitted, which will be submitted along with the fields customer fills in.
Upto 10 fields can be passed. If more than 10 fields are passed, the invisible form data will not be used and
the provided error callback will be invoked. For injecting form data, an object should be passed to
ciscoBubbleChat.showChatWindow() as an argument. The object should be of the form:
{
formData: {
InjectedField1: 'InjectedValue1',
InjectedField2: 'InjectedValue2'
...
},
validationErrorCallback: function(){console.log('business specific logic goes here');}
}
The form data can have any string as field name and value. The submitted invisible form data values will be
shown in the agent desktop, as well as will be updated in ContextService if the specified fieldset(s) in the widget
contains these field names just like the regular visible chat form fields data.
eg:
<button onclick="ciscoBubbleChat.showChatWindow({
formData: {
AnyFieldName1: 'AnyFieldValue1',
AnyFieldName2: 'AnyFieldValue2',
AnyFieldName3: 'AnyFieldValue3',
AnyFieldName4: 'AnyFieldValue4',
AnyFieldName5: 'AnyFieldValue5',
AnyFieldName6: 'AnyFieldValue6',
AnyFieldName7: 'AnyFieldValue7',
AnyFieldName8: 'AnyFieldValue8',
AnyFieldName9: 'AnyFieldValue9',
AnyFieldName10: 'AnyFieldValue10'
},
validationErrorCallback: function(){console.log('error in validating injected data');}
})">Click to chat</button>
-->
<html>
<body>
<button class onclick="ciscoBubbleChat.showChatWindow()">Start Chat</button>
</body>
</html>
I want to customize it so that it can have a better look, and find a way to keep it within my website. Does anyone have any ideas?
The best solution would be to add position: fixed; on the button, for example: <button style="position: fixed; bottom: 0; right: 0;" onclick="ciscoBubbleChat.showChatWindow()">Start Chat</button> That would force the button to stay on the lower right side of screen at all times. And for the icon, just add an <img> tag.
Demo:
.chatBtn {
position: fixed;
bottom: 20px;
right: 20px;
z-index: 2;
}
.chatBtn img {
width: 40px; /* Change this to what you want. */
height: 40px; /* Change this to what you want. */
}
<button class="chatBtn" onclick="ciscoBubbleChat.showChatWindow()"><img src="https://icon-library.com/images/talk-bubble-icon-png/talk-bubble-icon-png-2.jpg"> <!-- You can put your own image here. -->
</button>
<!-- Add this script tag without any modification to the target webpage -->
<script type="application/javascript">
var ciscoBubbleChat = (function () {
var smHost = 'socialminer.uonbi.ac.ke';
var widgetId = '1';
var msgMustAcceptCert = 'Certificate must be accepted to start the conversation.';
var msgAcceptCertButtonLabel = 'Accept Certificate';
var msgCloseButtonLabel = 'Close';
var msgWaitingCertAcceptance = 'Waiting for certificate acceptance.';
var msgConnectivityIssues = 'We are experiencing connectivity issues. Try later.';
var appId = 'cisco_bubble_chat';
var appMargin = 15;
var appUrl = 'https://' + smHost + '/ccp/ui/BubbleChat.html?host=' + smHost + '&wid=' + widgetId;
var connectivityCheckUrl = 'https://' + smHost + '/ccp/ui/ConnectivityCheck.html';
var messageEventListener;
var addNoCacheQueryParam;
return {
showChatWindow: function (injectedData) {
var logPrefix = 'CISCO_BUBBLE_CHAT: ';
if (document.getElementById(appId)) {
console.log(logPrefix + 'Not loading BubbleChat as it is already loaded');
return;
}
var validateInjectedData = function(formData) {
// browser compatible way to check whether it is an object with 10 fields and all the values are strings
var result = true;
if (formData && typeof formData === 'object' && formData.constructor === Object){
var counter = 0;
for (var key in formData) {
if (!(typeof formData[key] === 'string' || formData[key] instanceof String)) {
result = false;
break;
}
counter++;
if (counter > 10) {
result = false;
break;
}
}
} else {
result = false;
}
return result;
};
if (injectedData) {
if (validateInjectedData(injectedData.formData)) {
appUrl += '&injectedFormData=' + encodeURIComponent(JSON.stringify(injectedData.formData));
} else {
if (typeof injectedData.validationErrorCallback === 'function') {
injectedData.validationErrorCallback();
} else {
console.log(logPrefix + 'Could not invoke validationErrorCallback as it is not a function');
}
}
}
var iframe = document.createElement('iframe');
iframe.setAttribute('sandbox', 'allow-scripts allow-same-origin allow-forms allow-popups');
iframe.setAttribute('id', appId);
iframe.setAttribute('style', 'position: fixed; width: 312px; height: 410px; border: none; bottom: 0px; right: 0; z-index:999;');
document.body.appendChild(iframe);
var frameWindow = iframe.contentWindow ? iframe.contentWindow : iframe;
var frameDoc = frameWindow.document;
// Trigger a page load for iframe inline content loading to work in Firefox
frameDoc.open();
frameDoc.close();
frameDoc.body.innerHTML = '<div id="secure-connectivity-check-container" style="position: fixed; width: 300px; height: 395px; ' +
'bottom: 10px; right: 10px; font-family: Helvetica; font-size: 14px; color: #4F5051;' +
'box-shadow: 0 0 3px #000; background: #fff; display: flex; flex-direction: column; display: none;">' +
'<div style="height: 25%;"></div>' +
'<div style="height: 25%; display: flex; align-items: flex-start; justify-content: center; text-align: center;">' +
'<div style="padding: 0 15% 0 15%;">' +
'<div id="secure-connectivity-check-msg"></div>' +
'<a id="accept-cert-button" style="display:none; padding-top: 10px" href="#" onclick="acceptCertificate(); return void(0);">' +
msgAcceptCertButtonLabel +
'</a>' +
'</div>' +
'</div>' +
'<div style="height: 25%; display: flex; align-items: flex-end; justify-content: center; text-align: center;">' +
'<div style="padding: 0 15% 0 15%;">' +
'<a href="#" onclick="window.parent.postMessage({messageType: \'unmount\'}, \'*\'); return void(0);">' +
msgCloseButtonLabel +
'</a>' +
'</div>' +
'</div>' +
'<div style="height: 25%;"></div>' +
'</div>';
frameWindow.acceptCertificate = function () {
frameDoc.getElementById('secure-connectivity-check-msg').innerHTML = msgWaitingCertAcceptance;
frameDoc.getElementById('accept-cert-button').style.display = 'none';
window.open(addNoCacheQueryParam(connectivityCheckUrl), 'SM_CERT_PAGE');
};
if (!addNoCacheQueryParam){
addNoCacheQueryParam = function (url) {
return url + (url.indexOf("?") === -1 ? '?' : '&') + 'nocache=' + new Date().getTime();
}
}
if (!messageEventListener) {
messageEventListener = function (event) {
console.log(logPrefix + 'Received event from origin: ' + event.origin);
console.log(logPrefix + 'Received event data: ' + JSON.stringify(event.data));
switch (event.data.messageType) {
case 'resize':
document.getElementById(appId).style.height = event.data.height + appMargin + 'px';
console.log(logPrefix + 'Successfully resized');
break;
case 'unmount':
document.body.removeChild(document.getElementById(appId));
window.removeEventListener('message', messageEventListener);
console.log(logPrefix + 'Successfully unmounted BubbleChat and removed event listener for message');
break;
case 'bubblechat-cert-accepted':
document.getElementById(appId).setAttribute('src', addNoCacheQueryParam(appUrl));
console.log(logPrefix + 'Successfully validated certificate acceptance and loaded BubbleChat');
break;
default:
console.log(logPrefix + 'Unknown message type');
}
};
}
window.addEventListener('message', messageEventListener);
console.log(logPrefix + 'Event listener for message added');
// Check HTTPS connectivity and show appropriate screen
var showConnectivityIssue = function (message, showAcceptCertLink) {
window.postMessage({ messageType: 'resize', height: 395 }, '*');
frameDoc.getElementById('secure-connectivity-check-container').style.display = 'block';
frameDoc.getElementById('secure-connectivity-check-msg').innerHTML = message;
frameDoc.getElementById('accept-cert-button').style.display = showAcceptCertLink ? 'block' : 'none';
};
var xhr = new XMLHttpRequest();
xhr.onreadystatechange = function () {
if (this.readyState === 4) {
console.log(logPrefix + 'Connectivity check status: ' + this.status);
switch (this.status) {
case 200:
iframe.setAttribute('src', addNoCacheQueryParam(appUrl));
break;
case 0:
showConnectivityIssue(msgMustAcceptCert, true);
break;
default:
showConnectivityIssue(msgConnectivityIssues, false);
}
}
};
console.log(logPrefix + 'Checking connectivity to: ' + connectivityCheckUrl);
xhr.open('GET', addNoCacheQueryParam(connectivityCheckUrl), true);
xhr.send();
}
};
})();
</script>
<!--
Use the function 'ciscoBubbleChat.showChatWindow() as the event handler for initiating chat.
eg: <button onclick="ciscoBubbleChat.showChatWindow()">Start Chat</button>
Optionally, invisible form data can be submitted, which will be submitted along with the fields customer fills in.
Upto 10 fields can be passed. If more than 10 fields are passed, the invisible form data will not be used and
the provided error callback will be invoked. For injecting form data, an object should be passed to
ciscoBubbleChat.showChatWindow() as an argument. The object should be of the form:
{
formData: {
InjectedField1: 'InjectedValue1',
InjectedField2: 'InjectedValue2'
...
},
validationErrorCallback: function(){console.log('business specific logic goes here');}
}
The form data can have any string as field name and value. The submitted invisible form data values will be
shown in the agent desktop, as well as will be updated in ContextService if the specified fieldset(s) in the widget
contains these field names just like the regular visible chat form fields data.
eg:
<button onclick="ciscoBubbleChat.showChatWindow({
formData: {
AnyFieldName1: 'AnyFieldValue1',
AnyFieldName2: 'AnyFieldValue2',
AnyFieldName3: 'AnyFieldValue3',
AnyFieldName4: 'AnyFieldValue4',
AnyFieldName5: 'AnyFieldValue5',
AnyFieldName6: 'AnyFieldValue6',
AnyFieldName7: 'AnyFieldValue7',
AnyFieldName8: 'AnyFieldValue8',
AnyFieldName9: 'AnyFieldValue9',
AnyFieldName10: 'AnyFieldValue10'
},
validationErrorCallback: function(){console.log('error in validating injected data');}
})">Click to chat</button>
-->
EDIT:
A chat bubble icon has been added.

Organizing buttons in div using only JavaScript

I need help with organizing this gallery to look like this:
I tried everything I know with positions (absolute and relative), bottoms, margins... but I can't seem to organize it properly.
This popup div needs to occupy 80% of page height and 80% of the page width, and images shouldn't break out of div.
I am not allowed to change HTML or to add CSS. Everything needs to be written inside the JS file.
Here is my code:
$(document).ready(function() {
var images = $('div[title ="London gallery"]').children('img').map(function() {
return $(this).attr('src')
}).get();
var description = $('div[title ="London gallery"]').children('p').map(function() {
return $(this).text();
}).get();
$('div[title ="London gallery"]').hide();
var gallery_lndn = document.createElement('button');
gallery_lndn.id = 'btn_London';
gallery_lndn.innerHTML = 'Look at the galery!';
document.body.appendChild(gallery_lndn);
document.getElementById('btn_London').onclick = function() {
show_pictures(images, description);
}
function show_pictures(images, description) {
function popUp() {
var index = 0;
var popup = document.createElement('div');
popup.className = 'popup';
popup.id = 'div_popup';
popup.style.background = "#2F4F4F";
popup.style.position = "absolute";
popup.style.top = "0px";
popup.style.left = "0px";
popup.style.right = "0px";
popup.style.margin = "100px auto";
popup.style.height = "80%";
popup.style.width = "80%";
var cancelButton = document.createElement('button');
cancelButton.innerHTML = 'x';
cancelButton.id = 'btn_cancelButton';
cancelButton.style.background = "red";
cancelButton.style.border = "none";
cancelButton.style.display = "inline-block";
cancelButton.style.fontSize = "16px";
cancelButton.style.padding = "15px 20px";
cancelButton.style.float = "right";
cancelButton.style.top = "0";
cancelButton.onclick = function(e) {
popup.parentNode.removeChild(popup)
};
var previousButton = document.createElement('button');
previousButton.innerHTML = '<<';
previousButton.style.background = "#32CD32";
previousButton.style.border = "none";
previousButton.style.display = "inline-block";
previousButton.style.fontSize = "16px";
previousButton.style.padding = "15px 32px";
previousButton.style.position = "absolute";
previousButton.style.float = "left";
previousButton.style.bottom = "0";
previousButton.onclick = function() {
index = (index == 0) ? images.length - 1 : index - 1;
console.log(index);
updateImage();
}
var nextButton = document.createElement('button');
nextButton.innerHTML = '>>';
nextButton.style.background = "#32CD32";
nextButton.style.background = "#32CD32";
nextButton.style.border = "none";
nextButton.style.display = "inline-block";
nextButton.style.fontSize = "16px";
nextButton.style.padding = "15px 32px";
//nextButton.style.position = "absolute";
nextButton.style.float = "right";
nextButton.style.bottom = "0";
nextButton.onclick = function() {
index = (index == images.length - 1) ? 0 : index + 1;
console.log(index);
updateImage();
}
function updateImage() {
var img = new Image();
img.src = images[index];
img.style.margin = "auto";
img.style.position = "relative";
img.style.display = "block";
console.log(img);
$("#div_popup").html("");
if (index == 0) {
previousButton.style.background = "#A9A9A9";
//previousButton.disabled = "true";
} else if (index == images.length - 1) {
nextButton.style.background = "#A9A9A9";
//nextButton.disabled = "true";
} else {
//nextButton.disabled = "false";
//previousButton.disabled = "false";
previousButton.style.background = "#32CD32";
nextButton.style.background = "#32CD32";
}
popup.appendChild(previousButton);
popup.appendChild(nextButton);
popup.appendChild(cancelButton);
var message = document.createElement('span');
//message.style.position = "absolute";
message.style.bottom = "0";
message.innerHTML = "Picture " + (index + 1) + "/" + images.length + "<br>" + description[index];
img.onload = function() {
popup.appendChild(message);
popup.appendChild(img);
document.body.appendChild(popup);
};
}
updateImage();
}
popUp();
}
});
<!DOCTYPE html>
<html>
<head>
<meta charset="utf8">
<title>Document</title>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.js"></script>
<script src="gallery.js"></script>
</head>
<body>
<h1>London</h1>
<div class="gallery" title="London gallery">
<img src="https://cdn.londonandpartners.com/visit/general-london/areas/river/76709-640x360-houses-of-parliament-and-london-eye-on-thames-from-above-640.jpg">
<p data-target="https://cdn.londonandpartners.com/visit/general-london/areas/river/76709-640x360-houses-of-parliament-and-london-eye-on-thames-from-above-640.jpg">
Description 1.
</p>
<img src="https://news.itu.int/wp-content/uploads/2018/07/london-min-e1530887248858.jpg">
<p data-target="https://news.itu.int/wp-content/uploads/2018/07/london-min-e1530887248858.jpg">
Description 2.
</p>
</div>
</body>
</html>
You can update the button positions according to the image. Call below method inside the updateImage method just before closing.
function updatePositions(){
// absolute position for all buttons
$('#div_popup > button').css({'position': 'absolute', 'float':'none', 'z-index': 1});
// get image bottom position
let buttonTopPos = ($('#div_popup > img').offset().top + $('#div_popup > img').height()) - $('#div_popup').offset().top + 20;
// get image bottom left position
let buttonLeftPos = 0;
if($('#div_popup').width() > $('#div_popup > img').width()){
buttonLeftPos = ($('#div_popup').width() - $('#div_popup > img').width())/2
}else{
$('#div_popup > img').css({'min-width':'100%', 'max-width':'100%'});
}
// image overflow will be hidden
$('#div_popup').css('overflow', 'hidden');
// Back button position
$('#div_popup > button:nth-child(1)').css({'top': buttonTopPos, 'bottom':'auto', 'left': buttonLeftPos +'px'})
// Next button position
$('#div_popup > button:nth-child(2)').css({'top': buttonTopPos, 'bottom':'auto', 'left': (buttonLeftPos + $('#div_popup > img').width()) - 90})
// cancel button position
$('#div_popup > button:nth-child(3)').css({'top': 0, 'right': 0, left: 'auto'});
// description position
$('#div_popup > span').css({'position': 'absolute','top': buttonTopPos, 'bottom':'auto', 'left': buttonLeftPos + 90, 'width': $('#div_popup > img').width() - 90 - 90, 'text-align': 'center'})
}
Here's a layout that approximates the sample, above. For convenience, this uses JavaScript to add a <style> element to the <head>.
window.onload = () => {
const myCSS =
' body {\n' +
' width:100vw;\n' +
' height:100vh;\n' +
' position:relative\n' +
' }\n' +
' .gallery {\n' +
' background-color: darkblue;\n' +
' width: 80%;\n' +
' height: 80%;\n' +
' position: absolute;\n' +
' top: 10%;\n' +
' left: 10%;\n' +
' }\n' +
' .img-wrapper {\n' +
' background-color: transparent;\n' +
' width: calc(100% - 120px);\n' +
' height: calc(100% - 160px);\n' +
' margin: 60px;\n' +
' overflow-y: hidden;\n' +
' }\n' +
' .img-wrapper img {\n' +
' width: 100%;\n' +
' height: auto;\n' +
' }\n' +
' .btn1 {\n' +
' width: 120px;\n' +
' height: 60px;\n' +
' position: absolute;\n' +
' left: 60px;\n' +
' bottom: 30px;\n' +
' background-color: #999;\n' +
' }\n' +
' .btn2 {\n' +
' width: 120px;\n' +
' height: 60px;\n' +
' position: absolute;\n' +
' right: 60px;\n' +
' bottom: 30px;\n' +
' background-color: #999;\n' +
' }\n' +
' .btn-close {\n' +
' width: 80px;\n' +
' height: 40px;\n' +
' position: absolute;\n' +
' right: 0;\n' +
' top: 0;\n' +
' background-color: #999;\n' +
' }\n' +
' .caption {\n' +
' width: calc(100% - 409px);\n' +
' height: 60px;\n' +
' position: absolute;\n' +
' left: 192px;\n' +
' bottom: 30px;\n' +
' color: white;\n' +
' border: 1px dashed #aaa;\n' +
' text-align: center;\n' +
' padding: 0 12px;\n' +
' overflow: hidden;\n' +
' }\n';
const myStyle = document.createElement('style');
myStyle.id = 'myCSS';
myStyle.innerHTML = myCSS;
document.head.appendChild(myStyle);
}
<body>
<div class="gallery">
<div class="img-wrapper">
<img src="https://cdn.londonandpartners.com/visit/general-london/areas/river/76709-640x360-houses-of-parliament-and-london-eye-on-thames-from-above-640.jpg">
</div>
<div class="btn1">.btn1</div>
<div class="btn2">.btn2</div>
<div class="caption">.caption</div>
<div class="btn-close">.btn-close</div>
</div>
</body>

Responsive Slider Script

I'm trying to add a responsive slider to my website and am having a couple of issues. The biggest is the size of the outside container. On desktop, the actual size of the slider should be 680 x 380. As it stands, I have major margins on either side of the slider and really am not sure how to get rid of them. I'm sure this is easy for most of you but, I can't figure it out. Secondly, is there an easy way to have the images appear in random order? Any help would be greatly appreciated. Thanks very much
Here is my test page for the slider: https://www.realtimehockey.net/testing.html
I need the slider to fill the entire container much like my current slider here: https://www.realtimehockey.net
HTML
<div id="slidy-container">
<figure id="slidy">
<img src="https://i.imgur.com/iVhs269.png" width="680" height="380" alt="Black-Biscuit Hockey Outfitters" data-caption="Black-Biscuit Hockey Outfitters">
<img src="https://i.imgur.com/cqMgCFa.png?2" width="680" height="380" alt="All Black Hockey Sticks" data-caption="All Black Hockey Sticks" >
<img src="https://i.imgur.com/WhSLIsE.png?1" width="680" height="380" alt="OneHockey Guinness World Record" data-caption="OneHockey Guinness World Record">
<img src="https://i.imgur.com/ZQ2KecX.png" width="680" height="380" alt="Planet Hockey Camps" data-caption="Planet Hockey Camps">
<img src="https://i.imgur.com/9x1H8wq.png" width="680" height="380" alt="OneHockey Tournaments" data-caption="OneHockey Tournaments">
<img src="https://i.imgur.com/1kzo8hS.jpg" width="680" height="380" alt="ScoreStream" data-caption="ScoreStream">
</figure>
</div>
JS
var cssSlidy = function(newOptions) {
var options = (function() {
var mergedOptions = {},
defaultOptions = {
timeOnSlide: 4,
timeBetweenSlides: 1,
slidyContainerSelector: '#slidy-container', // name of slider container
slidySelector: '#slidy', // name of slider
slidyDirection: 'left', // options: left, right
fallbackFunction: function() {},
cssAnimationName: 'slidy',
captionSource: 'data-caption', // options: data-caption, alt, none
captionBackground: 'rgba(0,0,0,0.8)',
captionColor: '#fff',
captionFont: 'anton',
captionPosition: 'bottom', // options: top, bottom
captionAppear: 'slide', // options: slide, perm, fade
captionSize: '1.3rem',
captionPadding: '.6rem'
};
for (var option in defaultOptions) mergedOptions[option] = defaultOptions[option];
for (var option in newOptions) mergedOptions[option] = newOptions[option];
return mergedOptions;
})(),
CS = this;
CS.animationString = 'animation';
CS.hasAnimation = false;
CS.keyframeprefix = '';
CS.domPrefixes = 'Webkit Moz O Khtml'.split(' ');
CS.pfx = '';
CS.element = document.getElementById(options.slidySelector.replace('#', ''));
CS.init = (function() {
// browser supports keyframe animation w/o prefixes
if (CS.element.style.animationName !== undefined) CS.hasAnimation = true;
// browser supports keyframe animation w/ prefixes
if (CS.hasAnimation === false) {
for (var i = 0; i < CS.domPrefixes.length; i++) {
if (CS.element.style[CS.domPrefixes[i] + 'AnimationName'] !== undefined) {
CS.pfx = domPrefixes[i];
CS.animationString = pfx + 'Animation';
CS.keyframeprefix = '-' + pfx.toLowerCase() + '-';
CS.hasAnimation = true;
// determines CSS prefix required for CSS animations
break;
}
}
}
if (CS.hasAnimation === true) {
var images = CS.element.getElementsByTagName("img"),
L = images.length,
fig = document.createElement('figure'),
who, temp;
while(L) {
temp = fig.cloneNode(false);
who = images[--L];
// wraps all images in the slider with <figure> tags
if (options.captionSource!=="none")
caption = who.getAttribute(options.captionSource);
who.parentNode.insertBefore(temp, who);
if (caption !== null) {
content = document.createElement('figcaption');
content.innerHTML = caption;
// places captions in each <figure> element, if required
}
temp.appendChild(who);
if (caption !== null) {
temp.appendChild(content);
}
}
var figs = CS.element.getElementsByTagName("figure");
var firstFig = figs[0]; // get the first figure inside the "slidy" element.
figWrap = firstFig.cloneNode(true); // copy it.
CS.element.appendChild(figWrap); // add the clone to the end of the images
var imgCount = images.length, // count the number of images in the slide, including the new cloned element
totalTime = (options.timeOnSlide + options.timeBetweenSlides) * (imgCount - 1), // calculate the total length of the animation by multiplying the number of _actual_ images by the amount of time for both static display of each image and motion between them
slideRatio = (options.timeOnSlide / totalTime) * 100, // determine the percentage of time an induvidual image is held static during the animation
moveRatio = (options.timeBetweenSlides / totalTime) * 100, // determine the percentage of time for an individual movement
basePercentage = 100 / imgCount, // work out how wide each image should be in the slidy, as a percentage.
position = 0, // set the initial position of the slidy element
css = document.createElement("style"); // start marking a new style sheet
// creating css style tag
css.type = "text/css";
css.id = options.slidySelector.replace('#', '') + "-css";
css.innerHTML += options.slidyContainerSelector + " { overflow: hidden; }\n";
css.innerHTML += options.slidySelector + " { text-align: left; margin: 0; font-size: 0; position: relative; width: " + (imgCount * 100) + "%; }\n"; // set the width for the inner slider container
css.innerHTML += options.slidySelector + " figure { float: left; margin: 0; position: relative; display: inline-block; width: " + basePercentage + "%; height: auto; }\n"; // set the width and size pf the inner <figure> elements
css.innerHTML += options.slidySelector + " figure img { width: 100%; }\n";
css.innerHTML += options.slidySelector + " figure figcaption { position: absolute; width: 100%; background-color: " + options.captionBackground + "; color: " + options.captionColor + "; font-family: " + options.captionFont + ";";
var captions = document.getElementsByTagName("figcaption");
var captionHeight = captions[0].offsetHeight*2 + parseInt(window.getComputedStyle(captions[0]).fontSize, 10);
if (options.captionPosition == "top") {
switch (options.captions) {
case 'fade':
css.innerHTML += " top: 0; opacity: 0;";
break;
case 'slide':
css.innerHTML += " top: -"+captionHeight+"px; ";
break;
default:
css.innerHTML += " top: 0;";
}
} else {
switch (options.captionAppear) {
case 'fade':
css.innerHTML += " bottom: 0; opacity: 0;";
break;
case 'slide':
css.innerHTML += " bottom: -"+captionHeight+"px; ";
break;
default:
css.innerHTML += " bottom: 0;";
}
}
css.innerHTML += " font-size: " + options.captionSize + "; padding: " + options.captionPadding + "; " + keyframeprefix + "transition: .5s; }\n";
css.innerHTML += options.slidySelector + ":hover figure figcaption { opacity: 1; ";
if (options.captionPosition == "top") { css.innerHTML += " top: 0px;"; }
else { css.innerHTML += " bottom: 0px;"; }
css.innerHTML += " }\n";
css.innerHTML += "#" + keyframeprefix + "keyframes " + options.cssAnimationName + " {\n";
if (options.slidyDirection == "right") {
for (i = imgCount - 1; i > 0; i--) { //
position += slideRatio; // make the keyframe the position of the image
css.innerHTML += position + "% { left: -" + (i * 100) + "%; }\n";
position += moveRatio; // make the postion for the _next_ slide
css.innerHTML += position + "% { left: -" + ((i - 1) * 100) + "%; }\n";
}
} else { // the slider is moving to the left
for (i = 0; i < (imgCount - 1); i++) { //
position += slideRatio; // make the keyframe the position of the image
css.innerHTML += position + "% { left: -" + (i * 100) + "%; }\n";
position += moveRatio; // make the postion for the _next_ slide
css.innerHTML += position + "% { left: -" + ((i + 1) * 100) + "%; }\n";
}
}
css.innerHTML += "}\n";
css.innerHTML += options.slidySelector + " { ";
if (options.slidyDirection == "right") { css.innerHTML += "left: " + imgCount*100+"%" }
else { css.innerHTML += "left: 0%; " }
css.innerHTML += keyframeprefix + "transform: translate3d(0,0,0); " + keyframeprefix + "animation: " + totalTime + "s " + options.cssAnimationName + " infinite; }\n"; // call on the completed keyframe animation sequence
// place css style tag
if (options.cssLocation !== undefined) options.cssLocation.appendChild(css);
else document.body.appendChild(css);
} else {
// fallback function
options.fallbackFunction();
}
})();
}
cssSlidy();
CSS
body {
background: #ffffff;
}
#slidy-container {
width: 70%;
margin: 0 auto;
overflow: hidden;
}

JavaScript Issue can not use function with HTML Tag

I have created a JavaScript exercise that changes the ID of an HTML object.
I want to set up a button that will cycle between choices. Right now the button is not executing the function.
Please take a look at the code and let me know what I am doing wrong.
a = 0;
n = 1;
i = 0;
function changexc(a, n) {
document.getElementById('effect00').id = "effect00" + (a + i);
}
function counterxc() {
i = n++;
return n;
}
document.write("<br>" + "a is " + a + "<br>");
document.write(" i is " + i + "<br>");
document.write(" n is " + n + "<br>");
document.write(" n + a is " + (n + a) + "<br>");
changexc(a);
<style>#effect001 {
max-width: 100px!important;
height: 200px;
background-color: red;
display: block;
}
#effect002 {
max-width: 200px!important;
height: 100px;
background-color: blue;
display: block;
}
#effect003 {
max-width: 300px!important;
height: 300px;
border-radius: 50%;
background-color: yellow;
display: block;
}
</style>
<div id="effect00"></div>
<button type="button" id="thatdarnbutton" onclick="counterxc ()">Click Me</button>
This code works - see explanation below
var a = 0;
var n = 1;
var i = 0;
function changexc() {
console.log(" added class : " + "effect00" + (a + i));
document.getElementById("effect00").className = "effect00" + (a + i);
console.log("<br>" + "a is " + a + "<br>");
console.log(" i is " + i + "<br>");
console.log(" n is " + n + "<br>");
console.log(" n + a is " + (n + a) + "<br>");
}
function counterxc() {
i = n + 1;
n++;
if(n >3) {
n = 0;
}
changexc();
}
changexc();
.effect001 {
max-width: 100px!important;
height: 200px;
background-color: red;
display: block;
}
.effect002 {
max-width: 200px!important;
height: 100px;
background-color: blue;
display: block;
}
.effect003 {
max-width: 300px!important;
height: 200px;
border-radius: 50%;
background-color: yellow;
display: block;
}
<div id="effect00">
hello world!
</div>
<button type="button" onClick="counterxc();">Click Me</button>
Its just "use strict"; javascript environment (node, browser etc) would assume/say that you can't use variables before you declare them and I suggest you do that. Its good practise:
However, as other have commented - start from basics, learn how browser uses javascript as well other environments such as node. I am still getting used to the new ES6 and ES7 syntax and all the new build systems. Its a whole lot to mention here but i would recommend the "You don't know JS" series of books
You code work fine, but need a little work.
First of you have to make sure that all element been loaded before you begin your work use setTimeout.
See down i have fixed your problem here and this should now work
a = 0;
n = 1;
i = 0;
var id = "effect00";
function changexc(a, n) {
document.getElementById(id).setAttribute("id", "effect00" + (a + i));
id = "effect00" + (a + i);
}
function counterxc() {
i = n++;
write();
return n;
}
function write() {
var resultDiv = document.getElementById(id);
var resultstring = "<br>" + "a is " + a + "<br>"
resultstring += " i is " + i + "<br>"
resultstring += " n is " + n + "<br>"
resultstring += " n + a is " + (n + a) + "<br>"
resultstring += "id is " + "effect00" + (a + i);
resultDiv.innerHTML = resultstring;
changexc(a)
}
setTimeout(function() { /// this is importent, wait untill elemtns have loaded
changexc(a);
write();
}, 100);
#effect001 {
max-width: 100px!important;
height: 200px;
background-color: red;
display: block;
}
#effect002 {
max-width: 200px!important;
height: 100px;
background-color: blue;
display: block;
}
#effect003 {
max-width: 300px!important;
height: 300px;
border-radius: 50%;
background-color: yellow;
display: block;
}
<button type="button" id="thatdarnbutton" onclick="counterxc()">Click Me</button>
<div id="effect00"></div>

Categories

Resources