JQuery transition jittering in Chrome - javascript

The code below works in Firefox, but having problem when executing in Chrome.
The idea is simple; after click change the 'max-height' property and show the rest of the text. Height is computed for each element itself and transition is executed via jQuery's .transition(). JS does it's work, but transition is represented poorly. It looks little better if I reduce the transition time, but still very far from expected.
Any ideas on how to fix representation in Chrome?
$(function() {
var Readmore = function(el) {
this.el = el || {};
var descriptionElement = this.el.find('#predmetDesc');
var chevronElement = this.el.find('#showMore');
var links = descriptionElement.add(chevronElement);
links.on('click', this.sloppy);
};
Readmore.prototype.sloppy = function() {
$this = $(this).parents().eq(1).find('#paragraph');
$sibling = $this.siblings('#showMore');
var expanded = $this.is('.expanded');
if (expanded) {
$this.transition({ 'max-height': '96px',
overflow: 'hidden'
}, 500, 'in', function() {
$this.removeClass("expanded");
});
$sibling.transition({
'rotate': '0deg'
}, 500, 'in', function() {
$sibling.removeClass("expanded");
});
} else {
$this.transition({
'max-height': $this.get(0).scrollHeight,
overflow: ''
}, 500, 'out', function() {
$this.addClass("expanded");
});
$sibling.transition({
'rotate': '180deg'
}, 500, 'out', function() {
$sibling.addClass("expanded");
});
}
};
var readMore = new Readmore($('.sviPredmetiCol'), false);
});
.paragraph {
display: inline-block;
max-height: 96px;
overflow: hidden;
padding-top: 23px;
margin-bottom: -4px;
}
div.paragraph > p {
text-decoration: none !important;
cursor: pointer;
}
p {
margin: 0;
}
#predmetDesc {
position: relative;
/*max-height: 97px; !*72px*!*/
}
#showMore {
position: relative;
display: block;
text-align: center;
line-height: 1;
cursor: pointer;
margin-bottom: -8px;
}
.fa-chevron-down::before {
position: relative;
cursor: pointer;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="row sviPredmetiRow">
<div id="sviPredmetiId" class="col-xs-12 col-md-12 sviPredmetiCol">
<div id="parentAbs" class="panel panel-primary sviPredmetiPanel">
<div class="panel-heading">
<div class="panelMainTitle">courseName</div>
</div>
<div class="panel-body">
<div class="widget">
<div class="statEcts">
<div class="ects">
<span class="count">courseInfo</span>
<span class="desc">ECTS</span>
</div>
</div>
<div class="statCourse">
<div class="courseId">
<span class="count">courseID</span>
<span class="desc">ID predmeta</span>
</div>
</div>
</div>
<div id="paragraph" class="paragraph">
<p id="predmetDesc">Course description</p>
</div>
<!--/div .paragraph-->
<div id="showMore"><i class="fa fa-chevron-down"></i>
</div>
</div>
<!--/div .panel-body-->
</div>
<!--/div .sviPredmetiPanel-->
</div>
<!--/div .sviPredmetiCol-->
</div>
<!--/div sviPredmetiRow-->

Related

Simple text slider in jQuery

I need help to do a simple text slider in jQuery or JavaScript.
I need a slider with animation so that the text moves from right to left.
Within my code I have also pagination, where I need highlight which text is active.
This is all of what I have, I need to be very simple.
All answers on the internet are so complicated.
Can someone help me?
.active{
color:red;
}
<div class="buttons">
<button name="prev">Prev</button>
<button name="next">Next</button>
</div>
<div class="content">
<div class="slide">
<p>content od slide</p>
</div>
<div class="slide">
<p>content od slide</p>
</div>
<div class="slide">
<p>content od slide</p>
</div>
</div>
<div class="paginator">
<div class="pagin-tracker">1</div>
<div class="pagin-tracker active">1</div>
<div class="pagin-tracker">1</div>
</div>
You can try this one.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Document</title>
<style>
.slider {
}
.slider__wrap {
overflow: hidden;
}
.slide {
width: 100%;
display: inline-block;
text-align: center;
}
.content {
will-change: transform;
white-space: nowrap;
transition: transform 0.3s;
}
</style>
</head>
<body>
<div id="slider" class="slider">
<div class="buttons">
<button name="prev">Prev</button>
<button name="next">Next</button>
</div>
<div class="slider__wrap">
<div class="content" style="transform: translate(-100%);" data-active="1"> <!-- if you need to set initial position to the second slider, or you can use translate(0) to set it to the first slide -->
<div class="slide">
<p>content od slide 1</p>
</div>
<div class="slide">
<p>content od slide 2</p>
</div>
<div class="slide">
<p>content od slide 3</p>
</div>
</div>
</div>
<div class="paginator">
<div class="pagin-tracker">1</div>
<div class="pagin-tracker active">1</div>
<div class="pagin-tracker">1</div>
</div>
</div>
<script>
const slider = document.getElementById('slider');
const sliderWrap = slider.querySelector('.slider__wrap');
const sliderContent = sliderWrap.querySelector('.content');
const sliderButtons = slider.querySelector('.buttons');
const buttonPrev = sliderButtons.querySelector('button[name="prev"]');
const buttonNext = sliderButtons.querySelector('button[name="next"]');
const pages = Array.from(slider.querySelectorAll('.pagin-tracker'));
const pagesCount = pages.length;
const slidesCount = sliderContent.querySelectorAll('.slide').length;
let activeIndex = sliderContent.getAttribute('data-active');
const updatePaginator = () => {
for (let i = 0; i < pagesCount; i++) {
pages[i].classList.remove('active');
}
if (pages[activeIndex]) {
pages[activeIndex].classList.add('active');
}
};
const applyStyle = () => {
sliderContent.setAttribute('data-active', activeIndex);
sliderContent.style.cssText = `transform: translate(-${activeIndex * 100}%);`;
updatePaginator();
};
buttonPrev.addEventListener('click', () => {
if (activeIndex > 0) {
activeIndex--;
applyStyle();
}
}, false);
buttonNext.addEventListener('click', () => {
if (activeIndex < slidesCount - 1) {
activeIndex++;
applyStyle();
}
}, false);
</script>
</body>
</html>
You can use something like this and extend as per you requirement.
https://codepen.io/anon/pen/MqRpKg
HTML
<div class="slide-wrap">
<div class="slide-mask">
<ul class="slide-group">
<li class="slide">this</li>
<li class="slide">is</li>
<li class="slide">a</li>
<li class="slide">simple</li>
<li class="slide">slider</li>
</ul>
</div>
<div class="slider-nav">
<ul></ul>
</div>
</div>
JQuery:
var $slide = $('.slide'),
$slideGroup = $('.slide-group'),
$bullet = $('.bullet')
var slidesTotal = ($slide.length - 1),
current = 0,
isAutoSliding = true;
$bullet.first().addClass('current');
var clickSlide = function() {
//stop auto sliding
window.clearInterval(autoSlide);
isAutoSliding = false;
var slideIndex = $bullet.index($(this));
updateIndex(slideIndex);
};
var updateIndex = function(currentSlide) {
if(isAutoSliding) {
if(current === slidesTotal) {
current = 0;
} else {
current++;
}
} else {
current = currentSlide;
}
$bullet.removeClass('current');
$bullet.eq(current).addClass('current');
transition(current);
};
var transition = function(slidePosition) {
var slidePositionNew = (slidePosition ) * 500;
$slideGroup.animate({
'left': '-' + slidePositionNew + 'px'
});
};
var autoSlide = window.setInterval(updateIndex, 2000);
$( "li.slide" ).each(function( index ) {
$('.slider-nav').append('<span class="bullet">'+index+'</span>');
});
var $bullet = $('.bullet');
$bullet.on( 'click', clickSlide);
CSS
body {
background: rgb(191, 76, 76);
}
/* slider
----------------------*/
.slide-wrap {
margin: 5% auto 0;
width: 540px;
}
.slide-mask {
position: relative;
overflow: hidden;
height: 100px;
}
.slide-group {
position: absolute;
top: 0px;
left: 0;
}
.slide {
display:inline-block;
height: 100px;
width:500px;
font: 100 90px/135px "lato";
font-size: 2em;
color: #fff;
text-align: center;
text-transform: uppercase;
}
/* nav
----------------------*/
.slide-nav {
text-align: center;
border: 1px solid red;
height: 30px;
color: red;
}
.slide-nav ul {
margin: 0;
padding: 0;
}
.slide-nav li {
border: 1px solid red;
width: 100px;
cursor: pointer;
color: red;
}
.slide-nav li.current {
background: rgb(144, 39, 39);
}
.slider-nav {
width: 300px;
text-alignt: center;
margin-left:40%;
}
span.bullet {
display:inline-block;
width: 30px;
cursor: pointer;
}

animation text function callback jquery

I have problem here http://test10.bitballoon.com/
I have animation (show/hide) text.first text has class "active". the animation show this text then remove class "active" and add this class to the next text and callback the function again.. the function also check if the last text has class "active" then remove and add class "active" to the first text and hide all text and callback again. this how it work. the first time work fine when the animation finished callback again and animate the first text good then the function add "active" to multiple text then all text and function break. i don't know why this happen i tried to use setInterval but the same problem
function animateText() {
"use strict";
if ($(".text-container .active").hasClass("left")) {
$(".text-container .active").addClass("active");
$(".text-container .active").delay(1000).animate({
marginLeft: 0,
opacity: 1
}, 700, function() {
if ($(".text-container .text:last").hasClass("active")) {
$(".text-container .text:last").removeClass("active")
$(".text-container .text").animate({
opacity: 0
}, 700, function() {
$(".text-container .text:first").addClass("active");
animateText();
})
}
$(".text-container .active").removeClass("active").next().addClass("active");
animateText();
});
} else if ($(".text-container .active").hasClass("right")) {
$(".text-container .active").addClass("active");
$(".text-container .active").delay(1000).animate({
marginRight: "5px",
opacity: 1
}, 700, function() {
if ($(".text-container .text:last").hasClass("active")) {
$(".text-container .text:last").removeClass("active")
$(".text-container .text").animate({
opacity: 0
}, 700, function() {
$(".text-container .text:first").addClass("active");
animateText();
})
}
$(".text-container .active").removeClass("active").next().addClass("active");
animateText();
});
}
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="text-container">
<div class="text left active">
<p>Hello World</p>
</div>
<div class="text left">
<p>Hello World2</p>
</div>
<div class="text right">
<p>Hello World3</p>
</div>
<div class="text right">
<p>Hello World4</p>
</div>
<div class="text left">
<p>Hello World5</p>
</div>
<div class="text right">
<p>Hello World6</p>
</div>
</div>
As long as this animation is concerned, there is no use for class .active. Note I added some css to accommodate it in the snippet, so let me know if it helps.
$(document).ready(function() {
animateText($(".text-container .active"));
});
function animateText($this) {
var leftParams = {'left': 0, opacity: 1};
var rightParams = {'right': 0, opacity: 1};
$this.stop(true).animate(
($this.hasClass('left') ? leftParams : rightParams),
1000, function() {
if ($this.next().presence())
animateText($this.next());
else
startOver();
}
);
}
function startOver() {
var selector = $(".text-container .text");
var next = $(".text-container > .active");
selector.animate({
opacity: 0
}, 200, function() {
selector.filter('.left').css('left', -200);
selector.filter('.right').css('right', -200);
animateText(next);
});
}
$.fn.presence = function() {
return this.length !== 0 && this;
};
.text-container {
display: inline-block;
width: 260.4px;
height: 419px;
padding-top: 10px;
padding-left: 5px;
overflow: hidden;
}
.text-container .text {
max-width: 225px;
float: left;
padding: 8px 9px;
margin-bottom: 6px;
border-radius: 20px;
text-align: left;
background-color: rgba(224,230,237,.5);
clear: both;
opacity: 0;
position: relative;
}
.text-container .left {
float: left;
left: -200px;
}
.text-container .right {
float: right;
right: -200px;
background-color: #1bb45e;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="text-container">
<div class="text left active">
<p>Hello World</p>
</div>
<div class="text left">
<p>Hello World2</p>
</div>
<div class="text right">
<p>Hello World3</p>
</div>
<div class="text right">
<p>Hello World4</p>
</div>
<div class="text left">
<p>Hello World5</p>
</div>
<div class="text right">
<p>Hello World6</p>
</div>
</div>

Pause jQuery On Hover

I just want the ability to be able to pause the animation on mouse hover. I trying to looking good way to do that, but there was some issues. I tested some hover/stop functions, but I can't get these working correctly.
jQuery(document).ready(function() {
setInterval(function() {
jQuery('#testimonials .slide').filter(':visible').fadeOut(1000, function() {
if (jQuery(this).next('.slide').size()) {
jQuery(this).next().fadeIn(1000);
} else {
jQuery('#testimonials .slide').eq(0).fadeIn(1000);
}
});
}, 5000);
});
#quote {
width: 100%;
height: 130px;
background-position: center bottom;
background-repeat: no-repeat;
margin-bottom: 65px;
overflow: hidden;
}
#testimonials .slide {
color: #555555;
}
#testimonials .testimonial-quote {
display: inline;
width: 600px;
height: 170px;
margin: 0;
padding: 0;
float: left;
position: relative;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="quote">
<div id="testimonials">
<div class="slide">
<div class="testimonial-quote">
<p>Text 1</p>
<h4 class="title">Title 1</h4>
</div>
</div>
</div>
</div>
You can achieve this by calling clearInterval() when the slide is hovered, then re-creating the interval again when the mouse leaves the slide, something like this:
jQuery(document).ready(function($) {
var $slides = $('#testimonials .slide');
function beginSlideInterval() {
return setInterval(function() {
$slides.filter(':visible').fadeOut(1000, function() {
var $next = $(this).next().length ? $(this).next() : $slides.first();
$next.fadeIn(1000);
});
}, 3000);
}
var slideInterval = beginSlideInterval();
$slides.on('mouseenter', function() {
clearInterval(slideInterval);
}).on('mouseleave', function() {
slideInterval = beginSlideInterval();
});
});
#quote {
width: 100%;
height: 130px;
background-position: center bottom;
background-repeat: no-repeat;
margin-bottom: 65px;
overflow: hidden;
}
#testimonials .slide {
color: #555555;
}
#testimonials .testimonial-quote {
display: inline;
width: 600px;
height: 170px;
margin: 0;
padding: 0;
float: left;
position: relative;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="quote">
<div id="testimonials">
<div class="slide">
<div class="testimonial-quote">
<p>Text 1</p>
<h4 class="title">Title 1</h4>
</div>
</div>
</div>
</div>
Note that I shortened the interval to make the effect more obvious.

Javascript Clicks, Taps and Hovers

What I'm trying to achieve is:
On desktop: 1) Hover to bring up overlay 2) Click to activate
On touch: 1) Tap to bring up overlay 2) Tap again to activate
What I've come up with so far is the below. However when using a touch device it fires the both touchend event and then the click event, this causes the overlay click event to be fired unnecessarily. What's the best way around this, if any?
$(".container > .item").on("mouseenter mouseleave", function(e) {
$(this).toggleClass("hover");
console.log("hover: " + e.type);
});
$(".container > .item > .overlay").on("mouseup touchend", function(e) {
console.log("click: " + e.type);
})
.item {
width: 200px;
height: 200px;
background: red;
display: inline-block;
position: relative;
}
.item.hover > .overlay {
display: block;
}
.overlay {
display: none;
position: aboslute;
top: 0;
left: 0;
height: 100%;
width: 100%;
background: green;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="container">
<div class="item">
<div class="overlay">
</div>
</div>
</div>
I came up with the below, which works rather nicely -- And when changing between touch/pen and mouse.
In effect, for mouse navigation, mouseover 'wakes up' the element, and readies the listeners, then click gets handled by the listeners. For touch navigation, the first tap 'wakes up' the element, and the second tap gets handled by the listeners.
var hoverCapture = (function() {
var TOUCH_STATE = {
'initial': 0,
'over': 1,
'click': 2
};
var eventTargetDefault = '.hover-layer';
function hoverCapture(selectorScope, eventTarget) {
var eventTarget = typeof eventTarget !== 'undefined' ? eventTarget : eventTargetDefault;
var $eventTarget = $(selectorScope).find(eventTarget);
var touchState = TOUCH_STATE.initial;
var previousEventType = '';
$eventTarget.on('mouseenter', function(e) {
$(this).addClass("hover");
previousEventType = e.type;
});
$eventTarget.on('mouseleave', function(e) {
$(this).removeClass("hover");
// Order of events is:
//
// outside -> .image
// touchend, mousenter
//
// .image -> .image
// touchend, mouseleave, mouseenter
//
// .image -> outside
// mouseleave
//
// When tapping out, we don't receive a touchend
// event, since the touchend happens outside of
// our scoped listeners
if (previousEventType === 'touchend') {
touchState = TOUCH_STATE.over;
} else {
touchState = TOUCH_STATE.initial;
}
previousEventType = e.type;
});
$eventTarget.on('touchend', function(e) {
if (touchState === TOUCH_STATE.initial) {
touchState = TOUCH_STATE.over;
} else {
touchState = TOUCH_STATE.click;
}
previousEventType = e.type;
});
$eventTarget.each(function() {
this.addEventListener("click", function(e){
if (touchState === TOUCH_STATE.over) {
e.stopPropagation();
}
previousEventType = e.type;
}, true);
});
}
return hoverCapture;
}());
hoverCapture("#gallery1", ".image");
hoverCapture("#gallery2", ".image");
$(".test").on("click", function(e) {
alert("Ouch!");
});
.gallery {
margin: 5px;
}
.image {
width: 100px;
height: 100px;
background: grey;
margin: 0 -4px -4px 0;
display: inline-block;
}
.image .overlay {
height: 100%;
width: 100%;
background: red;
display: none;
position: relative;
}
.image.hover .overlay {
display: block;
}
.test {
width: 25%;
height: 25%;
position: absolute;
right: 0;
background: purple;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="gallery" id="gallery1">
<div class="image">
<div class="overlay">
<div class="test"></div>
</div>
</div>
<div class="image">
<div class="overlay">
</div>
</div>
<div class="image">
<div class="overlay">
</div>
</div>
<div class="image">
<div class="overlay">
</div>
</div>
</div>
<div class="gallery" id="gallery2">
<div class="image">
<div class="overlay">
<div class="test">
</div>
</div>
</div>
<div class="image">
<div class="overlay">
</div>
</div>
<div class="image">
<div class="overlay">
<div class="test">
</div>
</div>
</div>
<div class="image">
<div class="overlay">
</div>
</div>
</div>
If anyone has any additions/suggestions please do follow up.. This has been giving me headaches for days now!

jQuery UI Drag/Droppable animation issue

I'm trying to use jQuery Ui for sorting some Items with Drag and Drop.
If one element passes the dropzone, the dropzone should expand. This works good. But my problem is that the attribute of event.target.clientWidth is still 25. So the dropzone is still 25px, while the container is allready 250px.
I dont know how to change it (i allready tried event.target.clientWidth = 250 but this doesnt work) and hoped you could maybe help me
This is a part of my code:
Html:
<section id="plot" class="plot">
<div class="cards">
<div id="card__container" class="card__container" style="width: 1392px;">
<div class="card__dropzone">
<div class="card__dropzone--inner"></div>
</div>
<div><div class="card ui-widget-content" id="card1">
<span class="card__id">1</span>
<span class="card__text">Hektor runs away followed by police</span>
</div>
</div>
<div class="card__dropzone">
<div class="card__dropzone--inner"></div>
</div>
<div><div class="card ui-widget-content" id="card2">
<span class="card__id">2</span>
<span class="card__text">Hektor stumbles and falls</span>
</div></div>
<div class="card__dropzone">
<div class="card__dropzone--inner"></div>
</div>
<div><div class="card ui-widget-content" id="card3">
<span class="card__id">3</span>
<span class="card__text">Hektor get catched by police and trys to bluff hisself out</span>
</div></div>
<div class="card__dropzone">
<div class="card__dropzone--inner"></div>
</div>
<div><div class="card ui-widget-content" id="card5">
<span class="card__id">5</span>
<span class="card__text">Hektor did say something stupid</span>
</div></div>
<div class="card__dropzone">
<div class="card__dropzone--inner"></div>
</div>
<div><div class="card ui-widget-content" id="card4">
<span class="card__id">4</span>
<span class="card__text">Police a bit confused and believes him</span>
</div></div>
<div class="card__dropzone">
<div class="card__dropzone--inner"></div>
</div>
<div><div class="card ui-widget-content" id="card6">
<span class="card__id">6</span>
<span class="card__text">Police arrested him</span>
</div>
</div>
</div>
</div>
</section>
Css:
.card {
cursor: pointer;
}
.plot {
overflow-y: hidden;
overflow-x: visible;
height: 100%;
position: absolute;
top: 0;
left: 0;
right: 0;
width: 100vw;
padding-top: 25%;
}
.cards {
position: relative;
left: 0;
right: 0;
margin: auto;
}
.card__container {
left:0;
right: 0;
margin: 25px auto;
height: 100%;
display: table;
}
.card {
margin-top: 50px;
width: 200px;
height: 150px;
border: 1px solid #d3d3d3;
display: table-cell;
}
.card__dropzone--inner {
width: 25px;
height: 150px;
}
.card__id {
font-size: 1.5em;
font-weight: bold;
display: block;
padding: 10px;
}
.card__text {
display: block;
padding: 10px;
font-family: sans-serif;
}
.card__dropzone {
display: table-cell;
vertical-align: top;
}
.card__dropzone--active {
background: blue;
box-shadow: 0 0 10px blue;
}
Javascript:
$(document).ready(function() {
$(".card").draggable({ helper: "clone",
revert: true,
opacity: 0.5,
scroll:true,
scrollSensitivity: 100});
$(".card__dropzone--inner").droppable({
activeClass: "card__dropzone--active",
over: function(event) {
$(this).animate({
width: "250px"
}, 200);
event.target.clientWidth = 250;
console.log("over");
},
out: function(event) {
console.log("now?!");
$(event.target).animate({
width: "25px"
},200);
event.target.clientWidth = 25;
console.log("out");
},
drop: function(event) {
console.log("drop");
}
});
});
And this is my jsfiddle
http://jsfiddle.net/qthrvt8s/
You have to add refreshPositions: true while initializing .draggable() to tell your droppable area to take new dimensions in account :
$(document).ready(function() {
$(".card").draggable({ helper: "clone",
revert: true,
opacity: 0.5,
scroll:true,
refreshPositions: true,
scrollSensitivity: 100});
$(".card__dropzone--inner").droppable({
activeClass: "card__dropzone--active",
over: function(event) {
$(this).animate({
width: "250px"
}, 200);
console.log("over");
},
out: function(event) {
console.log("now?!");
$(event.target).animate({
width: "25px"
},200);
console.log("out");
},
drop: function(event) {
console.log("drop");
}
});
});
Please see the updated fiddle

Categories