issue in video path in js file - javascript

I am trying to create Video gallery playlist using HTML CSS and JavaScript. I have created html and css and two js files
one to include all videos as shown here:
let allVideos = [
{
name: "Button Hover Effect",
src: "https://youtu.be/ykuD2QOZkhc",
id: "vid_1"
},
{
name: "Button Hover Effect",
src: "https://youtu.be/ykuD2QOZkhc",
id: "vid_2"
},
{
name: "Confirm Password using Html CSS & js",
src: "https://youtu.be/ykuD2QOZkhc",
id: "vid_3"
},
{
name: "Creative Card Hover Effect",
src: "https://youtu.be/ykuD2QOZkhc ",
id: "vid_4"
},
{
name: "Creative Digital Clock Ui Design",
src: "https://youtu.be/ykuD2QOZkhc",
id: "vid_5"
},
{
name: "Creative Our Team Section",
src: "https://youtu.be/ykuD2QOZkhc",
id: "vid_6"
},
{
name: "Filter Text Animation Using Html and CSS",
src: "https://youtu.be/ykuD2QOZkhc",
id: "vid_7"
},
{
name: "Glassmorphism Calculater New Design",
src: "https://youtu.be/ykuD2QOZkhc"
},
{
name: "How To Make Cheatsheet",
src: "https://youtu.be/ykuD2QOZkhc",
id: "vid_9"
},
{
name: "How to create Login Form",
src: "https://youtu.be/ykuD2QOZkhc",
id: "vid_10"
},
{
name: "How To Make Animated Menu Icon",
src: "https://youtu.be/ykuD2QOZkhc",
id: "vid_11"
},
{
name: "How to make Read More Function",
src: "https://youtu.be/ykuD2QOZkhc",
id: "vid_12"
},
{
name: "Vertical Navigation Bar",
src: "https://youtu.be/ykuD2QOZkhc",
id: "vid_13"
}
]
and one for the playlist script here
const mainVideo = document.querySelector('#main-Video');
const musicList = document.querySelector('.music-list');
const playlist = document.getElementById('playlist');
const AllLessons = document.querySelector('.AllLessons');
const videoTitle = document.querySelector('.title');
const ulTag = document.querySelector("ul");
AllLessons.innerHTML = `${allVideos.length} Lessons`
let musicIndex = 1;
window.addEventListener('load',()=>{
loadMusic(musicIndex);
playingNow();
})
function playMusic(){
mainVideo.play();
playlist.classList.add('active')
}
function loadMusic(indexNumb){
mainVideo.src = `${allVideos[indexNumb - 1].src}.mp4`;
videoTitle.innerHTML = `${indexNumb}. ${allVideos[indexNumb - 1].name}`
}
for(let i = 0; i < allVideos.length; i++){
let liTag = `<li li-index="${i + 1}">
<div class="row">
<span>${i + 1}. ${allVideos[i].name}</span>
</div>
<video class="${allVideos[i].id}" src="${allVideos[i].src}.mp4" style="display: none;" title="${allVideos[i].name}"></video>
<span id="${allVideos[i].id}" class="duration"></span>
</li>`;
playlist.insertAdjacentHTML('beforeend',liTag);
let liVideoDuration = ulTag.querySelector(`#${allVideos[i].id}`)
let liVideoTag = ulTag.querySelector(`.${allVideos[i].id}`);
liVideoTag.addEventListener("loadeddata", ()=>{
let videoDuration = liVideoTag.duration;
let totalMin = Math.floor(videoDuration / 60);
let totalSec = Math.floor(videoDuration % 60);
totalSec < 10 ? totalSec = "0"+ totalSec : totalSec
liVideoDuration.innerText = `${totalMin}:${totalSec}`;
liVideoDuration.setAttribute("t-duration", `${totalMin}:${totalSec}`);
})
}
const allLiTags = playlist.querySelectorAll('li');
function playingNow(){
for(let j = 0; j<allVideos.length; j++){
if(allLiTags[j].classList.contains('playing')){
allLiTags[j].classList.remove("playing")
}
if(allLiTags[j].getAttribute('li-index')==musicIndex){
allLiTags[j].classList.add('playing')
}
allLiTags[j].setAttribute("onclick", "clicked(this)")
}
}
function clicked(element){
let getIndex = element.getAttribute("li-index");
musicIndex = getIndex;
loadMusic(musicIndex);
playMusic();
playingNow();
}
everything working fine except the scr video in js "all Videos" file. it is not working.
can you please help to fix it?

Probably because of this line:
mainVideo.src = `${allVideos[indexNumb - 1].src}.mp4`;
The src property of the "video" object in allVideos returns a string, and you're concatenating that with '.mp4', not getting the source of the video.

Related

How to change value of global variable inside function

I know this has been asked before, but my case seems to be little bit different
I have two js files, one for logic, one for objects which includes data about movie(s)
my first file looks like this
var movieTitle = document.getElementById("movieTitle");
var rating = document.getElementById("rating");
var movieYear = document.getElementById("movieYear");
var movieDuration = document.getElementById("movieDuration");
var actorName = document.getElementById("actorName");
var actorRole = document.getElementById("actorRole");
var actorNameI = document.getElementById("actorName2");
var actorRoleII = document.getElementById("actorRole2");
var testClick = document.getElementById("testClick");
var movie = movieI;
movieTitle.innerHTML = "Title: " + movie.title;
movieYear.innerHTML = "release Year: " + movie.releaseYear;
movieDuration.innerHTML = "Duration: " + movie.duration;
actorName.innerHTML = "Name: " + movie.actors[0].name;
actorRole.innerHTML = "Role: " + movie.actors[0].role;
actorNameI.innerHTML = "Name: " + movie.actors[1].name;
actorRoleII.innerHTML = "Role: " + movie.actors[1].role;
rating.innerHTML = "Rating: " + movie.rating;
testClick.addEventListener("click", function(){
var movie = movieII
})
file from where i fetch objects looks like this
var movieI = {
title: "Titanic",
releaseYear: 1997,
rating: "PG21",
duration: "3 hours",
actors: [
{
name: "leonardo dicaprio",
role: "role goes here"
},
{
name: "kate winslet",
role: "role goes here"
},
]
};
var movieII = {
title: "Wolf of wall street",
releaseYear: 2013,
rating: "PG18",
duration: "2H 30M",
actors: [
{
name: "leonardo dicaprio",
role: "role goes here"
},
{
name: "jonah hill",
role: "role goes here"
},
]
};
on my first js file i have following function
testClick.addEventListener("click", function(){
movie = movieII
})
this is supposed to modify value of movie variable and set it to movieII so it can switch/access second object(movieII) from my objects file, but it does not seem to be working.
Your problem is that updating the object doesn't change what has already been shown in the HTML, you need to update your HTML with the new information but only after it changed in the variable.
You can do that linear ( as you have in your code) or just creating a function that you can call every time and will help you avoiding duplicated code.
Here is one way you can do that:
//Titanic
let movieI = {
title: "Titanic",
releaseYear: 1997,
rating: "PG21",
duration: "3 hours",
actors: [
{
name: "leonardo dicaprio",
role: "role goes here"
},
{
name: "kate winslet",
role: "role goes here"
},
]
};
let movieII = {
title: "Wolf of wall street",
releaseYear: 2013,
rating: "PG18",
duration: "2H 30M",
actors: [
{
name: "leonardo dicaprio",
role: "role goes here"
},
{
name: "jonah hill",
role: "role goes here"
},
]
};
let actorsBox = document.getElementById("actos-box");
let movieTitle = document.getElementById("movieTitle");
let rating = document.getElementById("rating");
let movieYear = document.getElementById("movieYear");
let movieDuration = document.getElementById("movieDuration");
let actorName = document.getElementById("actorName");
let actorRole = document.getElementById("actorRole");
let actorNameI = document.getElementById("actorName2");
let actorRoleII = document.getElementById("actorRole2");
let testClick = document.getElementById("testClick");
let movie = movieI;
updateMovie();
testClick.addEventListener("click", function(){
movie = movieII
updateMovie();
})
function updateMovie(){
movieTitle.innerHTML = "Title: " + movie.title;
movieYear.innerHTML = "release Year: " + movie.releaseYear;
movieDuration.innerHTML = "Duration: " + movie.duration;
actorName.innerHTML = "Name: " + movie.actors[0].name;
actorRole.innerHTML = "Role: " + movie.actors[0].role;
actorNameI.innerHTML = "Name: " + movie.actors[1].name;
actorRoleII.innerHTML = "Role: " + movie.actors[1].role;
rating.innerHTML = "Rating: " + movie.rating;
}
Also I highly recommend you not to use var as it can do weird things you might not want to do.
Take a look at this for learning more about let variables.
Have you try to use function and parameters for this project?
Here was the docs
Function in js

How to limit an array field in javascript object to a certain length

I know this may a simple problem but I have a the following javascript object:
const categories = {
title: 'cat1',
contents: [
{
name: 'cont1'
},
{
name: 'cont2'
},
{
name: 'cont3'
}
]
}
How can a transform this categories object so it has only 2 contents element as an example?
const transformedCategories = {
title: 'cat1',
contents: [
{
name: 'cont1'
},
{
name: 'cont2'
}
]
}
A couple of ways to do it:
const transformedCategories = {
title: categories.title,
contents: categories.contents.slice(0,2) // you can also use splice here
}
Another, slightly cheeky way:
const contents = [...categories.contents];
contents.length = 2;
const transformedCategories = {...categories, contents}

Get text of previous header in HTML

I have a HTML which looks like this:
<h1>Title</h1>
<p>Some additional content, can be multiple, various tags</p>
<h2><a id="123"></a>Foo</h2>
<p>Some additional content, can be multiple, various tags</p>
<h3><a id="456"></a>Bar</h3>
Now, for each anchor with id, I want to find out the header hierarchy, e.g. for the anchor with id="123" I would like to get something like [{level: 1, title: "Title"}, {level: 2, title: "Foo"}], similarly for anchor with id="456", I would like to get [{level: 1, title: "Title"}, {level: 2, title: "Foo"}, {level: 3, title: "Bar"}].
My code looks like this so far:
const linkModel: IDictionary<ILinkModelEntry> = {};
const $ = cheerio.load(html);
$("a").each((_i, elt) => {
const anchor = $(elt);
const id = anchor.attr().id;
if (id) {
const parent = anchor.parent();
const parentTag = parent.prop("tagName");
let headerHierarchy: any[] = [];
if (["H1", "H2", "H3", "H4", "H5", "H6"].includes(parentTag)) {
let level = parseInt(parentTag[1]);
headerHierarchy = [{level, text: parent.text()}];
level--;
while (level > 0) {
const prevHeader = parent.prev("h" + level);
const text = prevHeader.text();
headerHierarchy.unshift({level, text});
level--;
}
}
linkModel["#" + id] = {originalId: id, count: count++, headerHierarchy};
}
});
What am I doing wrong, since
const prevHeader = parent.prev("h" + level);
const text = prevHeader.text();
always returns an empty string (i.e. "")?
If I understand correctly, you're looking to capture hierarchy. If your example had another <h1> followed by more <h2> and <h3>s below it, you'd want to pop the stack of parents back down to that new <h1> level for linking future <h2> and <h3> children rather than have an array of all elements back up to that first <h1>Title</h1>.
Here's one approach:
const cheerio = require("cheerio"); // ^1.0.0-rc.12
const html = `
<h1>Title</h1>
<p>Some additional content, can be multiple, various tags</p>
<h2><a id="123"></a>Foo</h2>
<p>Some additional content, can be multiple, various tags</p>
<h3><a id="456"></a>Bar</h3>
<h1>Another Title</h1>
<h2><a id="xxx"></a>Foo 2</h2>
<h3><a id="yyy"></a>Bar 2</h3>`;
const $ = cheerio.load(html);
const result = {};
const stack = [];
[...$("h1,h2,h3,h4,h5,h6")].forEach(e => {
const level = +$(e).prop("tagName")[1];
while (stack.length && level <= stack.at(-1).level) {
stack.pop();
}
if (!stack.length || level >= stack.at(-1).level) {
stack.push({level, title: $(e).text()});
}
if ($(e).has("a[id]").length) {
const id = $(e).find("a[id]").attr("id");
result[`#${id}`] = [...stack];
}
});
console.log(result);
Output:
{
'#123': [ { level: 1, title: 'Title' }, { level: 2, title: 'Foo' } ],
'#456': [
{ level: 1, title: 'Title' },
{ level: 2, title: 'Foo' },
{ level: 3, title: 'Bar' }
],
'#xxx': [
{ level: 1, title: 'Another Title' },
{ level: 2, title: 'Foo 2' }
],
'#yyy': [
{ level: 1, title: 'Another Title' },
{ level: 2, title: 'Foo 2' },
{ level: 3, title: 'Bar 2' }
]
}
If you actually want the whole chain of ancestors linearly back to the first, then remove the while loop (unlikely your intent).

Recursive Function to Create DOM Tree String from DOM Object

I'm currently struggling with trying to build out a function that should take an input object from parsing HTML5 (node-html5-parser) and I need to process all tags and children tags, with their content to output a string of xml. The issue I'm running into is how to get a recursive function (or any function) to properly maintain the HTML5 tag order and outputting the content.
Example:
<div><span>My Content</span></div>
With the node-html5-parser, I get the following when it parses that:
rootElem {
childNodes: [
{
tagName: 'div',
childNodes: [
{
tagName: 'span',
childNodes: [
{
rawText: 'My Content'
}
],
}
]
}
]
}
I thought a simple DFS recursive algorithm could be used to build up a string, but I can't get it to work correctly.
const DOMRootObj = parse(this.htmlStr);
const processedData = this.processContent(DOMRootObj);
processContent(root: any): string {
if (root && !root.childNodes.length) {
return root.rawText;
} else {
for (const childNode of root.childNodes) {
const str = this.processContent(childNode);
const { tagName } = childNode;
if (tagName) {
this.outputStr += `<${tagName}>${str}</${tagName}>`;
}
}
}
}
from this HTML that's parsed by the parse() function: (object is as above)
<div><span>My Content</span></div>
This ends up outputting:
<span>undefined</span><div>undefined</div>
but It should output:
<div><span>My Content</span></div>
Not sure which XML format you expect, but the recursive call is not that hard to implement:
function toString(node, name="root") {
let tag = typeof name === "string" ? name : node.tagName;
return tag ? `<${tag}>${(node.childNodes||[]).map(toString).join``}</${tag}>`
: (node.rawText || "");
}
// Sample:
let rootElem = {
childNodes: [{
tagName: 'div',
childNodes: [{
tagName: 'span',
childNodes: [{
rawText: 'My Content'
}],
}]
}]
};
console.log(toString(rootElem, "root"));
Ive got a few days some same kind of problem inside a browsere. I want to walk over a dom tree and execute a function with given parameters on the nodes. In my case i want to reassign the element id if any. Thats why the function is named nodeinit. Anyhow
function nodeinit(node,dataset){console.log(node);}
function shadowWalker(node, nodeinit, dataset) {
nodeinit(node, dataset);
if (node) {
console.log(node.id);
if (node.childNodes.length > 0) {
node = node.firstChild; //needed to init while loop
while (node) {
shadowWalker(node, nodeinit, dataset);
node = node.nextSibling;
}
}
}
}
So its called with the node to start of. Nodeinit is a function and dataset is the parameter object for the nodeinit function (some kind of presets). Some similar answers you can find here by looking for transverse dom tree. Just as a idea or starting point.
Unpolished code, but you can get the ideia. You can add more attributes like onclick and tabindex simply by repeating the pattern. Although I don't think putting everything on the generator a good idea (you can lose track of what's being generated).
fillHeaderCurrenciesList = () => {
// Generated structure example
// <div
// id='currency-1'
// class='currency currency--hoverable'
// onclick='selectMainCurrency(this.id)'
// >
// <div class='currency__name'>Bitcoin</div>
// <div class='currency__icon'>
// <img src='assets/img/icon-coin.svg' alt='LG Bank' />
// <img src='assets/img/icon-btc.svg' alt='LG Bank' />
// </div>
// <div class='currency__balance'>
// <span class='currency__title'>Balance</span>
// <div class='currency__value'>
// <span>Exemplo1 | R$ 234.342.367,90</span>
// </div>
// </div>
// </div>;
let currenciesList = document.getElementById('currencies-list');
for (let i = 0; i < currencyData.length; i++) {
const currency = currencyData[i];
let currencyTree = {
tagName: 'div',
id: `currency-${i}`,
class: ['currency', 'currency--hoverable'],
onClick: function () {
selectMainCurrency(this, 'currencies-main-currency');
},
onKeyDown: function () {
keyDownEnter(
selectMainCurrency(this, 'currencies-main-currency')
);
},
tabIndex: '0',
children: [
{
tagName: 'div',
class: ['currency__name'],
text: currency.name,
},
{
tagName: 'div',
class: ['currency__icon'],
children: [
{
tagName: 'img',
src: currency.icon.src,
alt: currency.icon.alt,
},
{
tagName: 'img',
src: currency.iconName.src,
alt: currency.iconName.alt,
},
],
},
{
tagName: 'div',
class: ['currency__balance'],
children: [
{
tagName: 'span',
class: ['currency__title'],
text: 'Balance',
},
{
tagName: 'div',
class: ['currency__value'],
children: [
{
tagName: 'span',
text: currency.balance,
},
],
},
],
},
],
};
currenciesList.appendChild(DOMListItemGenerator(currencyTree));
}
};
const currencyData = [
{
name: 'bitcoin',
icon: {
src: 'assets/img/icon-coin.svg',
alt: 'LG Bank',
},
iconName: {
src: 'assets/img/icon-btc.svg',
alt: 'LG Bank',
},
quotation: '',
balance: 'Exemplo1bitcoin | R$ 234.342.367,90',
},
{
name: 'ethereum',
icon: {
src: 'assets/img/icon-coin.svg',
alt: 'LG Bank',
},
iconName: {
src: 'assets/img/icon-btc.svg',
alt: 'LG Bank',
},
quotation: '',
balance: 'Exemplo2ethereum | R$ 234.342.367,90',
},
{
name: 'ethereum',
icon: {
src: 'assets/img/icon-coin.svg',
alt: 'LG Bank',
},
iconName: {
src: 'assets/img/icon-btc.svg',
alt: 'LG Bank',
},
quotation: '',
balance: 'Exemplo2ethereum | R$ 234.342.367,90',
},
{
name: 'ethereum',
icon: {
src: 'assets/img/icon-coin.svg',
alt: 'LG Bank',
},
iconName: {
src: 'assets/img/icon-btc.svg',
alt: 'LG Bank',
},
quotation: '',
balance: 'Exemplo2ethereum | R$ 234.342.367,90',
},
{
name: 'teste',
icon: {
src: 'assets/img/icon-coin.svg',
alt: 'LG Bank',
},
iconName: {
src: 'assets/img/icon-btc.svg',
alt: 'LG Bank',
},
quotation: '',
balance: 'Exemplo3teste | R$ 234.342.367,90',
},
];
fillHeaderCurrenciesList();
DOMListItemGenerator = (inputTree) => {
let tree = Object.entries(inputTree);
let item;
let output;
for (let i = 0; i < tree.length; i++) {
const branch = tree[i];
if (branch[0] === 'tagName') {
output = document.createElement(branch[1]);
}
if (branch[0] === 'id') {
output.setAttribute('id', branch[1]);
}
if (branch[0] === 'tabIndex') {
output.setAttribute('tabindex', branch[1]);
}
if (branch[0] === 'class') {
for (const classItem of branch[1]) {
output.classList.add(classItem);
}
}
if (branch[0] === 'src') {
output.src = branch[1];
}
if (branch[0] === 'alt') {
output.alt = branch[1];
}
if (branch[0] === 'text') {
output.textContent = branch[1];
}
if (branch[0] === 'onClick') {
output.onclick = branch[1];
}
if (branch[0] === 'onKeyDown') {
output.onkeydown = branch[1];
}
if (branch[0] === 'children' && branch[1].length > 0) {
for (let j = 0; j < branch[1].length; j++) {
const children = branch[1][j];
item = DOMListItemGenerator(children);
output.appendChild(item);
}
}
}
return output;
};

Create randomly generated divs that fill a box jQuery and Javascript

I have a section on my website that is 100% wide and 450 pixels tall.
My html looks like so...
<section class="interactive-banner">
<figure></figure>
</section>
I want each 'figure' element to be 150 pixels wide and 150 pixels tall, I want to generate the 'figure' html automatically and randomly with jQuery, and to consist of some inner html.
I have the following...
$(function(){
var people = [
{ id: 1 },
{ id: 2 }
];
var figure = $('figure');
w = 1500;
h = 450;
var counter = 0;
var data = people[Math.floor(Math.random()*people.length)];
(function nextFade() {
counter++;
figure.clone().html(data.name).appendTo('.interactive-banner').hide().fadeIn(150, function() {
if(counter < 30) nextFade();
});
})();
});
I want each figure element to fade in 1 after the other, in total I will only have 7 original figures, only these 7 will be randomly cloned until i have 30 iterations in total, I want the figure html to contain the data inside each object in my people array, so each figure is an object so to speak, output as so...
<figure>
<img src="[image src from object inside array]" />
<div class="information">
<h5>[name from object inside of array ]</h5>
<p>[job title from object inside of array ]</p>
</div>
</figure>
only at the minute its being output as so...
<figure style="display: block;">
Chris
</figure>
Ive created an example here, as you see however each figure contains the same information...
http://jsfiddle.net/pGmeE/
http://jsbin.com/isopin/1/edit
Don't populate your section initially and don't clone your figure element with jQ. Rather create a new one at every loop iteration.
<section class="interactive-banner"></section>
jQ:
$(function(){
var people = [
{ id: 1, name: 'Justin', title: 'Head Designer', bio: 'This is Justin\'s Biography.', image: 'justin.jpg' },
{ id: 2, name: 'Chris', title: 'Head Developer', bio: 'This is Chris\' Biography.', image: 'chris.jpg' },
{ id: 3, name: 'Sam', title: 'Developer', bio: 'This is Sam\'s Biography.', image: 'sam.jpg' },
{ id: 4, name: 'Haythem', title: 'Developer', bio: 'This is Haythem\'s Biography.', image: 'haythem.jpg' },
{ id: 5, name: 'Geoff', title: 'Designer', bio: 'This is Geoff\'s Biography.', image: 'geoff.jpg' },
{ id: 6, name: 'Liam', title: 'Designer', bio: 'This is Liam\'s Biography.', image: 'liam.jpg' }
];
w = 1500;
h = 450;
var counter = 0;
(function nextFade() {
counter++;
// Give "random" a chance to get random again
var data = people[Math.floor(Math.random()*people.length)];
// Now create a new Figure element:
var figure = $('<figure />');
figure.html(data.name).appendTo('.interactive-banner').hide().fadeIn(150, function() {
if(counter < 30) nextFade();
});
})();
});

Categories

Resources