I am new to JavaScript/CSS (basically the whole world of web dev) and I am really struggling to create the following widget. I created a picture of what I want to make to make it more clear.
The Play/Pause and Stop button are ready. Loop checkbox is no problem. But the progress bar is painful. The two markers are supposed to mark the point from where the file would start playing and where it would stop. The progress bar is also supposed to be click-able, so if I want to access a certain point in time, then its possible.
What I tried so far
jQuery UI slider: For a sliding progress bar and use that draggable slider to access a certain point in audio file. Works fine. But no markers and looks really ugly. Don't how to change it.
<progress> tag: not very flexible. Marker? Clicking?
<div> tag: there seems to be no way to get the point where I clicked.
So, what do you guys recommend? How should I proceed?
Canvas Alternative
You might want to use a canvas and draw your own progress bar element within it.
Here are some canvas progress bar tutorials:
How to create a progress bar with HTML5
A progress bar using HTML5 canvas
Doing it with <progress>
To access the clicked position within a DOMElement, you can proceed with the click event's properties: clientX and clientY (MDN Source), like so:
HTML
<div class="marker" id="StartMarker">^</div>
<div class="marker" id="StopMarker">^</div>
<progress id="progress" value="0" min="0" max="100">0%</progress>
<form id="choice">
<button id="marker1">Beginning marker</button>
<button id="marker2">Ending marker</button>
<input type="hidden" id="markerValue" value="0" />
</form>
JavaScript (not optimized)
document.getElementById('progress').onclick = function (event, element) {
/* Math.floor((event.offsetX / this.offsetWidth) * 100) */
var newProgress = event.offsetX;
document.getElementById('choice').style.display = "block";
document.getElementById('markerValue').setAttribute('value', newProgress);
document.getElementById('marker1').onclick = function (event) {
event.preventDefault();
var newProgress = document.getElementById('markerValue').value;
var progressBar = document.getElementById('progress');
var startMarker = document.getElementById('StartMarker');
var stopMarker = document.getElementById('StopMarker');
var marker = startMarker;
marker.style.display = "block";
startMarker.style.display = "block";
startMarker.offsetTop = (progressBar.offsetTop + progressBar.offsetHeight + 2) + "px";
startMarker.style.left = newProgress + "px";
};
document.getElementById('marker2').onclick = function (event) {
event.preventDefault();
var newProgress = document.getElementById('markerValue').value;
var progressBar = document.getElementById('progress');
var startMarker = document.getElementById('StartMarker');
var stopMarker = document.getElementById('StopMarker');
stopMarker.style.display = "block";
stopMarker.offsetTop = (progressBar.offsetTop + progressBar.offsetHeight + 2) + "px";
stopMarker.style.left = newProgress + "px";
};
};
CSS
.marker {
position:absolute;
top:24px;
left:9px;
display:none;
z-index:8;
font-weight:bold;
text-align:center;
}
#StartMarker {
color: #CF0;
}
#StopMarker {
color:#F00;
}
#choice {
display:none;
}
progress {
display: inline-block;
-moz-box-sizing: border-box;
box-sizing: border-box;
width: 300px;
height: 20px;
padding: 3px 3px 2px 3px;
background: #333;
background: -webkit-linear-gradient(#2d2d2d, #444);
background: -moz-linear-gradient(#2d2d2d, #444);
background: -o-linear-gradient(#2d2d2d, #444);
background: linear-gradient(#2d2d2d, #444);
border: 1px solid rgba(0, 0, 0, .5);
border-radius: 15px;
box-shadow: 0 1px 0 rgba(255, 255, 255, .2);
}
Live Demo
Using simple blocks for that is possible. Your layout would look like this (simplified):
HTML
<div class="progressbar">
<div class="bar">
<div class="progress" style="width: 30%;">
</div>
</div>
<div class="markers">
<div class="right" style="width: 70%;">
<div class="marker">
</div>
<div class="left" style="width: 20%;">
<div class="marker">
</div>
</div>
</div>
</div>
</div>
SCSS
.progressbar {
width: 20em;
background: grey;
.bar {
height: 2em;
.progress {
background: blue;
height: 100%;
}
}
.markers {
height: 1em;
background: white;
.right {
height: 100%;
background: red;
.marker {
width: 1em;
height: 100%;
background: green;
position: relative;
float: right;
}
.left {
background: white;
height: 100%;
}
}
}
}
The operations can be quite difficult
jQuery
$('.bar').click(function(e){
$(this).find('.progress').css('width', (e.offsetX / this.offsetWidth)*100+'%');
});
will set the Progressbar properly on clicks.
For the markers though you will need mousedown, mousemove, mouseleave events, since you got 2 of them.
Example
http://jsfiddle.net/JXauW/
Related
so im making some vanilla js draggable modal boxes but i keep having trouble when it comes to the dragging.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<link rel="stylesheet" type="text/css" href="css/main.css">
<title>Me website mate</title>
</head>
<body>
<!--------------------------------------------------------------------------------------->
<button id="buttonone" class="button">click me</button>
<div id="boxone" class="box">
<div id="headerone" class="header">header
<div class="box-buttons">
<div id="box-close-one" class="operation-button" style="background-color: rgb(207, 9, 33);">×</div>
<div id="box-maximize" class="operation-button" style="background-color: rgb(248, 201, 27);">max</div>
<div id="box-minimize" class="operation-button" style="background-color: rgb(0, 104, 69);">min</div>
</div>
</div>
<div class="content">
content
</div>
<div class="resize"></div>
</div>
<!---------------------------------------------------------------------------------------->
<button id="buttontwo" class="button">click me</button>
<div id="boxtwo" class="box" style="left: 500px;">
<div id="headertwo" class="header">header
<div class="box-buttons">
<div id="box-close-two" class="operation-button" style="background-color: rgb(207, 9, 33);">×</div>
<div id="box-maximize" class="operation-button" style="background-color: rgb(248, 201, 27);">max</div>
<div id="box-minimize" class="operation-button" style="background-color: rgb(0, 104, 69);">min</div>
</div>
</div>
<div class="content">
content
</div>
<div class="resize"></div>
</div>
<script src="javaScript/main.js"></script>
</body>
</html>
the html has 2 buttons and 2 modal boxes each button opening the assigned box, each box had a close button that hides said modal box
.box{
/*display: none;*/
font-family: "Comic Sans MS", cursive, sans-serif;
font-size: 12px;
background-color: #666;
border: 1px solid #000;
position: absolute;
height: 280px;
width: 400px;
margin: 2px;
position: absolute;
left: 0px;
z-index: 9;
}
.header{
position: relative;
height: 32px;
line-height: 32px;
font-size: 1.2em;
vertical-align: middle;
padding: 0 8px 0 8px;
white-space: normal;
overflow: hidden;
background: rgb(69, 161, 211);/*69, 161(golden ratio), 211(prime)*/
cursor: grab;
position: initial;
}
.box-buttons{
position: absolute;
display: flex;
flex-direction: row-reverse;
right: 0em;
top: 0em;
}
.operation-button{
height: 31px;
width: 31px;
border: 1px solid black;
text-align: center;
cursor: pointer;
}
.content{
position: absolute;
width: 400px;
height: 248px;
}
some styling
const boxOne = document.querySelector("#boxone");
boxOne.style.display = "none";
const boxTwo = document.querySelector("#boxtwo");
boxTwo.style.display = "none";
/////
const buttonOne = document.querySelector("#buttonone");
const closeOne = document.querySelector("#box-close-one");
const headOne = document.querySelector("#headerone");
buttonOne.addEventListener("click", function open(e){
openBox(boxOne);
});
closeOne.addEventListener("click", function close(e){
closeBox(boxOne);
});
headOne.addEventListener("mousedown",function grab(e){
mouseDown(boxOne, headOne,e);
});
/////
const buttonTwo = document.querySelector("#buttontwo");
const closeTwo = document.querySelector("#box-close-two");
const headTwo = document.querySelector("#headertwo");
buttonTwo.addEventListener("click",function open(e){
openBox(boxTwo);
});
closeTwo.addEventListener("click",function close(e){
closeBox(boxTwo);
});
function mouseDown(B,H,i){
var box = B;
var head = H;
head.style.cursor = "grabbing";
window.addEventListener("mousemove",drag);
window.addEventListener("mouseup",drop);
var windowHeight = window.innerHeight;
var windowWidth =window.innerWidth;
let previousX = i.clientX;
let previousY = i.clientY;
function drag(i){
let currentX = previousX - i.clientX;
let currentY = previousY - i.clientY;
const bounds = box.getBoundingClientRect();
console.log(bounds);
box.style.left = bounds.left - currentX + "px";
box.style.top = bounds.top - currentY + "px";
previousX = i.clientX;
previousY = i.clientY;
}
function drop(){
head.style.cursor = "grab";
window.removeEventListener("mousemove",drag);
window.removeEventListener("mouseup",drop);
}
}
function openBox(rect){
if (rect.style.display === "none") {
rect.style.display = "block";
}
console.log("open");
}
function closeBox(rectClose){
if(rectClose.style.display !== "none"){
rectClose.style.display = "none";
}
console.log("close");
}
it opens and closes well but it seems to be having a lot of trouble when i try to drag it. it always seems to go to the bottom right of the screen for some reason. Ive tried this project before but only with a single box, the code for the single box worked great and dragged perfectly fine but when ive tried to copy the same instructions , it fails. ik that it my code rn is inefficient but rn its just a prototype. Ive tried console.log to trouble shoot it but when i do the same to the previous project which worked fine, the output of the console looks pretty much the same. i dont know if im missing something bc i am a beginner, ive never taken a class on JS, so i dont really know what to look for or how to properly debug this. I would really appreciate the help and if possible, i would like to keep it in vanilla JS for the practice.
so after some experimenting, i boiled the answer down to the fact that the box moved 2 pixels to the right and 2 pixels down plus the movement of my mouse. I know this because I printed out the bounds variable to the console and moving my mouse only up (with a straightedge) and to the side. im still not sure what causes this however i just added a "-2" to the box.style.left and box.style.top to mitigate this problem so now the code is
box.style.left = (bounds.left - currentX) - 2 + "px";
box.style.top = (bounds.top - currentY) -2 + "px";
thank you to anybody that actually tired to figure it out and help me
There is a need to update css to dynamic value and I am not sure what's the best approach to it.
<div id="app" style="zoom: 0.XX;">
...
</div>
The zoom level will trigger based on window resize and the app will zoom according. I loaded this app into cordova and have it run within iPAD, then I realize the font-size needs to be adjusted to the same as zoom level using "-webkit-text-size-adjust" in order for it to not break the design layout.
My challenge is to set the css dynamically like this:
#app * {
-webkit-text-size-adjust : nn%
}
Where nn is the zoom X 100 + '%'
I have tried:
1) Set the style on the app div, but this doesn't help to apply to inner elements
<div id="app" style="zoom: 0.XX; -webkit-text-size-adjust: XX%">
2) Use javascript to set to all inner nodes, but not only I think this is less efficient, but it won't get trigger if my window doesn't resize, that means if I navigate to other pages, this logic won't get called.
REF: https://stackoverflow.com/questions/25305719/change-css-for-all-elements-from-js
let textSizeAdjust = function(zoom) {
let i,
tags = document.getElementById("app").getElementsByTagName("*"),
total = tags.length;
for ( i = 0; i < total; i++ ) {
tags[i].style.webkitTextSizeAdjust = (zoom * 100) + '%';
}
}
3) I tried using javascript, and most likely they are technically incorrect because querySelector return null.
document.querySelector('#app *').style.webkitTextSizeAdjust = zoom *100 + '%';
document.querySelector('#app').querySelector('*').style.webkitTextSizeAdjust = zoom * 100 + "%";
Ultimate, I believe I need to dynamically create the css, for the browser to apply this setting to the DOM:
#app * {
-webkit-text-size-adjust: nn
}
Please let me know if this is the right, or how to use javascript to create the above css and change the value dynamically?
CSS Variables
Requirements
HTML
Each form control that has numerical data should have:
value={a default, don't leave it blank}
class='num'
data-unit={unit of measurement or a single space}
The select/option tag should have the selected attribute
CSS
CSS Variable Signature: propertyName: var(--propertyValue)
// Declare CSS Variables at the top of a stylesheet
:root {
--mx0: 50px;
--my0: 50px;
--rz0: 1.0;
--zm0: 1.0;
--sp0: 360deg;
}
JavaScript
There's step by step details commented in the JavaScript Demo. Here's the most important statement in the code:
CSSStyleDeclaration CSS Variable
🢃 🢃
`ele.style.setProperty(`--${node.id}`,
${node.valueAsNumber}${node.dataset.unit})
🢁 🢁
HTMLInputElement DataSet API
Demo 1
// Reference form#UI
var ui = document.forms.UI;
// Register form#UI to change event
ui.addEventListener('change', setCSS);
// Callback passes Event Object
function setCSS(e) {
// Collect all form controls of form#UI into a NodeList
var fx = ui.elements;
// Reference select#pk0
var pk0 = fx.pk0;
// Get select#pk0 value
var pick = pk0.options[pk0.selectedIndex].value
// if the changed element has class .num...
if (e.target.className === 'num') {
// Reference Event Target
var tgt = e.target;
// Then reference is by its #id
var node = document.getElementById(tgt.id);
// DOM Object to reference either html, square, or circle
var ele;
/* Determine which tag to test on: html (affects everything),
|| #sQ<uare> and #ciR<cle> shapes.
*/
switch (pick) {
case "rT":
ele = document.documentElement;
break;
case "sQ":
ele = document.getElementById('sQ');
break;
case "cR":
ele = document.getElementById('cR');
break;
default:
break;
}
/* Sets a target element's Transform:
|| translateXY, scale, and rotate
*/
ele.style.setProperty(`--${node.id}`, `${node.valueAsNumber}${node.dataset.unit}`);
}
}
/* Declare CSS Variables on the :root selector at the top of sheet
All CSSVar must be prefixed with 2 dashes: --
*/
:root {
--mx0: 50px;
--my0: 50px;
--rz0: 1.0;
--sp0: 360deg;
}
.set {
border: 3px ridge grey;
border-bottom-left-radius: 6px;
border-bottom-right-radius: 6px;
padding: 5px;
}
/* The var() function's signature is:
propertyName: var(--propertyValue)
*/
#sQ {
position: relative;
background: rgba(0, 100, 200, 0.3);
width: 50px;
height: 50px;
transform: translateX(var(--mx0)) translateY(var(--my0)) scale(var(--rz0)) rotate(var(--sp0));
border: 3px ridge grey;
z-index: 1;
transition: all 1s ease;
}
#cR {
position: relative;
background: rgba(200, 100, 0, 0.3);
width: 50px;
height: 50px;
transform: translateX(var(--mx0)) translateY(var(--my0)) scale(var(--rz0)) rotate(var(--sp0));
border: 3px ridge grey;
border-radius: 50%;
transition: all 1s ease;
}
#sQ::before {
content: '\1f504';
text-align: center;
font-size: 2.25rem;
transform: translate(1px, -8px)
}
#cR::after {
content: '\1f3b1';
text-align: center;
font-size: 2.25rem;
}
input,
select {
display: inline-block;
width: 6ch;
font: inherit;
text-align: right;
line-height: 1.1;
padding: 1px 2px;
}
select {
width: 9ch
}
.extension {
overflow-y: scroll;
overflow-x: auto;
min-height: 90vh;
}
/* For debugging on Stack Snippets */
/*.as-console-wrapper {
width: 25%;
margin-left: 75%;
min-height: 85vh;
}*/
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<style></style>
</head>
<body>
<!--
HTML Requirements
Each form control that has numerical data should have:
1. value={a default, don't leave it blank}
2. class='num'
3. data-unit={unit of measurement or a single space}
4. The select/option tag should have the selected attribute
-->
<form id='UI'>
<section class='set'>
<label>X: </label>
<input id='mx0' class='num' type='number' min='-350' max='350' value='50' step='10' data-unit='px'>
<label>Y: </label>
<input id='my0' class='num' type='number' min='-350' max='350' value='50' step='10' data-unit='px'>
<label>Size: </label>
<input id='rz0' class='num' type='number' min='0' max='5' value='1' step='0.1' data-unit=' '>
<label>Spin: </label>
<input id='sp0' class='num' type='number' min='0' max='1440' value='360' step='180' data-unit='deg'>
<label>Pick: </label>
<select id='pk0' class='num'>
<option value='rT' selected>Root</option>
<option value='sQ'>Square</option>
<option value='cR'>Circle</option>
</select>
</section>
</form>
<section class='set extension'>
<div id='sQ' class='test shape' width="50" height="50"></div>
<div id='cR' class='test shape' width="50" height="50"></div>
</section>
</body>
</html>
Update
This update is specifically for OP, so this may be of help or not for other users.
Deno 2
:root {
--opc: 0;
--zoom: 1;
}
.fc {
display: inline-block;
width: 18ch;
margin:0 0 10px 0
}
#app * {
opacity: var(--opc);
transform: scale(var(--zoom));
}
<!doctype html>
<html>
<head>
<meta charset='utf-8'>
</head>
<body>
<form id='app' action='https://httpbin.org/post' method='post' target='view'>
<fieldset class='sec'>
<legend>App of Mystery</legend>
<input id='A0' name='A0' class='fc' type='text' placeholder='User Name'>
<input id='A1' name='A1' class='fc' type='password' placeholder='Password'>
<input type='submit'>
<input type='reset'>
<input id='zBtn' type='button' value='Zoom'>
<iframe name='view' frameborder='1' width='100%'></iframe>
</fieldset>
</form>
<script>
var node = document.querySelector('#app *');
var zBtn = document.getElementById('zBtn');
var flag = false;
document.addEventListener('DOMContentLoaded', function(e) {
node.style.setProperty("--opc", "0.5");
});
document.addEventListener('click', function(e) {
node.style.setProperty("--opc", "1");
});
zBtn.addEventListener('click', function(e) {
if (flag) {
flag = false;
node.style.setProperty("--zoom", "1");
} else {
flag = true;
node.style.setProperty("--zoom", "1.25");
}
});
</script>
</body>
</html>
I don't have much knowledge about -webkit-text-size-adjust
However, this should work for creating a dynamic stylesheet and inserting it:
I have added code to dynamically update it as well
const form = document.getElementById('colorChooser');
form.addEventListener('submit', (e) => {
e.preventDefault();
color = document.getElementById('colorInput').value;
const style = document.getElementById('colorStyle');
style.innerHTML = `#app * {
background-color: ${color};
}`;
});
const style = document.createElement('style');
style.id = 'colorStyle';
style.type = 'text/css';
style.innerHTML = `#app * {
background-color: red;
}`;
document.head.appendChild(style);
#app {
margin-bottom: 10px;
}
#inner {
width: 50px;
height: 50px;
background-color: black;
}
<div id="app">
<div id="inner"></div>
</div>
<form id="colorChooser">
<input id="colorInput" type="text" placeholder="red" />
<input type="submit" value="Update color"/>
</form>
I have a function that alters the size of a div when I click on it. Now I have to write the onclick command in my html page, but I want it to stand in the extern .js file.
Now in html:
<div id="box1" class="kaesten" onclick="changeSize('box1')"> Title 1 </div>
What I want:
<div id="box1" class="kaesten" > Title 1 </div>
Tried something in jquery but it didn't work:
function changeSize(id) {
var elem = document.getElementById(id);
var currentAbsoluteElem = document.getElementById('dummy');
var text = elem.innerHTML;
currentAbsoluteElem.innerHTML = text;
currentAbsoluteElem.setAttribute('style', 'display:block');
/*Extra styling neeed to be done here*/
}
var elems = document.getElementsByClassName('kaesten');
for (var i = 0; i < elems.length; i++) {
elems[i].onclick = function() {
changeSize(this.id);
}
}
var absoluteCl = document.getElementsByClassName('absoluteclass');
absoluteCl[0].onclick = function() {
console.log(document.getElementsByClassName('absoluteclass'))
document.getElementsByClassName('absoluteclass')[0].setAttribute('style', 'display:none');
}
$(document).ready(function() {
$('.kaesten').click(function() {
changeSize($(this).attr('id'));
});
});
.kaesten {
width: 240px;
height: 300px;
background-color: darkgrey;
background-position: center;
background-repeat: no-repeat;
text-shadow: 0px 0px 3px #000;
border: 5px solid #F0F8ff;
vertical-align: top;
text-shadow: 3px 3px 4px #777;
float: left;
margin-left: 30px;
}
.absoluteclass {
position: absolute;
background-color: darkgrey;
width: 600px;
height: 600px;
left: calc(30%);
display: none;
}
<div id="box1" class="kaesten">title1</div>
<div id="box2" class="kaesten">title2</div>
<div id="box3" class="kaesten">title3</div>
<div id="box4" class="kaesten">title4</div>
<div id="dummy" class="absoluteclass"></div>
I know it works in the fiddle, but I don't know why it doesn't work on my homepage without writing the function in the div's.
I guess the problem is that you are trying to assign the onclick event handler before the DOM is actually rendered and ready. My suggestion is to wrap your "initialization code" inside a $(document).ready() method. As follows:
$(document).ready(function() {
// Apply the on click event handlers here, using jQuery or not
// For instance:
$('.kaesten').click(function() {
changeSize($(this).attr('id'));
});
});
if you want to pass the id from jquery to your function you should do it like this:
$(function(){
$(".kaesten").click(function(){
changeSize($(this).attr("id"));
});
});
you can use .css in jquery
$(function(){
$(".kaesten").click(function(){
$(this).css({'width' : '600px' , 'height' : '600px'});;
});
});
I have made a makeshift progress bar with two divs, styled with css to fit one in another to make the progress bar. I have a button that changes the width of the inside div to go up when I click the button, but the button click does not change the width of the div. I made sure I made no errors, the javascript console in my chrome browser gives no errors when I click the button. Anyways, here is my code:
function clickMe() {
var newExp = parseInt(document.getElementById("expHold").innerHTML);
document.getElementById("bar2").style.width = newExp + 'px';
document.getElementById("expHold").innerHTML += '+1';
document.getElementById("expHold").innerHTML = eval(document.getElementById("expHold").innerHTML);
}
#bar1 {
border: 2px solid gold;
height: 15px;
width: 100px;
background-color: blue;
border-radius: 8px;
}
#bar2 {
height: 15px;
width: 1px;
background-color: skyblue;
border-radius: 8px;
}
<div id="bar1">
<div id="bar2">
</div>
</div>
<p>
<input type="button" value="Click me" onClick="clickMe()" />
<span id="expHold" style="color:black;">1</span>
I would appreciate any help telling me what I am doing wrong, thanks!
Please do not use inline JavaScript. It reduces readability and maintainability.
You should use a JavaScript variable to store the exp, this way you don't have to repeatedly query the DOM, which is process intensive.
You should cache the DOM objects instead of creating new ones on each iteration.
You can increment the previously created exp variable by using the prefix increment modifier
The prefix increment modifier will return the incremented value.
The postfix increment modifier will return the value before incrementing.
var exp = 0, current;
var bar1 = document.getElementById("bar1");
var bar2 = document.getElementById("bar2");
var hold = document.getElementById("expHold");
var max = bar1.clientWidth;
document.getElementById('my-button').onclick = function() {
// Don't go past the end.
if(bar2.clientWidth < max) {
current = ++exp;
hold.textContent = current;
bar2.style.width = current + 'px';
}
}
#bar1 {
border: 2px solid gold;
height: 15px;
width: 100px;
background-color: blue;
border-radius: 8px;
}
#bar2 {
height: 15px;
width: 0px;
background-color: skyblue;
border-radius: 8px;
}
<div id="bar1">
<div id="bar2">
</div>
</div>
<p>
<input type="button" value="Click me" id="my-button" />
<span id="expHold" style="color:black;">0</span>
I need to build inline rating for tv shows for example. Max rating I put in jQuery code, current rating in html document. This is how I found the way to do this.
$(document).ready(function() {
var maxRating = $('.rate-line').width();
var maxRating = 6; //max-rating
var currentRatingFirst = $('.first-rd').text();
var calc = (currentRatingFirst / maxRating) * 100 + "%";
$('.first-rl span.fill').width(calc);
});
.rate-line {
border: 1px solid #bababa;
background: #fff;
position: relative;
vertical-align: middle;
margin-right: 1.25em;
overflow: hidden;
width: 50%;
height: 20px;
}
.rate-line, .rate-data, .fill {
display:inline-block;
}
.fill {
background: #ff6292;
height: 22px;
position: absolute;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<div>
<span class="rate-line first-rl">
<span class="fill"></span>
</span>
<span class="rate-data first-rd">4.56</span>
</div>
But, I need to create 6 rating lines for this month, then 6 for next and so on. And every time I must give new unique classes to make it work. And code becomes huge. And one more, all this rating nested to bootstrap carousel items and when I duplicate it nothing works .I'm not good in JavaScript at all and I'm asking your help. Would you please tell me how to make it work correctly and make it easier?
In this case it makes sense to create basin custom plugin, so you can easily reuse it without duplicating code.
Here is a very basic example of how you can extend jQuery prototype with a new method:
$.fn.rating = function(options) {
return this.each(function() {
var maxRating = $(this).find('.rate-line').width();
var maxRating = 6;
var currentRatingFirst = $(this).find('.first-rd').text();
var calc = (currentRatingFirst / maxRating) * 100 + "%";
$(this).find('.first-rl span.fill').width(calc);
});
};
$(document).ready(function () {
$('.rating').rating();
});
.rate-line {
border: 1px solid #bababa;
background: #fff;
position: relative;
vertical-align: middle;
margin-right: 1.25em;
overflow: hidden;
width: 50%;
height: 20px;
}
.rate-line, .rate-data, .fill {
display:inline-block;
}
.fill {
background: #ff6292;
height: 22px;
position: absolute;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="rating">
<span class="rate-line first-rl">
<span class="fill"></span>
</span>
<span class="rate-data first-rd">4.56</span>
</div>
<div class="rating">
<span class="rate-line first-rl">
<span class="fill"></span>
</span>
<span class="rate-data first-rd">3.21</span>
</div>