How to disallow mouseenter and mouseleave event when checkbox checked?
window.addEvent('domready',function() {
var z = 2;
var e = document.id('draggable');
var drag = new Drag.Move(e, {
grid: false,
preventDefault: true,
onStart: function() {
e.setStyle('z-index',z++);
}
});
//e.store('Drag', drag);
var w = e.getStyle('width');
var h = e.getStyle('height');
e.set("morph", {duration:700,delay:400}).addEvents({
mouseenter: function(){
this.store("timer", (function() {
this.morph({
width: '700px',
height: '500px',
opacity: [0.5, 1]
});
}).delay(1000, this));
},
mouseleave: function() {
var pin = this.store("timerB", (function() { //probably there is some missateke
this.morph({
width: w,
height: h,
opacity: [1, 0.5]
});
}).delay(1000, this));
$clear(this.retrieve("timer"));
}
});
});
function check(elem) {
var pin = document.id('draggable').retrieve('timerB');
if(elem.checked) {
pin.detach();
}
else {
pin.attach();
}
}
#draggable{
background-color: grey;
width: 300px;
height: 200px;
opacity: 0.5;
}
<input type="checkbox" onclick="check(this);">
<div id="draggable">Draggable DIV 1</div>
The code paste in http://jsfiddle.net/89RJp/4/
http://jsfiddle.net/89RJp/6/
you want if (element.get("checked")) return at the top of the mouseenter/mouseleave callbacks.
Related
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;
}
I selected two elements with same class with document.querySelectorAll and i want to apply function onmousemove but only to the element which has mousemove. Problem is that i dont know how to make it work on both elements but only when that element is hovered (onmousemove over it). I tried this
let menuSingle = document.querySelectorAll('.navigation__single');
let menuSingleText = document.querySelector('.navigation__single-text');
menuSingle.onmousemove = function (e) {
callParallax(e);
};
menuSingle.onmouseleave = function (e) {
TweenMax.to(menuSingleText, 2, {
y: 0,
ease: Power3.easeOut
});
};
It does not work. But when i try to select with querySelector then it only selects the first element and it works like it should. But i need it to work on both elements. Thanks in advance
edit:
my whole code
function menuHoverAnimation() {
let menuSingle = document.querySelector('.navigation__single');
let menuSingleText = document.querySelector('.navigation__single-text');
menuSingle.onmousemove = function (e) {
callParallax(e);
};
menuSingle.onmouseleave = function (e) {
TweenMax.to(menuSingleText, 2, {
y: 0,
ease: Power3.easeOut
});
};
function callParallax(e) {
parallaxIt(e, menuSingleText, 500);
}
function parallaxIt(e, target, movement) {
let $this = menuSingle;
let relY = e.pageY - $this.offsetTop;
TweenMax.to(target, 4, {
y: (relY - $this.offsetHeight / 2) / $this.offsetHeight * movement,
ease: Power3.easeOut
});
}
}
demo with working example only on first child
https://codepen.io/riogrande/pen/MGOrRr
document.querySelectorAll() returns a HTMLElementCollection containing the matches. You can loop through this and set the properties of each element to the desired functions:
let menuSingle = document.querySelectorAll('.navigation__single');
let menuSingleText = document.querySelector('.navigation__single-text');
menuSingle.forEach(elem => elem.onmouseenter = function (e) {
callParallax(e);
});
menuSingle.forEach(elem => elem.onmouseleave = function (e) {
TweenMax.to(menuSingleText, 2, {
y: 0,
ease: Power3.easeOut
});
});
Now, that you edited your post, there are a lot more mistakes of this kind:
function menuHoverAnimation() {
let menuSingle = document.querySelectorAll('.navigation__single');
let menuSingleText = document.querySelectorAll('.navigation__single-text');
menuSingle.forEach(elem => elem.onmousemove = function (e) {
callParallax(e);
});
menuSingle.forEach(elem => elem.onmouseleave = function (e) {
TweenMax.to(menuSingleText, 2, {
y: 0,
ease: Power3.easeOut
});
});
function callParallax(e) {
parallaxIt(e, menuSingleText, 500);
}
function parallaxIt(e, target, movement) {
let $this = menuSingle;
let relY = e.pageY - e.target.offsetTop;
TweenMax.to(e.target, 4, {
y: (relY - e.target.offsetHeight / 2) / e.target.offsetHeight * movement, //assuming they all have the same offsetHeight
ease: Power3.easeOut
});
}
}
menuHoverAnimation();
body {
display: flex;
}
.navigation__single {
width: 50%;
height: 100vh;
display: flex;
align-items: center;
justify-content: center;
background: blue;
}
#red {
background: red;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/gsap/1.20.3/TweenMax.min.js"></script>
<div class="navigation__single work-screen__trigger" id="red">
<span class="navigation__single-text">Work</span>
</div>
<div class="navigation__single about-screen__trigger">
<span class="navigation__single-text">About</span>
</div>
You need to add mousemove and mouseleave event listener to each element with class navigation__single. Something like below:
function mousemoveFn(e){
callParallax(e);
}
function mouseleaveFn(e){
TweenMax.to(menuSingleText, 2, {
y: 0,
ease: Power3.easeOut
});
}
let menuSingle = document.querySelectorAll('.navigation__single');
for(var i=0; i<menuSingle.length; i++){
menuSingle[i].addEventListener('mousemove', mousemoveFn);
menuSingle[i].addEventListener('mouseleave', mouseleaveFn);
}
You are almost there. Just need to loop through all the nodes to attach events to them like
let menuSingle = document.querySelectorAll('.navigation__single');
let menuSingleText = document.querySelector('.navigation__single-text');
for(var i=0; i<menuSingle.length; i++){
menuSingle[i].addEventListener("onmousemove", callParallax)
}
You can do it with Jquery, just put an ID name
$( "#mydiv" ).hover(
function() {
console.log('Hovering');
}, function() {
console.log('Not Hovering');
}
);
#mydiv {
background-color: red;
height: 100px;
width: 100px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id='mydiv'>
</div>
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>
I am currently styling the nav buttons of hero slider using css, below is my code, however I want to achieve the buttons like on the slider on www.bbc.co.uk. With the expanding div and the text appearing. Could sombeody show me how please?
This is the css for the buttons I would like to edit
.hero-carousel-nav li {
position: absolute;
bottom: 48px;
right: 48px;
list-style: none;
}
.hero-carousel-nav li.prev {
left: 48px;
right: auto;
}
.hero-carousel-nav li a {
background: #FFF;
color: #fff;
border: none;
outline: none;
display: block;
float: left;
padding: 5px 20px;
-moz-border-radius: 20px;
-webkit-border-radius: 20px;
border-radius: 10px;
behavior: url(/assets/PIE.htc);
}
.hero-carousel-nav li a:hover {
background: #06C;
}
and this is my javascript which includes the coding for the previous and next nav buttons that I would like to edit.
jQuery.fn.heroCarousel = function(options){
options = jQuery.extend({
animationSpeed: 1000,
navigation: true,
easing: '',
timeout: 5000,
pause: true,
pauseOnNavHover: true,
prevText: 'Previous',
nextText: 'Next',
css3pieFix: false,
currentClass: 'current',
onLoad: function(){},
onStart: function(){},
onComplete: function(){}
}, options);
if(jQuery.browser.msie && parseFloat(jQuery.browser.version) < 7){
options.animationSpeed = 0;
}
return this.each(function() {
var carousel = jQuery(this),
elements = carousel.children();
currentItem = 1;
childWidth = elements.width();
childHeight = elements.height();
if(elements.length > 2){
elements.each(function(i){
if(options.itemClass){
jQuery(this).addClass(options.itemClass);
}
});
elements.filter(':first').addClass(options.currentClass).before(elements.filter(':last'));
var carouselWidth = Math.round(childWidth * carousel.children().length),
carouselMarginLeft = '-'+ Math.round(childWidth + Math.round(childWidth / 2) ) +'px'
carousel.addClass('hero-carousel-container').css({
'position': 'relative',
'overflow': 'hidden',
'left': '50%',
'top': 0,
'margin-left': carouselMarginLeft,
'height': childHeight,
'width': carouselWidth
});
carousel.before('<ul class="hero-carousel-nav"><li class="prev">'+options.prevText+'</li><li class="next">'+options.nextText+'</li></ul>');
var carouselNav = carousel.prev('.hero-carousel-nav'),
timeoutInterval;
if(options.timeout > 0){
var paused = false;
if(options.pause){
carousel.hover(function(){
paused = true;
},function(){
paused = false;
});
}
if(options.pauseOnNavHover){
carouselNav.hover(function(){
paused = true;
},function(){
paused = false;
});
}
function autoSlide(){
if(!paused){
carouselNav.find('.next a').trigger('click');
}
}
timeoutInterval = window.setInterval(autoSlide, options.timeout);
}
carouselNav.find('a').data('disabled', false).click(function(e){
e.preventDefault();
var navItem = jQuery(this),
isPrevious = navItem.parent().hasClass('prev'),
elements = carousel.children();
if(navItem.data('disabled') === false){
options.onStart(carousel, carouselNav, elements.eq(currentItem), options);
if(isPrevious){
animateItem(elements.filter(':last'), 'previous');
}else{
animateItem(elements.filter(':first'), 'next');
}
navItem.data('disabled', true);
setTimeout(function(){
navItem.data('disabled', false);
}, options.animationSpeed+200);
if(options.timeout > 0){
window.clearInterval(timeoutInterval);
timeoutInterval = window.setInterval(autoSlide, options.timeout);
}
}
});
function animateItem(object,direction){
var carouselPosLeft = parseFloat(carousel.position().left),
carouselPrevMarginLeft = parseFloat(carousel.css('margin-left'));
if(direction === 'previous'){
object.before( object.clone().addClass('carousel-clone') );
carousel.prepend( object );
var marginLeft = Math.round(carouselPrevMarginLeft - childWidth);
var plusOrMinus = '+=';
}else{
object.after( object.clone().addClass('carousel-clone') );
carousel.append( object );
var marginLeft = carouselMarginLeft;
var plusOrMinus = '-=';
}
if(options.css3pieFix){
fixPieClones(jQuery('.carousel-clone'));
}
carousel.css({
'left': carouselPosLeft,
'width': Math.round(carouselWidth + childWidth),
'margin-left': marginLeft
}).animate({'left':plusOrMinus+childWidth}, options.animationSpeed, options.easing, function(){
carousel.css({
'left': '50%',
'width': carouselWidth,
'margin-left': carouselPrevMarginLeft
});
jQuery('.carousel-clone').remove();
finishCarousel();
});
}
function fixPieClones(clonedObject){
var itemPieId = clonedObject.attr('_pieId');
if(itemPieId){
clonedObject.attr('_pieId', itemPieId+'_cloned');
}
clonedObject.find('*[_pieId]').each(function(i, item){
var descendantPieId = $(item).attr('_pieId');
$(item).attr('_pieId', descendantPieId+'_cloned');
});
}
function finishCarousel(){
var elements = carousel.children();
elements.removeClass(options.currentClass).eq(currentItem).addClass(options.currentClass);
options.onComplete(carousel, carousel.prev('.hero-carousel-nav'), elements.eq(currentItem), options);
}
if(jQuery.browser.msie){
carouselNav.find('a').attr("hideFocus", "true");
}
options.onLoad(carousel, carouselNav, carousel.children().eq(currentItem), options);
}
});
};
BBC website is actually using a custom javascript library called glow. you might want to look at this:
Alternatively you can also use this slider, by checking the source code.
I want to display my jQuery validation messages in a tooltip. In order to accomplish this, I started out by adding the following CSS rules to my stylesheet:
fieldset .field-validation-error {
display: none;
}
fieldset .field-validation-error.tooltip-icon {
background-image: url('/content/images/icons.png');
background-position: -32px -192px;
width: 16px;
height: 16px;
display: inline-block;
}
and a very small piece of JS code:
; (function ($) {
$(function() {
var fields = $("fieldset .field-validation-valid, fieldset .field-validation-error");
fields.each(function() {
var self = $(this);
self.addClass("tooltip-icon");
self.attr("rel", "tooltip");
self.attr("title", self.text());
self.text("");
self.tooltip();
});
});
})(jQuery);
The issue is that I now need to capture any event when the validation message changes, I've been looking at the source for jquery.validate.unobtrusive.js, and the method I'd need to hook to is the function onError(error, inputElement) method.
My tooltip plugin works as long as I've an updated title attribute, the issue comes when the field is revalidated, and the validation message is regenerated, I would need to hook into that and prevent the message from being put out there and place it in the title attribute instead.
I want to figure out a way to do this without modifying the actual jquery.validate.unobtrusive.js file.
On a second note, how could I improve this in order to leave the functionality unaltered in case javascript is disabled?
Ok I went with this, just in case anyone runs into this again:
; (function ($) {
$(function() {
function convertValidationMessagesToTooltips(form) {
var fields = $("fieldset .field-validation-valid, fieldset .field-validation-error", form);
fields.each(function() {
var self = $(this);
self.addClass("tooltip-icon");
self.attr("rel", "tooltip");
self.attr("title", self.text());
var span = self.find("span");
if (span.length) {
span.text("");
} else {
self.text("");
}
self.tooltip();
});
}
$("form").each(function() {
var form = $(this);
var settings = form.data("validator").settings;
var old_error_placement = settings.errorPlacement;
var new_error_placement = function() {
old_error_placement.apply(settings, arguments);
convertValidationMessagesToTooltips(form);
};
settings.errorPlacement = new_error_placement;
convertValidationMessagesToTooltips(form); // initialize in case of model-drawn validation messages at page render time.
});
});
})(jQuery);
and styles:
fieldset .field-validation-error { /* noscript */
display: block;
margin-bottom: 20px;
}
fieldset .field-validation-error.tooltip-icon { /* javascript enabled */
display: inline-block;
margin-bottom: 0px;
background-image: url('/content/images/icons.png');
background-position: -32px -192px;
width: 16px;
height: 16px;
vertical-align: middle;
}
I'll just include the tooltip script I have, since it's kind of custom-made (though I based it off someone else's).
; (function ($, window) {
$.fn.tooltip = function (){
var classes = {
tooltip: "tooltip",
top: "tooltip-top",
left: "tooltip-left",
right: "tooltip-right"
};
function init(self, tooltip) {
if ($(window).width() < tooltip.outerWidth() * 1.5) {
tooltip.css("max-width", $(window).width() / 2);
} else {
tooltip.css("max-width", 340);
}
var pos = {
x: self.offset().left + (self.outerWidth() / 2) - (tooltip.outerWidth() / 2),
y: self.offset().top - tooltip.outerHeight() - 20
};
if (pos.x < 0) {
pos.x = self.offset().left + self.outerWidth() / 2 - 20;
tooltip.addClass(classes.left);
} else {
tooltip.removeClass(classes.left);
}
if (pos.x + tooltip.outerWidth() > $(window).width()) {
pos.x = self.offset().left - tooltip.outerWidth() + self.outerWidth() / 2 + 20;
tooltip.addClass(classes.right);
} else {
tooltip.removeClass(classes.right);
}
if (pos.y < 0) {
pos.y = self.offset().top + self.outerHeight();
tooltip.addClass(classes.top);
} else {
tooltip.removeClass(classes.top);
}
tooltip.css({
left: pos.x,
top: pos.y
}).animate({
top: "+=10",
opacity: 1
}, 50);
};
function activate() {
var self = $(this);
var message = self.attr("title");
var tooltip = $("<div class='{0}'></div>".format(classes.tooltip));
if (!message) {
return;
}
self.removeAttr("title");
tooltip.css("opacity", 0).html(message).appendTo("body");
var reload = function() { // respec tooltip's size and position.
init(self, tooltip);
};
reload();
$(window).resize(reload);
var remove = function () {
tooltip.animate({
top: "-=10",
opacity: 0
}, 50, function() {
$(this).remove();
});
self.attr("title", message);
};
self.bind("mouseleave", remove);
tooltip.bind("click", remove);
};
return this.each(function () {
var self = $(this);
self.bind("mouseenter", activate);
});
};
$.tooltip = function() {
return $("[rel~=tooltip]").tooltip();
};
})(jQuery, window);