JavaScript Modal is Too Big for Screen - javascript

I have created a modal window using the Prototype JavaScript framework and the following object:
var Modal = Class.create({
animate: function () {
this.step = (this.step + 1) % 31;
if (this.throbber) {
this.throbber.setStyle({
backgroundPosition: 'center ' + this.step * -33 + 'px'
});
}
},
destroy: function () {
if (this.interval_id) {
window.clearInterval(this.interval_id);
}
if (this.timeout_id) {
window.clearTimeout(this.timeout_id);
}
if (this.overlay.parentNode) {
this.overlay.remove();
}
if(this.window.select('select')){
this.window.select('select').each(function(ele){
Element.remove(ele);
});
}
this.window.select('*').invoke('remove');
if (this.window.parentNode) {
this.window.remove();
}
},
initialize: function (element) {
this.launch_element = element;
this.overlay = new Element('div', {'class': 'modal_overlay'});
$$('body').first().insert(this.overlay);
this.close = new Element('a', {
'class': 'modal_close'
}).insert('Close');
this.close.observe('click', this.destroy.bind(this));
this.window = new Element('div', {'class': 'modal_window'});
if(this.window.select('select')){
this.window.select('select').each(function(ele){
Element.remove(ele);
});
}
this.window.select('*').invoke('remove');
this.window.insert(this.close);
this.section = new Element('div', {'class': 'section'});
this.show_throbber();
this.window.insert(this.section);
$$('body').first().observe('keypress', function (e) {
var key_code = window.event ? event.keyCode : e.keyCode;
var esc = window.event ? 27 : e.DOM_VK_ESCAPE;
if (key_code === esc) {
this.destroy();
}
}.bind(this));
$$('.container').first().insert(this.window);
if (Prototype.Browser.IE) {
this.scroll_window();
Event.observe(window, 'scroll', this.scroll_window.bind(this));
}
},
remove_throbber: function () {
if (this.interval_id) {
window.clearInterval(this.interval_id);
}
if (this.timeout_id) {
window.clearTimeout(this.timeout_id);
}
this.throbber.remove();
},
scroll_window: function() {
var height, offsets;
offsets = document.viewport.getScrollOffsets();
this.overlay.setStyle({
left: offsets.left + 'px',
top: offsets.top + 'px'
});
height = document.viewport.getHeight();
this.window.setStyle({
top: offsets.top + Math.round(17 * height / 100) + 'px'
});
},
show_throbber: function (text) {
if(this.section.select('select')){
this.section.select('select').each(function(ele){
Element.remove(ele);
});
}
this.section.select('*').invoke('remove');
if (!text) {
text = 'Loading';
}
this.throbber = new Element('div', {
'class' : 'modal_throbber'
}).insert(new Element('p').insert(text + '...'));
this.section.insert(this.throbber);
this.step = 0;
this.interval_id = window.setInterval(this.animate.bind(this), 50);
this.complete = false;
this.timeout_id = window.setTimeout(this.timeout.bind(this), 20000);
},
timeout: function () {
var div, p, span;
if (!this.complete) {
if (this.interval_id) {
window.clearInterval(this.interval_id);
}
if (this.throbber) {
this.remove_throbber();
span = new Element('span', {'class': 'icon icon-delete'});
p = new Element('p', {'class': 'first'}).update(span);
p.insert('There seems to be something wrong with eSP. ' +
'Please try again later.');
div = new Element('div', {'class': 'error'}).update(p);
this.section.update(div);
}
if (this.timeout_id) {
window.clearTimeout(this.timeout_id);
}
}
}
});
and is styled with the following stylesheet:
.modal_overlay {
height: 100%;
width: 100%;
position: fixed;
left: 0;
top: 0;
z-index: 2999;
opacity: 0.5;
background: #000;
}
* html .modal_overlay {
filter: alpha(opacity=50);
position: absolute;
zoom: 1;
}
.modal_window {
display: block;
position: fixed;
top: 17%;
z-index: 3000;
}
* html .modal_window {
position: absolute;
}
.modal_close {
background: url('/images/close.gif') no-repeat scroll 0 0;
height: 26px;
cursor: pointer;
position: absolute;
right: -13px;
top: -8px;
width: 26px;
text-indent: -10000px;
}
.modal_throbber {
background: url('/images/throbber.png') no-repeat top center;
padding-top: 32px;
}
.modal_throbber p {
background: #fff;
text-align: center;
}
We are now getting reports from customers that when the modal window is taller than the screen they cannot scroll down to see the bottom part of the modal window's content.
Is it a case of us making sure that too much information isn't displayed in the modal or is there a better, more technical fix?

You can put a max-height on the modal window and overflow:scroll.

Related

Collision detection using pure jQuery is not giving desired output

I am trying to develop a very simple game where the ship (red box) will move left-right when user clicks on playground.
There are some moving walls (black boxes) as obstacles that the ship should avoid colliding with.
If any collision happens, the walls will stop moving and a text will be printed out in console.
I have succeeded to get this as close as I can. But its working sometime, not always. You can see it in the code below, try to collide with wall. Sometime it will stop them and print text, sometime it will just ignore the collision as if nothing happens.
I have no clue why this is happening.
Here is the code.
$('document').ready(function() {
var $totalHeight = $('.inner').height(); //of walls
var $maxHeight = Math.ceil(Math.ceil($totalHeight / 3) - (Math.ceil($totalHeight / 3) * 30) / 100); //30% of total wall height
$('.wall').each(function(i, obj) {
$(this).height($maxHeight);
$('.wall.four').css({
'height': $wallGap
});
})
var $wallGap = Math.ceil($totalHeight / 3) - $maxHeight;
var $wallOneTop = 0;
var $wallTwoTop = $maxHeight + $wallGap;
var $wallThreeTop = ($maxHeight * 2) + ($wallGap * 2);
var $wallFourTop = -$('.wall.four').height() - $wallGap;
$('.wall.one').css({
'top': $wallOneTop
});
$('.wall.two').css({
'top': $wallTwoTop
});
$('.wall.three').css({
'top': $wallThreeTop
});
$('.wall.four').css({
'top': $wallFourTop
});
function moveWall(wallObj) {
var $currentTop = wallObj.position().top;
var $limitTop = $('.inner').height();
if ($currentTop >= $limitTop) {
var $rand = Math.floor(Math.random() * ($maxHeight - $wallGap + 1) + $wallGap);
wallObj.height($rand);
var $top = -(wallObj.height());
} else {
var $top = (wallObj.position().top) + 5;
}
var $collide = checkCollision(wallObj);
wallObj.css({
'top': $top
});
return $collide;
}
var $wallTimer = setInterval(function() {
$('.wall').each(function(i, obj) {
var $status = moveWall($(this));
if ($status == true) {
clearInterval($wallTimer);
}
})
}, 40);
function checkCollision(wallObj) {
var $ship = $('.ship');
var $shipWidth = $ship.width();
var $shipHeight = $ship.height();
var $shipLeft = $ship.position().left;
var $shipRight = $shipLeft + $shipWidth;
var $shipTop = $ship.position().top;
var $shipBottom = $shipTop + $shipHeight;
var $wall = wallObj;
var $wallWidth = wallObj.width();
var $wallHeight = wallObj.height();
var $wallLeft = wallObj.position().left;
var $wallRight = $wallLeft + $wallWidth;
var $wallTop = wallObj.position().top;
var $wallBottom = $wallTop + $wallHeight;
if (
$shipLeft >= $wallRight ||
$shipRight <= $wallLeft ||
$shipTop >= $wallBottom ||
$shipBottom <= $wallTop
) {
return false;
} else {
console.log("dhumm!");
return true;
}
}
$('.outer .inner').click(function() {
var $ship;
$ship = $('.ship');
$shipLeft = $ship.position().left;
$shipRight = $shipLeft + $ship.width();
$inner = $('.inner');
$innerLeft = $inner.position().left;
$innerRight = $innerLeft + $inner.width();
if (($shipLeft < $inner.width() - $ship.width())) {
$ship.animate({
"left": $inner.width() - $ship.width()
}, 500, "linear");
} else if (($shipRight >= $inner.width())) {
$ship.animate({
"left": '0'
}, 500, "linear");
}
});
});
.outer {
background: #fff;
border: 20px solid #efefef;
width: 400px;
height: 600px;
display: inline-block;
position: fixed;
top: 0;
bottom: 0;
left: 0;
right: 0;
margin: auto;
overflow: hidden;
}
.outer .inner {
background: #fff;
height: 100%;
width: 100%;
margin: auto;
position: relative;
overflow: hidden;
}
.outer .inner .wall {
width: 5px;
position: absolute;
left: 50%;
transform: translateX(-50%);
background: #000;
}
.outer .inner .ship {
width: 15px;
height: 15px;
background: red;
position: absolute;
top: 50%;
transform: translateY(-50%);
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="outer">
<div class="inner">
<div class="wall one"></div>
<div class="wall two"></div>
<div class="wall three"></div>
<div class="wall four"></div>
<div class="ship"></div>
</div>
</div>
As freefomn-m already said.
Check for collision in the animation cycle of the ship, not the walls.
For this I use the second type of parameters for jQuery's .animate method
.animate( properties, options )
I use the "progress" option to check the collision in every movement cycle of the ship.
console.clear();
$('document').ready(function() {
var collided = false;
var collidedWith = null;
var $ship = $('.ship');
var $walls = $('.wall')
var $totalHeight = $('.inner').height(); //of walls
var $maxHeight = Math.ceil(Math.ceil($totalHeight / 3) - (Math.ceil($totalHeight / 3) * 30) / 100); //30% of total wall height
$('.wall').each(function(i, obj) {
$(this).height($maxHeight);
$('.wall.four').css({
'height': $wallGap
});
})
var $wallGap = Math.ceil($totalHeight / 3) - $maxHeight;
var $wallOneTop = 0;
var $wallTwoTop = $maxHeight + $wallGap;
var $wallThreeTop = ($maxHeight * 2) + ($wallGap * 2);
var $wallFourTop = -$('.wall.four').height() - $wallGap;
$('.wall.one').css({
'top': $wallOneTop
});
$('.wall.two').css({
'top': $wallTwoTop
});
$('.wall.three').css({
'top': $wallThreeTop
});
$('.wall.four').css({
'top': $wallFourTop
});
function moveWall(wallObj) {
var $currentTop = wallObj.position().top;
var $limitTop = $('.inner').height();
if ($currentTop >= $limitTop) {
var $rand = Math.floor(Math.random() * ($maxHeight - $wallGap + 1) + $wallGap);
wallObj.height($rand);
var $top = -(wallObj.height());
} else {
var $top = (wallObj.position().top) + 5;
}
// var $collide = checkCollision(wallObj);
wallObj.css({
'top': $top
});
// return $collide;
}
var $wallTimer = setInterval(function() {
$walls.each(function(i, obj) {
moveWall($(this));
if (collided) {
clearInterval($wallTimer);
}
})
}, 40);
function checkCollision() {
var $shipWidth = $ship.width();
var $shipHeight = $ship.height();
var $shipLeft = $ship.position().left;
var $shipRight = $shipLeft + $shipWidth;
var $shipTop = $ship.position().top;
var $shipBottom = $shipTop + $shipHeight;
$('.wall').each(function(i) {
var $wall = $(this);
var $wallWidth = $wall.width();
var $wallHeight = $wall.height();
var $wallLeft = $wall.position().left;
var $wallRight = $wallLeft + $wallWidth;
var $wallTop = $wall.position().top;
var $wallBottom = $wallTop + $wallHeight;
if (
$shipLeft < $wallRight &&
$shipRight > $wallLeft &&
$shipTop < $wallBottom &&
$shipBottom > $wallTop
) {
console.log("dhumm!");
collided = true;
collidedWith = $wall
$wall.addClass('crashed')
$ship.addClass('crashed')
$ship.stop();
return false;
}
})
}
$('.outer .inner').click(function() {
var $ship;
$ship = $('.ship');
$shipLeft = $ship.position().left;
$shipRight = $shipLeft + $ship.width();
$inner = $('.inner');
$innerLeft = $inner.position().left;
$innerRight = $innerLeft + $inner.width();
if (($shipLeft < $inner.width() - $ship.width())) {
$ship.animate({
"left": $inner.width() - $ship.width()
}, {
"duration": 500,
"easing": "linear",
"progress": checkCollision,
});
} else if (($shipRight >= $inner.width())) {
$ship.animate({
"left": '0'
}, {
"duration": 500,
"easing": "linear",
"progress": checkCollision,
});
}
});
});
.outer {
background: #fff;
border: 20px solid #efefef;
width: 400px;
height: 600px;
display: inline-block;
position: fixed;
top: 0;
bottom: 0;
left: 0;
right: 0;
margin: auto;
overflow: hidden;
}
.outer .inner {
background: #fff;
height: 100%;
width: 100%;
margin: auto;
position: relative;
overflow: hidden;
}
.outer .inner .wall {
width: 5px;
position: absolute;
left: 50%;
transform: translateX(-50%);
background: #000;
}
.outer .inner .wall.crashed {
background: red;
}
.outer .inner .ship {
width: 15px;
height: 15px;
background: orange;
position: absolute;
top: 50%;
transform: translateY(-50%);
}
.outer .inner .ship.crashed {
background: red;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="outer">
<div class="inner">
<div class="wall one"></div>
<div class="wall two"></div>
<div class="wall three"></div>
<div class="wall four"></div>
<div class="ship"></div>
</div>
</div>
As a recommendation how I would do this from scratch.
Use an update cycle that is called by either setInterval or setTimeout, or even better with requestAnimationFrame. The updatecycle would be responsible for the time progress and orchestrate the different objects. The structure would be like this.
jQuery(function($) { // same as $('document').ready()
var ship = ...;
var boundaries = ...;
var walls = ...;
var clickEvents = [];
document.addEventListener('click', function(e) {clickEvents.push(e)})
var handleEvents = function() {}
var setupWalls = function () {}
var setupShip= function () {}
var moveWalls = function () {}
var moveShip = function () {}
var checkCollision() {}
var setup = function() {
setupWalls();
setupShip();
// set the initial positions of the ships and the walls
}
var update = function() {
handleEvents();
moveWalls();
moveShips();
var collided = checkCollision();
if (!collided) {
setTimeout(update, 30);
}
}
setup();
update();
})

Jquery toggle icons on show more and less

I am using https://github.com/jasonujmaalvis/show-more to show and hide text on a mobile device. What I want to do is toggle between images on show more and show less:
So far I have:
Jquery:
source file:
;
(function($, window, document, undefined) {
'use strict';
var pluginName = 'showmore',
defaults = {
closedHeight: 100,
buttonTextMore: 'show more',
buttonTextLess: 'show less',
buttonCssClass: 'showmore-button',
animationSpeed: 0.5,
openHeightOffset: 0,
onlyWithWindowMaxWidth: 0
};
function Plugin(element, options) {
this.element = element;
this.settings = $.extend({}, defaults, options);
this._defaults = defaults;
this._name = pluginName;
this.btn;
this.init();
}
$.extend(Plugin.prototype, {
init: function() {
if (this.settings.onlyWithWindowMaxWidth > 0) {
this.bindResize();
this.responsive();
} else {
this.showmore();
}
},
bindResize: function() {
var self = this;
var resizeTimer;
$(window).on('resize', function() {
if (resizeTimer) {
clearTimeout(resizeTimer);
}
resizeTimer = setTimeout(function() {
self.responsive();
}, 250);
});
},
responsive: function() {
if ($(window).innerWidth() <= this.settings.onlyWithWindowMaxWidth) {
this.showmore();
} else {
this.remove();
}
},
showmore: function() {
if (this.btn) {
return;
}
var self = this;
var element = $(this.element);
var settings = this.settings;
if (settings.animationSpeed > 10) {
settings.animationSpeed = settings.animationSpeed / 1000;
}
var showMoreInner = $('<div />', {
'class': settings.buttonCssClass + '-inner more',
text: settings.buttonTextMore
});
var showLessInner = $('<div />', {
'class': settings.buttonCssClass + '-inner less',
text: settings.buttonTextLess
});
element.addClass('closed').css({
'height': settings.closedHeight,
'overflow': 'hidden'
});
var resizeTimer;
$(window).on('resize', function() {
if (!element.hasClass('closed')) {
if (resizeTimer) {
clearTimeout(resizeTimer);
}
resizeTimer = setTimeout(function() {
// resizing has "stopped"
self.setOpenHeight(true);
}, 150); // this must be less than bindResize timeout!
}
});
var showMoreButton = $('<div />', {
'class': settings.buttonCssClass,
html: showMoreInner
});
showMoreButton.on('click', function(event) {
event.preventDefault();
if (element.hasClass('closed')) {
self.setOpenHeight();
element.removeClass('closed');
showMoreButton.html(showLessInner);
} else {
element.css({
'height': settings.closedHeight,
'transition': 'all ' + settings.animationSpeed + 's ease'
}).addClass('closed');
showMoreButton.html(showMoreInner);
}
});
element.after(showMoreButton);
this.btn = showMoreButton;
},
setOpenHeight: function(noAnimation) {
$(this.element).css({
'height': this.getOpenHeight()
});
if (noAnimation) {
$(this.element).css({
'transition': 'none'
});
} else {
$(this.element).css({
'transition': 'all ' + this.settings.animationSpeed + 's ease'
});
}
},
getOpenHeight: function() {
$(this.element).css({'height': 'auto', 'transition': 'none'});
var targetHeight = $(this.element).innerHeight();
$(this.element).css({'height': this.settings.closedHeight});
// we must call innerHeight() otherwhise there will be no css animation
$(this.element).innerHeight();
return targetHeight;
},
remove: function() {
// var element = $(this.element);
if ($(this.element).hasClass('closed')) {
this.setOpenHeight();
}
if (this.btn) {
this.btn.off('click').empty().remove();
this.btn = undefined;
}
}
});
$.fn[pluginName] = function(options) {
return this.each(function() {
if (!$.data(this, 'plugin_' + pluginName)) {
$.data(this, 'plugin_' + pluginName, new Plugin(this, options));
}
});
};
})(jQuery, window, document);
my Jquery:
$('.read-more').showmore({
closedHeight: 100,
shadow: true,
onlyWithWindowMaxWidth: 576,
buttonCssClass: 'showmore-button',
buttonTextLess: 'Read less',
buttonTextMore: 'Read more'
});
CSS
.home-text .showmore-button {
margin-bottom: 25px;
background-image: url('../assets/images/plus-octagon-light.svg')!important;
background-repeat: no-repeat;
width: 150px;
padding-left: 40px;
height: 30px;
display: block;
}
.home-text .showmore-button::active {
margin-bottom: 25px;
background-image: url('../assets/images/minus-octagon-light.svg')!important;
background-repeat: no-repeat;
width: 150px;
padding-left: 40px;
height: 30px;
display: block;
}
.read-more { line-height:24px; }
.read-more_content { position:relative; overflow:hidden; }
.read-more_trigger { width:100%; height:45px; line-height:45px; cursor:pointer; }
.read-more_trigger span { display:block; }
html
<div class="home-text"><p>xxxxxxxx</p>
</div>
So I am trying to toggle between icons on show more and show less. Any ideas? I know if I used Jquery as stand alone functions I could use the toggle class, but as this is a JS plugin that is where I am thinking where to add it?
After viewing the JQuery code more, the solution that worked for me was changing the CSS with the following classes:
.showmore-button-inner.more {
margin-bottom: 25px;
background-image: url('../assets/images/plus-octagon-light.svg')!important;
background-repeat: no-repeat;
width: 150px;
padding-left: 40px;
height: 30px;
display: block;
}
.showmore-button-inner.less {
margin-bottom: 25px;
background-image: url('../assets/images/minus-octagon-light.svg')!important;
background-repeat: no-repeat;
width: 150px;
padding-left: 40px;
height: 30px;
display: block;
}

How to determine why a hyperlink is not working?

I've created a new format of the main banner for my page. However, all the links except for the little preview picture on the right side isn't working and I have no idea why.
I'm a designer who's trying to do publishing at the same time so my knowledge for js is very limited but I deal with css and html quite well.
Here is the link
;
(function($) {
$.fn.DB_tabArrowSlideMove2 = function(options) {
var opt = {
motionType: 'fade',
motionSpeed: 300,
autoRollingTime: 3000,
videoRollingTime: 6000,
arrowVisible: true,
overRolling: false,
random: false,
yt_player: []
};
$.extend(opt, options);
return this.each(function() {
var $this = $(this);
var $img = $this.find('.img');
var $img_li = $img.find('> li');
var $arrow = $this.find('.arrow');
var $next = $this.find('.next');
var $prev = $this.find('.prev');
var $auto = $this.find('.auto');
var len = $img_li.length;
//console.log(len);
var $btn = $this.find('.btn');
if (len == 1) {
$next.hide();
$prev.hide();
$btn.hide();
return;
}
if ($btn.find('li').length == 0) {
for (var i = 0; i < len; i++) {
$btn.append('<li class=n' + (i + 1) + '><span>' + (i + 1) + '</span></li>');
};
};
var $btn_li = $btn.find('> li');
var current = 0;
var oldCurrent = 0;
var dir = 'next';
var random = opt.random;
if (random) {
current = Math.floor(Math.random() * len);
oldCurrent = current;
dir = 'random';
};
var timerId = 0;
var timer = 0;
var autoPlay = true;
var arrowOver = false;
var imgWidth = $img_li.width();
var imgHeight = $img_li.height();
var overRolling = opt.overRolling;
var arrowVisible = opt.arrowVisible;
var motionType = opt.motionType;
var motionSpeed = opt.motionSpeed;
var autoRollingTime = opt.autoRollingTime;
var videoRollingTime = opt.videoRollingTime;
var mOver = false;
//
var $window = $(window);
//var yt_player=opt.yt_player;
var yt_length = yt_player.length;
var yt_pos = {};
var scrollTop = 0;
if (yt_length) {
//var $iframe=$this.find('iframe');
$iframe.each(function(index) {
$(this).attr('data-no', index);
});
$window.scroll(function() {
videoSoundByWinScroll();
});
var isMute = 1;
videoSoundByWinScroll();
function videoSoundByWinScroll() {
yt_pos.start = $this.offset().top;
yt_pos.height = $this.height()
yt_pos.end = yt_pos.start + yt_pos.height
scrollTop = $(this).scrollTop();
if (scrollTop + $window.height() > yt_pos.start && scrollTop < yt_pos.end) {
if (isMute == 0) {
var _iframe = $img_li.eq(current).find('iframe');
if (_iframe.length) {
var _no = _iframe.attr('data-no') * 1;
yt_player[_no].playVideo();
}
isMute = 1;
$this.mouseleave();
}
} else {
if (isMute == 1) {
for (var i = 0; i < yt_length; i++) {
//console.log('멈춤');
yt_player[i].pauseVideo();
}
isMute = 0;
$this.mouseenter();
}
}
}
}
init();
function init() {
setCss();
setMouseEvent();
setEnterFrame();
};
function setCss() {
if (arrowVisible == false) {
$arrow.hide();
$auto.hide();
};
for (var i = 0; i < len; i++) {
var _img = $img_li.eq(i);
switch (motionType) {
case 'x':
if (i == current) {
_img.css({
'left': 0,
'top': 0
});
} else {
_img.css({
'left': imgWidth * i,
'top': 0
});
}
break;
case 'y':
if (i == current) {
_img.css({
'top': 0,
'left': 0
});
} else {
_img.css({
'top': imgHeight * i,
'left': 0
});
}
break;
default:
_img.css({
'top': 0,
'left': 0
});
if (i == current) {
_img.show();
} else {
_img.hide();
};
};
};
$btn_li.removeClass('on');
$btn_li.eq(current).addClass('on');
$btn_li.find('span').stop().css('width', 0);
function setMouseEvent() {
$this.bind('mouseenter', function() {
mOver = true;
if (overRolling == false && autoPlay == true) {
$btn_li.eq(current).find('span').stop();
};
if (arrowVisible == false) {
$arrow.show();
$auto.show();
};
});
$this.bind('mouseleave', function() {
mOver = false;
if (overRolling == false && autoPlay == true) {
var time
if ($img_li.eq(current).find('iframe').length) {
time = videoRollingTime - videoRollingTime * $btn_li.eq(current).find('span').width() / $btn_li.eq(current).find('span').parent().width();
} else {
time = autoRollingTime - autoRollingTime * $btn_li.eq(current).find('span').width() / $btn_li.eq(current).find('span').parent().width();
}
//console.log('남은시간:'+time);
$btn_li.eq(current).find('span').animate({
'width': '100%'
}, time, 'linear');
};
if (arrowVisible == false) {
$arrow.hide();
$auto.hide();
};
if (random && (motionType != 'x' || motionType != 'y')) {
dir = 'random';
}
});
$btn_li.bind('mouseenter', function() {
var _index = $(this).index();
if (_index > current) {
//dir='next';
} else {
//dir='prev';
};
if (current != _index) {
current = _index;
setAnimation();
};
});
$arrow.bind('mouseenter', function() {
arrowOver = true;
});
$arrow.bind('mouseleave', function() {
arrowOver = false;
});
$next.bind('click', function() {
dir = 'next';
changeCurrent();
});
$prev.bind('click', function() {
dir = 'prev';
changeCurrent();
});
$auto.bind('click', function() {
if (autoPlay) {
autoPlay = false;
setReplace($auto.find('img'), 'src', '_on', '_off');
} else {
autoPlay = true;
setReplace($auto.find('img'), 'src', '_off', '_on');
};
});
};
function changeCurrent() {
if (autoPlay || arrowOver) {
if (dir == 'next') {
current++;
if (current == len) {
current = 0
}
} else if (dir == 'prev') {
current--;
if (current < 0) {
current = len - 1;
}
dir = "next";
} else {
for (var i = 0; i < 10; i++) {
current = Math.floor(Math.random() * len);
if (oldCurrent != current) {
break;
}
}
}
//console.log(current);
setAnimation();
};
};
function setEnterFrame() {
var rollingTime = 0;
if (autoRollingTime > 0) {
setInterval(function() {
// console.log(mOver,current,dir)
if (mOver == false || overRolling == true) {
timer++;
//console.log('현재동작중인:'+current)
//video
if ($img_li.eq(current).find('iframe').length) {
rollingTime = videoRollingTime;
} else {
rollingTime = autoRollingTime;
}
if (timer % (Math.ceil(rollingTime / 100)) == 0) {
changeCurrent();
}
}
}, 100);
};
};
$btn_li.removeClass('on');
$btn_li.eq(current).addClass('on');
$btn_li.find('span').stop().css('width', 0);
if (mOver == false || overRolling == true) {
function setReplace(_mc, _attr, _old, _new) {
var str = _mc.attr(_attr);
if (String(str).search(_old) != -1) {
_mc.attr(_attr, str.replace(_old, _new));
};
};
});
};
})(jQuery);
if ($iframe.length == 0) {
$('.JS_mainBnr').DB_tabArrowSlideMove2({
motionType: 'fade',
motionSpeed: 600,
autoRollingTime: 6000,
arrowVisible: true,
overRolling: false,
random: false
})
}
.JS_mainBnr {
margin-top: -283px;
z-index: 1;
width: 100%;
height: 369px/;
overflow: hidden;
margin: 0 auto;
text-align: center
}
.JS_mainBnr .img {
position: relative;
margin: 0 auto;
width: auto;
height: 100%;
}
.JS_mainBnr .img:after {
content: "";
display: block;
clear: both;
}
.JS_mainBnr .img li {
position: absolute;
top: 0;
left: 50%!important;
width: 5000px;
height: auto;
margin-left: -2500px;
text-align: center;
}
.JS_mainBnr .img li a {
width: 5000px;
height: auto;
display: inline-block
}
.JS_mainBnr .img li:first-child {
z-index: 1;
}
/* Button */
.JS_mainBnr .btn {
z-index: 3;
position: absolute;
top: 0px;
letter-spacing: -4px;
top: 0;
left: 50%!important;
width: 5000px;
height: 100%;
margin-left: -2630px;
text-align: center;
}
.JS_mainBnr .btn:after {
content: "";
display: block;
clear: both;
}
.JS_mainBnr .btn li {
position: relative;
*zoom: 1;
padding: 0 0;
background: rgba(255, 255, 255, .5);
box-shadow: 0 1px 6px rgba(0, 0, 0, 0.10);
color: #333;
font-size: 12px;
cursor: pointer;
letter-spacing: 0;
transition: all .2s ease;
-webkit-transition: all .2s ease;
width: 257px;
margin-left: 60%;
}
.JS_mainBnr:hover .btn li {
background: rgba(0, 0, 0, .1);
}
.JS_mainBnr:hover .btn li img {
opacity: 0.3
}
.JS_mainBnr .btn li.on {
z-index: 1;
background: rgba(255, 255, 255, .9) color:#fff;
}
.JS_mainBnr:hover .btn li.on img {
opacity: 1
}
/* Arrow */
.JS_mainBnr .prev {
position: absolute;
top: 285px;
left: 515px;
width: 21.5px;
height: 30px;
background: url('/_wg/img/_arrow/arrowL_50.gif') no-repeat 50% 50% rgba(255, 255, 255, .2);
opacity: 0;
-webkit-opacity: 0;
transition: all .3s ease;
-webkit-transition: all .3s ease;
background-size: 18px 27px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="JS_mainBnr">
<ul class="img">
<li>
<img src="/_wg/img/JS_mainBnr/06P.jpg" alt="">
</li>
<li>
<img src="/_wg/img/JS_mainBnr/08O.jpg" alt="">
</li>
<li>
<img src="/_wg/img/JS_mainBnr/09J.jpg" alt="">
</li>
</ul>
<div id="outer">
<ul class="btn">
<li>
<img src="/_wg/img/JS_mainBnr/01thumba.jpg" width="257px" height="105px">
</li>
<li>
<img src="/_wg/img/JS_mainBnr/02thumba.jpg" width="257px" height="105px">
</li>
<li>
<img src="/_wg/img/JS_mainBnr/03thumba.jpg" width="257px" height="105px">
</li>
</ul>
</div>
<ul class="DB_dir">
<span class="arrow prev"></span>
<span class="arrow next"></span>
</ul>
</div>
.JS_mainBnr .btn {
z-index: 3;
position: absolute;
top: 0;
left: 50%;
margin-left: 370px;
}
.JS_mainBnr .btn li {
margin-left: 60% } /<< DELETE/

Issue when sliding element in jquery?

I am trying to develop the following carousel.
http://jsfiddle.net/2kLanjwn/2/
It should work in this way.
Clicking the button DOWN, carousel scrolls and resize always div in the center.
I am not able to apply the same logic on the reverse, so when I click button UP I need to contract the central div, and sliding up.
I kindly you what I am doing wrong and if you would be able to fix it on jsfiddle.
Also I would like to know if there is any better way to achieve that same effect or a component that can be reused.
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>Scroll text box example</title>
<style>
#btn-up, #btn-down {
position: absolute;
top: 600px;
}
#btn-up {
left: 0px;
}
#btn-down {
left: 50px;
}
#btn-up, #btn-down {
width: 50px;
height: 50px;
background-color: yellow;
outline: 1px solid black;
}
#content-scroll-container {
position: absolute;
top: 0;
left: 0px;
width: 500px;
height: 250px; /* MASK HEIGHT real mask would be 200*/
overflow: hidden;
}
#content-scroll-inner {
position: absolute;
}
.cnt {
height: 100px;
width: 500px;
background-color: red;
}
.cnt:nth-child(even) {
height: 100px;
background-color: pink;
}
</style>
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<script>
var scroller = {
config: {
curPos: 0, // position
canExpand: false,
el: 'content-scroll-container', // visible area (container)
elInner: 'content-scroll-inner', // inner content
cntPosY: null, // content top-left corner (0 position)
cntHeight: null, // content lenght
maskHeight: null, // visible area (rest is masked out)
canMoveUp: null, // true jquery can slide up content
canMoveDown: null, // true jquery can slide down content
increment: 100, // slide of x pixel when user perfom an action
incrementOf: 0, // how much we have slided the contnt
animationSpeed: 500, // jquery animation speed, use 0 for no animation
isAnimationOn: false, // true when jquery is performing animation
},
data: '<div id="cnt-0" class="cnt">0</div><div id="cnt-1" class="cnt">1</div><div id="cnt-2" class="cnt">2</div><div id="cnt-3" class="cnt">3</div><div id="cnt-4" class="cnt">4</div><div id="cnt-5" class="cnt">5 empty</div>',
getCntPosition: function () {
// get y position of content
var elm = document.getElementById(this.config.elInner);
this.config.cntPosY = elm.offsetTop;
},
getCntSize: function () {
// get height for content
var elm = document.getElementById(this.config.elInner);
this.config.cntHeight = elm.clientHeight;
},
getMaskSize: function () {
// get height visible area
var elm = document.getElementById(this.config.el);
this.config.maskHeight = elm.clientHeight;
},
updateData: function () {
// refresh state
this.getMaskSize();
this.getCntPosition();
this.getCntSize();
this.canMoveUpCheck();
this.canMoveDownCheck();
//console.clear();
console.log(this.config);
},
canMoveUpCheck: function () {
// set flags allowing sliding up (in case we have enought content to show)
var lastScreenY = (this.config.cntHeight - this.config.maskHeight); // last screen visible
if ((this.config.incrementOf * -1) < lastScreenY)
this.config.canMoveUp = true;
else
this.config.canMoveUp = false;
},
canMoveDownCheck: function () {
// set flags allowing sliding down (in case we have enought content to show)
if (this.config.cntPosY >= 0)
this.config.canMoveDown = false; // cannot move more up if content is on start position (0 position)
else
this.config.canMoveDown = true;
},
goUp: function () {
// user want to read previose content
//this.updateData();
if (this.config.canMoveDown == true && this.config.isAnimationOn == false) {
this.moveCnt('down'); // content go down
}
},
goDown: function () { //**************************
// user want to read next content
//this.updateData();
if (this.config.canMoveUp == true && this.config.isAnimationOn == false) {
// check newPos
var newPos = this.config.curPos + 1;
if (newPos > 0) { // special case
if (this.config.canExpand == true)
this.config.increment = 150;
this.config.canExpand = true;
this.moveCnt('up');
}
}
},
moveCnt: function (direction) {
// do the actual animation
var moveOf;
this.isAnimationOn = true;
if (direction == 'up') {
this.config.curPos++;
if (this.config.cntPosY == 0) { // special case for first item
moveOf = '-=' + (this.config.increment / 2);
}
else {
moveOf = '-=' + this.config.increment;
}
var target = '#' + this.config.elInner + ':not(:animated)';
$(target).animate({ 'top': moveOf }, this.animationSpeed, this.cbEndAnimation.bind(this, direction));
} else if (direction == 'down') {
this.config.curPos++;
var distanceToFp = (this.config.increment / 2); // height to reach first page (special page)
var distanceToFp = 50;
if (this.config.cntPosY == (distanceToFp * -1)) {
moveOf = '+=' + distanceToFp;
// i need to contract only the firs tone
$('cnt-1').css({ height: '100px' }, 500, this.cbEndAnimationExpand.bind(this));
} else {
moveOf = '+=' + this.config.increment;
}
var target = '#' + this.config.elInner + ':not(:animated)';
$(target).animate({ 'top': moveOf }, this.animationSpeed, this.cbEndAnimation.bind(this));
}
//var target = '#' + this.config.elInner + ':not(:animated)';
//$(target).animate({ 'top': moveOf }, this.animationSpeed, this.cbEndAnimation.bind(this, direction));
},
cbEndAnimation: function (direction) {
// runs when animation end
this.config.isAnimationOn = false;
if (direction == 'up') {
this.config.incrementOf -= this.config.increment;
if (this.config.canExpand == true) { // expand
this.logicExpand();
} else {
// do nothing
}
}
else if (direction == 'down') {
this.config.incrementOf += this.config.increment;
}
this.updateData(); // refresh state has element has just moved
this.logicShowHideArrows();
},
logicExpand: function () {
// take contenf and expand it
var elm = document.getElementById('cnt-' + this.config.curPos);
$(elm).animate({ height: '150px' }, 500, this.cbEndAnimationExpand.bind(this));
},
cbEndAnimationExpand: function () {
console.log('end anim expand');
},
logicContract: function () {
var elm = document.getElementById('cnt-' + this.config.curPos);
$(elm).animate({ height: '-=50px' }, 500, this.cbEndAnimationContract.bind(this));
},
logicShowHideArrows: function () {
// reset first
this.hideArrow('btn-up');
this.hideArrow('btn-down');
if (this.config.canMoveUp == true)
this.showArrow('btn-down');
if (this.config.canMoveDown == true)
this.showArrow('btn-up');
},
cbEndAnimationContract: function () {
this.config.isAnimationOn = false;
this.moveCnt('down'); // content go down
},
showArrow: function (elmName) {
var elm = document.getElementById(elmName);
elm.style.display = '';
},
hideArrow: function (elmName) {
var elm = document.getElementById(elmName);
elm.style.display = 'none';
},
setEventHandler: function () {
// envet handlers for arrows
var btnUp = document.getElementById('btn-up');
btnUp.addEventListener('click', this.goUp.bind(this), false);
var btnDown = document.getElementById('btn-down');
btnDown.addEventListener('click', this.goDown.bind(this), false);
},
renderData: function () {
// render data content to slide
var elm = document.getElementById(this.config.elInner);
elm.innerHTML = this.data;
},
start: function () {
this.renderData();
this.updateData();
this.setEventHandler();
this.logicShowHideArrows(); // at start set arrows visibility
}
};
</script>
</head>
<body onload="scroller.start();">
<div id="content-scroll-container">
<div id="content-scroll-inner">
</div>
</div>
<div id="btn-up">UP</div>
<div id="btn-down">DOWN</div>
</body>
</html>
I can't find what in your code is wrong, but I made some changes to it, and it worked. Here is the code
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>Scroll text box example</title>
<style>
#btn-up, #btn-down {
position: absolute;
top: 400px;
}
#btn-up {
left: 0px;
}
#btn-down {
left: 50px;
}
#btn-up, #btn-down {
width: 50px;
height: 50px;
background-color: yellow;
outline: 1px solid black;
}
#content-scroll-container {
position: absolute;
top: 0;
left: 0px;
width: 500px;
height: 250px; /* MASK HEIGHT real mask would be 200*/
overflow: hidden;
}
#content-scroll-inner {
position: absolute;
}
.cnt {
height: 100px;
width: 500px;
background-color: red;
}
.cnt:nth-child(even) {
height: 100px;
background-color: pink;
}
</style>
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<script>
var scroller = {
config: {
curPos: 0, // position
el: 'content-scroll-container', // visible area (container)
elInner: 'content-scroll-inner', // inner content
cntPosY: null, // content top-left corner (0 position)
cntHeight: null, // content lenght
maskHeight: null, // visible area (rest is masked out)
animationSpeed: 500, // jquery animation speed, use 0 for no animation
isAnimationOn: false, // true when jquery is performing animation
},
data: '<div id="cnt-0" class="cnt">0</div><div id="cnt-1" class="cnt">1</div><div id="cnt-2" class="cnt">2</div><div id="cnt-3" class="cnt">3</div><div id="cnt-4" class="cnt">4</div><div id="cnt-5" class="cnt">5 empty</div>',
getCntPosition: function () {
// get y position of content
var elm = document.getElementById(this.config.elInner);
this.config.cntPosY = elm.offsetTop;
},
getCntSize: function () {
// get height for content
var elm = document.getElementById(this.config.elInner);
this.config.cntHeight = elm.clientHeight;
},
getMaskSize: function () {
// get height visible area
var elm = document.getElementById(this.config.el);
this.config.maskHeight = elm.clientHeight;
},
updateData: function () {
// refresh state
this.getMaskSize();
this.getCntPosition();
this.getCntSize();
//console.clear();
console.log(this.config);
},
logicShowHideArrows: function () {
if(this.config.curPos<1) {
$('#btn-up').hide();
} else {
$('#btn-up').show();
}
if(this.config.curPos>=4) {
$('#btn-down').hide();
} else {
$('#btn-down').show();
}
},
goUp: function () {
if(this.config.curPos<4 && scroller.config.isAnimationOn ==false) {
scroller.config.isAnimationOn = true;
scroller.config.curPos++;
if(scroller.config.curPos==1) {
$('#content-scroll-inner').animate({'top':'-=50px'},500,function(){
$('#cnt-'+scroller.config.curPos).animate({'height':'+=50px'},500);
scroller.logicShowHideArrows();
scroller.config.isAnimationOn = false;
});
this.config.incrementOf-=50;
$('#btn-up').show();
}
else {
$('#content-scroll-inner').animate({'top':'-=150px'},500,function(){
$('#cnt-'+scroller.config.curPos).animate({'height':'+=50px'},500);
scroller.logicShowHideArrows();
scroller.config.isAnimationOn = false;
});
this.config.incrementOf-=150;
}
this.updateData();
}
},
goDown: function () { //**************************
// user want to read next content
//this.updateData();
if(this.config.curPos>0 && scroller.config.isAnimationOn ==false) {
scroller.config.isAnimationOn = true;
if(this.config.curPos==1) {
$('#cnt-'+scroller.config.curPos).animate({'height':'-=50px'},500,function(){
$('#content-scroll-inner').animate({'top':'+=50px'},500);
scroller.logicShowHideArrows();
scroller.config.isAnimationOn = false;
});
scroller.config.curPos--;
this.config.incrementOf+=150;
this.updateData();
}
else {
$('#cnt-'+scroller.config.curPos).animate({'height':'-=50px'},500,function(){
$('#content-scroll-inner').animate({'top':'+=150px'},500);
scroller.logicShowHideArrows();
scroller.config.isAnimationOn = false;
});
scroller.config.curPos--;
this.config.incrementOf+=150;
this.updateData();
}
}
},
setEventHandler: function () {
$('#btn-up').click(function() {
scroller.goDown();
});
$('#btn-down').click(function() {
scroller.goUp();
});
},
renderData: function () {
// render data content to slide
var elm = document.getElementById(this.config.elInner);
elm.innerHTML = this.data;
},
start: function () {
this.renderData();
this.updateData();
this.setEventHandler();
this.logicShowHideArrows();
}
};
</script>
</head>
<body onload="scroller.start();">
<div id="content-scroll-container">
<div id="content-scroll-inner">
</div>
</div>
<div id="btn-up">UP</div>
<div id="btn-down">DOWN</div>
</body>
</html>

Empty space appearing at the end of my carousel

I have used this script to create an infinite carousel on my website here. It's been customized with CSS so the first and last items are displayed half way.
If you keep clicking the right arrow, you will end up hitting an empty space at the end. So far I haven't been able to fix this. Can anybody offer any solutions?
Here is the relevant script:
/**
* #author Stéphane Roucheray
* #extends jquery
*/
jQuery.fn.simplecarousel = function(previous, next, options){
var sliderList = jQuery(this).children()[0];
if (sliderList) {
var increment = jQuery(sliderList).children().outerWidth(true),
elmnts = jQuery(sliderList).children(),
numElmts = elmnts.length,
sizeFirstElmnt = increment,
shownInViewport = Math.round(jQuery(this).width() / sizeFirstElmnt),
firstElementOnViewPort = 1,
isAnimating = false;
for (i = 0; i < shownInViewport; i++) {
jQuery(sliderList).css('width',(numElmts+shownInViewport)*increment + increment + "px");
jQuery(sliderList).append(jQuery(elmnts[i]).clone());
}
jQuery(previous).click(function(event){
if (!isAnimating) {
if (firstElementOnViewPort == 1) {
jQuery(sliderList).css('left', "-" + numElmts * sizeFirstElmnt + "px");
firstElementOnViewPort = numElmts;
}
else {
firstElementOnViewPort--;
}
jQuery(sliderList).animate({
left: "+=" + increment,
y: 0,
queue: true
}, "swing", function(){isAnimating = false;});
isAnimating = true;
}
});
jQuery(next).click(function(event){
if (!isAnimating) {
if (firstElementOnViewPort > numElmts) {
firstElementOnViewPort = 2;
jQuery(sliderList).css('left', "0px");
}
else {
firstElementOnViewPort++;
}
jQuery(sliderList).animate({
left: "-=" + increment,
y: 0,
queue: true
}, "swing", function(){isAnimating = false;});
isAnimating = true;
}
});
}
};
#home-carousel-container {
position: relative;
}
#home-carousel {
overflow: hidden;
}
#home-carousel ul {
margin-left: -143px;
padding: 0;
position: relative;
}
#home-carousel li {
float: left;
height: 645px;
list-style: none outside none;
margin: 0 3px;
width: 256px;
}
As per my comment.
You have set a negative left-margin on your carousel causing it to hide half of an image. As a result when you click next/previous, it shows where an image is moved to create the continuous affect.
Witihin your css, I changed
#home-carousel ul{
position: relative;
padding: 0;
margin-left: -143px;
}
to
#home-carousel ul{
position: relative;
padding: 0;
margin-left: -3px;
}
And had no problems what so ever.

Categories