Carousel testimonial auto scroll with description - html

I have carousel testimonial, the carousel is working with click on right left arrow, I want auto slide images and particular testimonial person need to heading in top of image and description in bottom of image, as per image slide, heading and description should shows in middle of testimonial for each testimonial member, I have attached the image for reference, of someone have any testimonial section like this so please share with me, please help really appreciated[
<script>
const galleryContainer = document.querySelector('.gallery-container');
const galleryControlsContainer = document.querySelector('.gallery-controls');
const galleryControls = ['previous', 'add', 'next'];
const galleryItems = document.querySelectorAll('.gallery-item');
class Carousel {
constructor(container, items, controls) {
this.carouselContainer = container;
this.carouselControls = controls;
this.carouselArray = [...items];
}
updateGallery() {
this.carouselArray.forEach(el => {
el.classList.remove('gallery-item-1');
el.classList.remove('gallery-item-2');
el.classList.remove('gallery-item-3');
el.classList.remove('gallery-item-4');
el.classList.remove('gallery-item-5');
});
this.carouselArray.slice(0, 5).forEach((el, i) => {
el.classList.add(`gallery-item-${i+1}`);
});
}
setCurrentState(direction) {
if (direction.className == 'gallery-controls-previous') {
this.carouselArray.unshift(this.carouselArray.pop());
} else {
this.carouselArray.push(this.carouselArray.shift());
}
this.updateGallery();
}
setControls() {
this.carouselControls.forEach(control => {
galleryControlsContainer.appendChild(document.createElement('button')).className = `gallery-controls-${control}`;
document.querySelector(`.gallery-controls-${control}`).innerText = control;
});
}
useControls() {
const triggers = [...galleryControlsContainer.childNodes];
triggers.forEach(control => {
control.addEventListener('click', e => {
e.preventDefault();
if (control.className == 'gallery-controls-add') {
const newItem = document.createElement('img');
const latestItem = this.carouselArray.length;
const latestIndex = this.carouselArray.findIndex(item => item.getAttribute('data-index') == this.carouselArray.length)+1;
Object.assign(newItem,{
className: 'gallery-item',
src: `#{this.carouselArray.length+1}`
});
newItem.setAttribute('data-index', this.carouselArray.length+1);
this.carouselArray.splice(latestIndex, 0, newItem);
document.querySelector(`[data-index="${latestItem}"]`).after(newItem);
this.updateGallery();
} else {
this.setCurrentState(control);
}
});
});
}
}
const exampleCarousel = new Carousel(galleryContainer, galleryItems, galleryControls);
exampleCarousel.setControls();
// exampleCarousel.setNav();
exampleCarousel.useControls();
</script>
.gallery {
width: 100%;
position: relative;
}
.gallery-container {
align-items: center;
display: flex;
height: 400px;
margin: 0 auto;
max-width: 1000px;
position: relative;
}
.gallery-item {
height: 150px;
opacity: 0;
position: absolute;
transition: all 0.3s ease-in-out;
width: 100px;
z-index: 0;
}
.gallery-item-1 {
left: 15%;
opacity: .4;
transform: translateX(-50%);
margin-top: 150px;
}
.gallery-item-2,
.gallery-item-4 {
height: 150px;
opacity: 1;
width: 100px;
z-index: 1;
}
.gallery-item-2 {
left: 30%;
transform: translateX(-88%);
margin-top: 150px;
}
.gallery-item-3 {
box-shadow: 0 0 30px rgba(255, 255, 255, 0.6), 0 0 60px rgba(255, 255, 255, 0.45), 0 0 110px rgba(255, 255, 255, 0.25), 0 0 100px rgba(255, 255, 255, 0.1);
height: 250px;
opacity: 1;
left: 50%;
transform: translateX(-50%);
width: 350px;
z-index: 2;
margin-top: 50px;
}
.gallery-item-4 {
left: 70%;
transform: translateX(-12%);
margin-top: 150px;
}
.gallery-item-5 {
left: 85%;
opacity: .4;
transform: translateX(-48%);
margin-top: 150px;
}
.gallery-controls {
display: flex;
justify-content: center;
margin: 30px 0;
}
.gallery-controls button {
background-color: transparent;
border: 0;
cursor: pointer;
font-size: 16px;
margin: 0 20px;
padding: 0 12px;
text-transform: capitalize;
}
.gallery-controls-next{
position: absolute!important;
right: 8%;
top: 58%;
}
.gallery-controls-previous {
position: absolute!important;
left: 8%;
top: 58%;
}
.gallery-controls button:focus {
outline: none;
}
.gallery-controls-previous {
position: relative;
}
.gallery-controls-previous::before {
border: solid #ffc20e;
border-width: 0 2px 2px 0;
content: '';
display: inline-block;
height: 15px;
left: -10px;
padding: 2px;
position: absolute;
top: 0;
transform: rotate(135deg) translateY(-50%);
transition: left 0.15s ease-in-out;
width: 15px;
}
.gallery-controls-previous:hover::before {
left: -18px;
}
.gallery-controls-next {
position: relative;
}
.gallery-controls-next::before {
border: solid #ffc20e;
border-width: 0 2px 2px 0;
content: '';
display: inline-block;
height: 15px;
padding: 2px;
position: absolute;
right: -10px;
top: 50%;
transform: rotate(-45deg) translateY(-50%);
transition: right 0.15s ease-in-out;
width: 15px;
}
.gallery-controls-next:hover::before {
right: -18px;
}
.gallery-nav {
bottom: -15px;
display: flex;
justify-content: center;
list-style: none;
padding: 0;
position: absolute;
width: 100%;
}
.gallery-nav li {
background: #ccc;
border-radius: 50%;
height: 10px;
margin: 0 16px;
width: 10px;
}
.gallery-nav li.gallery-item-selected {
background: #555;
}
<div class="container">
<div class="row">
<div class="col-md-12 col-sm-6">
<div class="gallery">
<div class="testimonial-bg"></div>
<div class="gallery-container">
<img class="gallery-item gallery-item-1" src="images/events/guest.jpg" data-index="1">
<img class="gallery-item gallery-item-2" src="images/events/guest.jpg" data-index="2">
<img class="gallery-item gallery-item-3" src="images/events/guest.jpg" data-index="3">
<img class="gallery-item gallery-item-4" src="images/events/guest.jpg" data-index="4">
<img class="gallery-item gallery-item-5" src="images/events/guest.jpg" data-index="5">
</div>
<div class="gallery-controls"></div>
</div>
</div>
</div>
</div>
]1

See the below code, I have added auto slide functionality with interval time 5 seconds.
If you want to change the interval, Please update the setInterval time in the "constructor" and "setCurrentState" functions.
<script>
const galleryContainer = document.querySelector('.gallery-container');
const galleryControlsContainer = document.querySelector('.gallery-controls');
const galleryControls = ['previous', 'add', 'next'];
const galleryItems = document.querySelectorAll('.gallery-item');
class Carousel {
constructor(container, items, controls) {
this.carouselContainer = container;
this.carouselControls = controls;
this.carouselArray = [...items];
this.mySlideInterval = null;
this.mySlideInterval = setInterval(
this.autoSlide.bind(this),
5000
);
}
autoSlide() {
this.carouselArray.push(this.carouselArray.shift());
this.updateGallery();
}
updateGallery() {
this.carouselArray.forEach(el => {
el.classList.remove('gallery-item-1');
el.classList.remove('gallery-item-2');
el.classList.remove('gallery-item-3');
el.classList.remove('gallery-item-4');
el.classList.remove('gallery-item-5');
});
this.carouselArray.slice(0, 5).forEach((el, i) => {
el.classList.add(`gallery-item-${i+1}`);
});
}
setCurrentState(direction) {
if (direction.className == 'gallery-controls-previous') {
this.carouselArray.unshift(this.carouselArray.pop());
} else {
this.carouselArray.push(this.carouselArray.shift());
}
clearInterval(this.mySlideInterval);
this.updateGallery();
this.mySlideInterval = setInterval(
this.autoSlide.bind(this),
5000
);
}
setControls() {
this.carouselControls.forEach(control => {
galleryControlsContainer.appendChild(document.createElement('button')).className = `gallery-controls-${control}`;
document.querySelector(`.gallery-controls-${control}`).innerText = control;
});
}
useControls() {
const triggers = [...galleryControlsContainer.childNodes];
triggers.forEach(control => {
control.addEventListener('click', e => {
e.preventDefault();
if (control.className == 'gallery-controls-add') {
const newItem = document.createElement('img');
const latestItem = this.carouselArray.length;
const latestIndex = this.carouselArray.findIndex(item => item.getAttribute('data-index') == this.carouselArray.length)+1;
Object.assign(newItem,{
className: 'gallery-item',
src: `#{this.carouselArray.length+1}`
});
newItem.setAttribute('data-index', this.carouselArray.length+1);
this.carouselArray.splice(latestIndex, 0, newItem);
document.querySelector(`[data-index="${latestItem}"]`).after(newItem);
this.updateGallery();
} else {
this.setCurrentState(control);
}
});
});
}
}
const exampleCarousel = new Carousel(galleryContainer, galleryItems, galleryControls);
exampleCarousel.setControls();
// exampleCarousel.setNav();
exampleCarousel.useControls();
</script>

Related

In Html how to activate a close button with an iFrame that plays video?

In my previous question I asked about how to play video in an iFrame, and got an answer : How to click from a video link and let it play in an area below?
But now I'm facing another problem, I have an iFrame and a close [ x ] button [ inspired by : http://jsfiddle.net/EFbzY/1/ ], yet I can't figure out how to activate that close button to close the iFrame, the html and script code at the end of my site looks like this, it's used to control the iFrame :
<div id="modal" tabindex="-1">
<button type="button" data-dismiss="modal" class="close" title="close">×</button>
<div class="content">
<h4 class="title"></h4>
<iframe class="yt-video" src="https://www.youtube.com/embed/A1nRiiWYgZw" frameborder="0" allow="autoplay; encrypted-media" allowfullscreen></iframe>
</div>
<div id="fade" class="black_overlay" onclick="closeLightBox()" style="display: block;">
<div style=" z-index: 0; left: 76%; top: 17%; width: 22px; position: absolute;">
<h2>×</h2>
</div>
</div>
</div>
<script>
var modal = document.getElementById('modal'),
closeBtn = modal.querySelector('close'),
ytVideo = modal.querySelector('.content .yt-video'),
title = modal.querySelector('.content .title'),
anchors = document.querySelectorAll('a[data-target="modal"]'),
l = anchors.length;
for (var i = 0; i < l; i++)
{
anchors[i].addEventListener("click", function(e)
{
e.preventDefault();
title.textContent = this.dataset.videoTitle || 'No title';
ytVideo.src = this.href;
modal.classList.toggle('is-visible');
modal.focus();
});
}
modal.addEventListener("keydown", function(e)
{
if (e.keyCode == 27)
{
title.textContent = '';
ytVideo.src = '';
this.classList.toggle('is-visible');
}
});
closeBtn.addEventListener("click", function(e)
{
e.preventDefault();
title.textContent = '';
ytVideo.src = '';
modal.classList.toggle('is-visible');
});
</script>
The style code [ at the top of the page ] looks like this :
#modal {
display: none;
position: fixed;
width: 100vw;
height: 100vh;
max-height: 100vh;
top: 0;
left: 0;
background: rgba(24, 24, 24, .6);
z-index: 999;
}
#modal .content {
width: 55%;
height: 65vh;
margin: auto; /* allows horyzontal and vertical alignment as .content is in flex container */
}
#modal .content .yt-video {
display: block;
width: 100%;
height: calc(100% - 45px);
}
#modal .content .title {
box-sizing: border-box;
height: 45px;
line-height: 23px;
padding: 12px 4px;
margin: 0;
background: #007bff;
max-width: 100%;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
#modal .close {
position: absolute;
top: 0;
right: 0;
width: 35px;
height: 35px;
line-height: 35px;
text-align: center;
border: 0;
font-weight: bold;
font-size: 24px;
color: #fff;
background: #666;
cursor: pointer;
transition: background .4s;
}
#modal .close:hover, #modal .close:active {
background: #ef3658;
}
#modal.is-visible {
display: flex;
}
The test site is live at : http://gatecybertech.com/test
At the upper right of the site, click on the "Videos" link will take you to the section, after you click on a video, an iFrame opens and plays the video with a [x] button on the top right corner, but it's not activated, how to fix it so it an close the iFrame and video ?
OK, after some research and experiment, I finally got it. It's running at : http://gatecybertech.com/test later will be moved to the main site : http://gatecybertech.com
[1] Style looks like this :
#modal {
display: none;
position: fixed;
width: 100vw;
height: 100vh;
max-height: 100vh;
top: 0;
left: 0;
background: rgba(24, 24, 24, .6);
z-index: 999;
}
#modal .content {
width: 55%;
height: 65vh;
margin: auto; /* allows horyzontal and vertical alignment as .content is in flex container */
}
#modal .content .yt-video {
display: block;
width: 100%;
height: calc(100% - 45px);
}
#modal .content .title {
box-sizing: border-box;
height: 45px;
line-height: 23px;
padding: 12px 4px;
margin: 0;
background: #007bff;
color: #fff;
text-align: center;
font-size: 26px;
max-width: 100%;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
#modal .close {
position: absolute;
top: 0;
right: 0;
width: 58px;
height: 58px;
line-height: 35px;
text-align: center;
border: 0;
font-weight: bold;
font-size: 26px;
color: #fff;
background: #366;
cursor: pointer;
transition: background .2s;
}
#modal .close:hover, #modal .close:active {
background: #ef3658;
}
#modal.is-visible {
display: flex;
}
[2] Html looks like this :
<div class="tools-icon">
<img src=https://i.ytimg.com/vi/IgBIaZgoAQc/hqdefault.jpg?sqp=-oaymwEXCPYBEIoBSFryq4qpAwkIARUAAIhCGAE=&rs=AOn4CLDW3KcjXsTR5utmlvhFfibLe-bvRg width=170 height=110>
<p class="tools-icon__text">Keypad Pins Easily Stolen</p>
</div>
...
<!-- the modal div that will open when an anchor link is clicked to show the related video in an iframe. -->
<div id="modal" tabindex="-1">
<div class="content">
<h4 class="title"></h4>
<iframe class="yt-video" src="https://www.youtube.com/embed/A1nRiiWYgZw" frameborder="0" allow="autoplay; encrypted-media" allowfullscreen></iframe>
</div>
<div class="black_overlay" onclick="closeLightBox()" style="display: block;">
<div style=" z-index: 0; left: 76%; top: 17%; width: 22px; position: absolute;">
<a class="close" onclick = "return close_iFrame();"><h2>×</h2></a>
</div>
</div>
</div>
[3] Script looks like this :
<script>
var modal = document.getElementById('modal'),
closeBtn = modal.querySelector('close'),
ytVideo = modal.querySelector('.content .yt-video'),
title = modal.querySelector('.content .title'),
anchors = document.querySelectorAll('a[data-target="modal"]'),
l = anchors.length;
for (var i = 0; i < l; i++)
{
anchors[i].addEventListener("click", function(e)
{
e.preventDefault();
title.textContent = this.dataset.videoTitle || 'No title';
ytVideo.src = this.href;
modal.classList.toggle('is-visible');
modal.focus();
});
}
modal.addEventListener("keydown", function(e)
{
if (e.keyCode == 27)
{
title.textContent = '';
ytVideo.src = '';
this.classList.toggle('is-visible');
}
});
</script>
<script language="javascript" type="text/javascript">
function close_iFrame()
{
var modal = document.getElementById('modal'),
ytVideo = modal.querySelector('.content .yt-video');
ytVideo.src = '';
modal.classList.toggle('is-visible');
}
</script>

Arrange 2 divs diagonally inside a parent div

I'm trying to arrange 2 divs inside a parent div so that is looks like the parent div is being divided into 2 parts diagonally. The diagram below will show what is required
This is the code i have tried.
App.js
import React, { Component } from "react";
import "./App.css";
class InnerMainDiv extends Component {
constructor() {
super();
this.section = React.createRef();
}
componentDidMount() {
this.handleResize();
window.addEventListener("resize", this.handleResize);
}
componentWillUnmount() {
window.addEventListener("resize", null);
}
handleResize = (WindowSize, event) => {
let h = this.section.current.clientHeight;
let w = this.section.current.clientWidth;
let angle = Math.atan(h / w) * 57.29577;
let rotateProperty = "rotate(" + angle + "deg)";
this.section.current.style.webkitTransform = rotateProperty;
this.section.current.style.transform = rotateProperty;
this.section.current.style.mozTransform = rotateProperty;
};
render() {
return (
<div className="maindiv">
<section ref={this.section}>
<div href="#1" />
</section>
<section ref={this.section}>
<div href="#2" />
</section>
</div>
);
}
}
export default InnerMainDiv;
App.css
html,
body,
div {
height: 100%;
width: 100%;
padding: 0;
margin: 0;
}
div {
overflow: hidden;
position: relative;
}
section {
position: absolute;
top: -100%;
height: 5000vw;
width: 5000vh;
background: #ccc;
-webkit-transform-origin: 0 0;
-moz-transform-origin: 0 0;
transform-origin: 0 0;
}
section + section {
background: #666;
top: 0%;
}
section div {
display: block;
width: 100%;
height: 100%;
cursor: pointer;
}
Any ideas or suggestions on how to achieve this?.
You can use clip-path to achieve this:
.container {
width: 200px;
height: 200px;
position: relative;
}
.container > * {
height: 100%;
background: red;
}
.container :last-child {
position: absolute;
top: 0;
left: 0;
width: 100%;
background: blue;
-webkit-clip-path: polygon(0 0, 100% 0%, 100% 100%);
clip-path: polygon(0 0, 100% 0%, 100% 100%);
}
<div class="container">
<div></div>
<div></div>
</div>
But in case you want more browser support you can use rotation like this:
.container {
width: 200px;
height: 200px;
position: relative;
overflow:hidden;
}
.container > * {
height: 100%;
background: red;
}
.container :last-child {
position: absolute;
top: 0;
left: 0;
width: 141%; /* = 1.41 * 100% --> 1.41 = sqrt(2) */
height: 141%;
background: blue;
transform-origin:top left;
transform:rotate(-45deg);
}
<div class="container">
<div></div>
<div></div>
</div>

Embedded video height issue in Safari browser

I have two horizontally aligned responsive divs that are set to be the same height.
The left holds an embedded youtube video, the right a fixed image.
Tested in Chrome there are no issues, but if tested in Safari the youtube video is not filling the full height of the div.
html markup is:
<div id="IndexBanners">
<div class="indexbannerimages effect first">
<div id="player"></div>
<script src="https://www.youtube.com/player_api"></script>
<script>
// create youtube player
var player;
function onYouTubePlayerAPIReady() {
player = new YT.Player('player', {
videoId: 'GfaiXgY114U',
autoplay: '0',
controls: '0',
width: '100%',
height: '100%',
playerVars: {
rel: 0,
showinfo: 0
},
events: {
'onReady': onPlayerReady,
'onStateChange': onPlayerStateChange
}
});
}
// autoplay video
function onPlayerReady(event) {
// event.target.playVideo();
}
// change mask opacity depending on player state
function onPlayerStateChange(event) {
if (event.data === -1) {
document.getElementById("mask1").setAttribute("style", "opacity:1; -moz-opacity:1; filter:alpha(opacity=100)");
}
if (event.data === 0) {
document.getElementById("mask1").setAttribute("style", "opacity:1; -moz-opacity:1; filter:alpha(opacity=100)");
}
if (event.data === 1) {
document.getElementById("mask1").setAttribute("style", "opacity:0; -moz-opacity:0; filter:alpha(opacity=0)");
}
if (event.data === 2) {
document.getElementById("mask1").setAttribute("style", "opacity:1; -moz-opacity:1; filter:alpha(opacity=100)");
}
}
</script>
<div id="mask1">
<div class="watchText">Watch The Video</div>
<div class="watch"></div>
</div>
</div>
<div class="indexbannerimages effect">
<img src="https://placehold.it/795x436">
<div id="mask2">
<div class="newsText">Latest News</div>
<div class="news"></div>
</div>
</div>
</div>
css:
#IndexBanners {
display: flex;
margin-top: 20px;
}
.indexbannerimages {
flex: 1 0 0;
position: relative;
}
img {
max-width: 100%;
height: auto;
vertical-align: top;
}
.indexbannerimages .watch {
background: url(../images/play-icon.png) no-repeat scroll 0% 25% / 14px auto;
}
.indexbannerimages .news {
background: url(../images/news-icon.png) no-repeat scroll 0% 25% / 14px auto;
}
.watchText {
color: #fff;
text-transform: uppercase;
padding-top: 23%;
margin: 0;
}
.newsText {
color: #fff;
text-transform: uppercase;
padding-top: 23%;
margin: 0;
}
.effect #mask1,
.effect #mask2 {
text-align: center;
font-size: 16px;
color: #fff;
background-color: rgba(00, 00, 00, 0.8);
opacity: 0.75;
transition: all 0.5s ease-in-out;
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
cursor: pointer;
}
.effect:hover #mask1,
.effect:hover #mask2 {
visibility: hidden;
opacity: 0.0;
transition: all 0.5s ease-in-out;
}
#media (max-width:600px) {
#IndexBanners {
display: block;
}
.first {
position: relative;
padding-bottom: 56.25%;
height: 0;
}
.first iframe {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
}
}
I've set up a fiddle here to demonstrate the issue. https://jsfiddle.net/bgaqfvxm/3/
Any suggestions on a fix for this size issue in Safari?
Issue resolved by adding the following to the css
.first iframe {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
}
Thanks to #Michael Coker for the original css that was used in #media query below 600px

Bind the index and ionic card together - ionic

I am doing a project on ionic. It is a quiz type app. I have scrollable div on the top which contains all the question numbers. Below that I have cards where questions are appearing. The screenshot is below :
The cards have swipable feature in it that users can swipe the cards to and fro.
My requirement is when the user selects a particular question from the top question number panel, corresponding questions should show and the selected question should be highlighted. Also when the user swipes the cards, the selection of the question numbers in the top should also change.
I created a circle using css for the above panel and using ng-repeat, I am repeating the question numbers. I added a ng-click option on the question number and passing the index. So that I can show the corresponding question. By using this I am able to bind the both panels in one way. I need to bind it reverse too. So that when user swipes the card, the question number should change.
Also I need to highlight a particular item in ng-repeat to show that that is selected. I tried :hover property in css, it somehow highlighting the selected item but not as good as expected.
Here is my code:
angular.module('quiz', ['ionic'])
.controller('QuizController', function($scope) {
$scope.nodes = [{
count: 1,
disabled: false
}, {
count: 2,
disabled: false
}, {
count: 3,
disabled: false
}, {
count: 4,
disabled: false
}, {
count: 5,
disabled: true
}];
$scope.goToQuestionNumber = function(index) {
console.log('goToQuestionNumber: ', index);
$scope.currentQuestion = index;
$scope.act_type = $scope.quiz.clues[$scope.currentQuestion].act_type;
$scope.isActive = $scope.nodes[index];
changeTemplate();
}
$scope.next = function() {
if ($scope.currentQuestion != ($scope.nodes.length - 1)) {
$scope.currentQuestion++;
$scope.currentTry = 1;
$scope.act_type = $scope.quiz.clues[$scope.currentQuestion].act_type;
$scope.failureResult = false;
changeTemplate();
}
}
$scope.prev = function() {
if ($scope.currentQuestion != 0) {
$scope.additionalActivity = false;
$scope.addtionalQuestionAvailability = false;
console.log('Left swipe');
$scope.currentQuestion = $scope.currentQuestion - 1;
$scope.currentTry = 1;
$scope.act_type = $scope.quiz.clues[$scope.currentQuestion].act_type;
$scope.failureResult = false;
changeTemplate();
}
}
})
.events {
position: relative;
}
.event,
span .event,
.event span {
content: "";
float: left;
position: relative;
padding: 3%;
margin: 0% 2% 0% 2%;
border-radius: 50%;
background-color: lightgrey;
border: 3px solid darkgray;
top: 15%;
left: 2%;
font-size: 15px;
z-index: 1;
text-align: center;
line-height: 150%;
color: hotpink;
}
.slider-column {
position: relative;
display: flex;
flex: 0 0 30%;
}
.slider-column::after {
content: '';
height: 3px;
width: 100%;
background-color: #66a3ff;
position: absolute;
top: 45%;
z-index: -5;
margin-left: 0%;
border-radius: 1% 1% 1% 1%;
padding: 1%;
}
.slider-column:last-child:after {
content: '';
height: 2%;
width: 100%;
background-color: transparent;
position: absolute;
top: 30%;
}
/*.event::after{
content:'';
height:3px;
width:170%;
background-color:#6d6dff;
position: absolute;
top: 45%;
z-index: -5;
margin-left: 55%;
border-radius: 1% 1% 1% 1%;
padding: 1%;
}*/
.event::before {
content: '';
height: 5px;
width: 100%;
background-color: transparent;
position: absolute;
top: 30%;
z-index: -5;
padding-left: 10%;
}
.events:first-child:before {
content: '';
height: 5px;
width: 100%;
background-color: transparent;
position: absolute;
top: 30%;
}
.events:last-child-1:after {
content: '';
height: 5px;
width: 100%;
background-color: transparent;
position: absolute;
top: 30%;
}
.timeline-text {
z-index: 4;
top: 0;
bottom: 5px;
}
.enabled-event {
background: red;
}
.event:hover {
border-color: red;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/ionic/1.3.0/js/ionic.bundle.min.js"></script>
<ion-content ng-app="quiz" ng-controller="QuizController">
<div style="padding-top:10px;padding-left:5px;">
<label class="hamburger" style="float:left">Score:{{totalPoints}} pts</label>
<button style="float:right" class="button button-clear button-small bonus-button" ng-click="bonus()">Try Bonus</button>
</div>
<br>
<br>
<ion-scroll direction="x" class="timeline-scroll">
<div class="timeline">
<div class="events row">
<div class="slider-column" ng-repeat="count in nodes">
<span class="event " ng-click="goToQuestionNumber($index)" ng-if="!count.disabled">
{{count.count}}/{{nodes.length}}
</span>
<span class="event" ng-click="goToQuestionNumber($index)" ng-if="count.disabled">
{{count.count}}/{{nodes.length}}
<!-- </span> -->
</div>
</div>
</div>
</ion-scroll>
<br>
<br>
<div ng-include="currentClueTemplate" ng-swipe-right="prev()" ng-swipe-left="next()" class="question-card"></div>
</ion-content>
Can anyone help me ?

browser add a slash in hash fragment

I have this HTML :
Option 1
When I hover it, I can read http://localhost/#MyHash
And when I click on it, the url in the browser is http://localhost/#/MyHash
Why is this slash added ? Is there a workaround ?
I couldn't figure it out...
Extra :
It's a .NET MVC web solution with AngularJS, I don't know if this is relevant
I saw some topic about googlebot / SEO (URL fragments: a leading slash in your hash url - good or bad?) : I don't care about it, this is not for a public website.
Edit :
See it in JSFiddle : https://jsfiddle.net/y2nLaxh5/embedded/result/
Hover the green part an look on options proposed
(as it is in an iframe you should open in a new tab)
Edit2 :
(function () {
var app = angular.module("myApp", []);
app.controller("MenuController", ['$scope', function($scope) {
$scope.items = [
{
name: "Option 1",
url: 'MyUrl'
},
{
name: "Option 2",
url: 'MyUrl',
items: [
{
name: "SubOption 2-1"
}
]
}
];
function preprocessItems(items, depth) {
depth = typeof(depth) === "undefined" ? 0 : depth;
for (var i in items) {
items[i].depth = depth;
preprocessItems(items[i].items, depth + 1);
}
}
preprocessItems($scope.items);
}]);
})();
body {
font-size: .85em;
font-family: "Segoe UI", Verdana, Helvetica, Sans-Serif;
color: #CCC;
background-color: #333;
}
#background
{
position: fixed;
top: 15%;
bottom: 15%;
left: 15%;
right: 15%;
}
#LeftMenu
{
height: 100%;
position: fixed;
left: 0;
top: 0;
width: 0;
}
#LeftMenu > .MenuContent
{
position: absolute;
width: 0;
height: 100%;
z-index:1;
}
#LeftMenu > .MenuContent > .MenuSlider
{
background-color: #000;
left: -200px;
position: relative;
width: 200px;
height: 100%;
padding: 10px 20px;
box-sizing: border-box;
transition: left 0.3s ease-out;
}
#LeftMenu:hover > .MenuContent > .MenuSlider
{
left: 0;
}
.MenuSlider h3
{
margin: 0 0 10px 0;
text-align: center;
}
.MainIcon
{
display: block;
text-decoration: none;
padding: 10px;
border-radius: 0 0 5px 0;
background-color: #1fa67a;
width: 200px;
height: auto;
box-sizing: border-box;
font-family: 'Nixie One';
font-size: 2em;
font-weight: bold;
color: #FFF;
}
.MainIcon > p
{
margin: 0;
}
.Activator
{
position: absolute;
right: 0;
top: 0;
height: 100%;
}
.ActivatorCirle
{
position: absolute;
height: 400px;
top: -200px;
width: 400px;
left: -200px;
border-radius: 100%;
}
.ActivatorColumn
{
position: absolute;
height: 100%;
top: 0;
width: 30px;
left: 0;
}
.menuItem.dpt0 { font-size: 1.2em; }
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<script type="text/ng-template" id="menuItem_renderer.html">
{{item.name}}
<div ng-if="item.items">
<div ng-repeat="item in item.items" ng-include="'menuItem_renderer.html'"></div>
</div>
</script>
<body ng-app="myApp">
<div id="background"></div>
<div id="LeftMenu" ng-controller="MenuController as menu">
<div class="Activator">
<div class="ActivatorCirle"></div>
<div class="ActivatorColumn"></div>
</div>
<div class="MenuContent">
<a class="MainIcon" href="/">
<p>Media<br />Content<br />Supervisor</p>
</a>
<div class="MenuSlider">
<h3>MENU</h3>
<div ng-repeat="item in items" ng-include="'menuItem_renderer.html'"></div>
</div>
</div>
</div>
</body>