Scroll to bottom using ngScrollbar - javascript

I am trying to automatically scroll to bottom whenever there is a new message.
I use angular directive ng-scrollbar.
Here is the code of the directive there is one method of scroll named scrolTo:
/**
* #name ng-scrollbar
* #author angrytoro
* #since 9/12/2014
* #version 0.1
* #beta 0.2
* #see https://github.com/angrytoro/ngscrollbar
* #copyright 2014 angrytoro
* #license MIT: You are free to use and modify this code, on the condition that this copyright notice remains.
*
* #description The angular directive ng-scrollbar imitate the true browser scrollbar.
* It's applied to the element which set height or width attribute and the overflow is auto, but exclude body element.
* It's not necessary to imitate scrollbar for body element, if you use the AngularJS.
* suggests: don't use the directive, if you don't have to. The scrollbar which is inbuilt in browser is more highly-efficient.
*AngularJS is not fit for IE which version is less then 9, so the directive is not fit the IE(8,7,6,5).
*
*
* #example
* 1.
* <div style="height:300px;overflow:auto;" ng-scrollbar>
* <li ng-repeat="item in items">item</li>
* </div>
* 2.
* <div style="height:300px;overflow:auto;" ng-scrollbar scrollbar-x="false" scrollbar-y="true" scrollbar-config="{show:true, autoResize: true, dragSpeed: 1.2}">
* <li ng-repeat="item in items">item</li>
* </div>
* 3.
* <div ng-scrollbar>
* <div style="height:400px;width:3000px"></div>
* </div>
*
* #conf spec
* scrollbar-x the value is true or false, to configure the x scrollbar create or no create, the default value is true. but the directive can decide whether it need be created if user not set the attribute.
*
* scrollbar-y the value is true or false, to configure the y scrollbar create or no create, the default value is true. but the directive can decide whether it need be created if user not set the attribute.
*
* scrollbar-config
* default config is
*
* {
* dragSpeed: 1, //default browser delta value is 120 or -120
autoResize: false, // if need auto resize, default false
show: false, // if need show when mouse not enter the container element which need scrollbar, default false.
scrollbar: {
width: 6, //scrollbar width
hoverWidth: 8, //scrollbar width when the mouse hover on it
color: 'rgba(0,0,0,.6)' //scrollbar background color
},
scrollbarContainer: {
width: 12, //scrollbarContainer width
color: 'rgba(0,0,0,.1)' // scrollbarContainer background
}
* }
*
*/
angular.module('widget.scrollbar', [])
.directive('ngScrollbar', [
function() {
return {
restrict: 'AE',
transclude: true,
scope: {
scrollbarConfig: '=scrollbarConfig',
scrollbarX: '#', // the value is true or false, to configure the x scrollbar create or no create.
scrollbarY: '#' // the value is true or false, to configure the y scrollbar create or no create.
},
template: '<div style="position:relative;width:100%;height:100%;">\
<div class="ngscroll-content-container" style="display:inline-block;margin-top:0;margin-left:0" ng-transclude>\
</div>\
<ng-scrollbar-x ng-if="scrollbarX || scrollbarX === undefined"></ng-scrollbar-x>\
<ng-scrollbar-y ng-if="scrollbarY || scrollbarY === undefined"></ng-scrollbar-y>\
</div>',
controller: 'scrollbarController',
compile: function(element) {
element.css('overflow', 'hidden');
return function(scope, element, attrs, ctrl) {
ctrl.init(element, scope.scrollbarConfig);
};
}
};
}
])
.controller('scrollbarController', [function() {
var defaultConfig = {
dragSpeed: 1, //default browser delta value is 120 or -120
autoResize: false, // if need auto resize, default false
show: false, // if need show when mouse not enter the container element which need scrollbar, default false.
scrollbar: {
width: 6, //scrollbar width
hoverWidth: 8, //scrollbar width when the mouse hover on it
color: 'rgba(0,0,0,.6)' //scrollbar background color
},
scrollbarContainer: {
width: 12, //scrollbarContainer width
color: 'rgba(0,0,0,.1)' // scrollbarContainer background
}
};
var containerElement, // the element which need the directive of ngscrollbar
contentElement, // the element which transclude the true content
config, // config
scrollbarMargin, // the variable is used to descide the scrollbar element top or left to its parent element scrollbarContainer
scrollbarHoverMargin; // the variable is used to descide the scrollbar element top or left to its parent element scrollbarContainer when the mouse hover on the scrollbar
/**
* it must be called before the controller is used.
* #param {jqlite object} element it's necessary variable
* #param {object} scrollbarConfig the config which is defined by user
* #return
*/
this.init = function(element, scrollbarConfig) {
containerElement = element;
config = angular.copy(angular.extend(defaultConfig, scrollbarConfig || {}));
contentElement = angular.element(element[0].querySelector('.ngscroll-content-container'));
scrollbarMargin = (config.scrollbarContainer.width - config.scrollbar.width) / 2;
scrollbarHoverMargin = (config.scrollbarContainer.width - config.scrollbar.hoverWidth) / 2;
};
angular.extend(this, {
/**
* Wrap window in an angular jqLite object.
*/
winEl: angular.element(window),
/**
* get the element which need the directive of ngscrollbar
* #return {jqlite object}
*/
getContainerElement: function() {
return containerElement;
},
/**
* the element which transclude the true content
* #return {jqlite object}
*/
getContentElement: function() {
return contentElement;
},
/**
* get the config
* #return {object}
*/
getConfig: function() {
return config;
},
/**
* get the scrollbarMargin
* #return {number}
*/
getScrollbarMargin: function() {
return scrollbarMargin;
},
/**
* get the scrollbarHoverMargin
* #return {number}
*/
getScrollbarHoverMargin: function() {
return scrollbarHoverMargin;
}
});
}])
.directive('ngScrollbarY', ['$timeout', function($timeout){
return {
restrict: 'AE',
require: '^ngScrollbar',
replace: true,
template: '<div class="ngscrollbar-container-y" ng-style="styles.scrollbarContainer"><div class="ngscrollbar-y" ng-style="styles.scrollbar"></div></div>',
compile: function() {
return function(scope, element, attrs, ctrl) {
var config = ctrl.getConfig(),
docEl = angular.element(document),
containerElement = ctrl.getContainerElement(),
contentElement = ctrl.getContentElement(),
scrollbar = angular.element(element[0].querySelector('.ngscrollbar-y')),
scrollbarMargin = ctrl.getScrollbarMargin(),
scrollbarHoverMargin = ctrl.getScrollbarHoverMargin();
scope.styles = {
scrollbarContainer: {
position: 'absolute',
width: config.scrollbarContainer.width + 'px',
height: '100%',
top: 0,
right: 0,
transition: 'background .3s ease-in-out',
'border-radius': config.scrollbarContainer.width / 2 + 'px'
},
scrollbar: {
position: 'absolute',
width: config.scrollbar.width + 'px',
right: scrollbarMargin + 'px',
cursor: 'default',
opacity: 0,
transition: 'opacity .3s ease-in-out, border-radius .1s linear, width .1s linear, right .1s linear',
background: config.scrollbar.color,
'border-radius': config.scrollbar.width / 2 + 'px'
}
};
var getContentHeight = function() {
return contentElement[0].offsetHeight;
};
var getContainerHeight = function() {
return containerElement[0].offsetHeight;
};
var getScrollbarHeight = function() {
var height = Math.pow(getContainerHeight(), 2) / getContentHeight() - scrollbarMargin*2;
return height;
};
var isOverflow = function() {
return getContentHeight() > getContainerHeight();
};
var hideScrollbar = function() {
scrollbar.css('opacity', 0);
};
var showScrollbar = function() {
scrollbar.css('opacity', 1);
};
var reset = function() {
var oldMarginTop = parseInt(contentElement.css('margin-top'), 10);
contentElement.css('margin-top', '0px'); // this is for the element which has the attribute of max-height
if (isOverflow()) {
element.css('display', 'block');
scrollbar.css('height', getScrollbarHeight() + 'px');
scrollTo(oldMarginTop);
if (config.show) {
showScrollbar();
}
} else {
element.css('display', 'none');
}
};
var scrollTo = function(top) {
top = Math.min(0, Math.max(top, getContainerHeight() - getContentHeight()));
contentElement.css('margin-top', top + 'px');
scrollbar.css('top', -top/getContentHeight()*getContainerHeight() + scrollbarMargin + 'px');
};
var scroll = function(distance) {
var newTop = parseInt(contentElement.css('margin-top'), 10) + distance;
scrollTo(newTop);
};
containerElement.on('mousewheel', function(event) {
if (!isOverflow()) {
return;
}
event.preventDefault();
if (event.originalEvent !== undefined) {
event = event.originalEvent;
}
scroll(event.wheelDeltaY || event.wheelDelta);
});
if(window.navigator.userAgent.toLowerCase().indexOf('firefox') >= 0) {
containerElement.on('wheel', function(event) {
if (!isOverflow()) {
return;
}
event.preventDefault();
if (event.originalEvent !== undefined) {
event = event.originalEvent;
}
scroll(-event.deltaY * 40);// the ff delta value is 3 or -3 when scroll and the chrome or ie is -120 or 120, so it must multiply by 40
});
}
element.on('mouseenter', function() {
element.css('background', config.scrollbarContainer.color);
scrollbar.css('width', config.scrollbar.hoverWidth + 'px');
scrollbar.css('right', scrollbarHoverMargin + 'px');
scrollbar.css('border-radius', config.scrollbar.hoverWidth / 2 + 'px');
});
element.on('mouseleave', function() {
element.css('background', 'none');
scrollbar.css('width', config.scrollbar.width + 'px');
scrollbar.css('right', scrollbarMargin + 'px');
scrollbar.css('border-radius', config.scrollbar.width / 2 + 'px');
});
var scrollbarMousedown = false,
axisY,
mouseInElement = false;
if (!config.show) {
containerElement.on('mouseenter', function() {
mouseInElement = true;
showScrollbar();
});
containerElement.on('mouseleave', function() {
mouseInElement = false;
if (scrollbarMousedown) {
return;
}
hideScrollbar();
});
}
scrollbar.on('mousedown', function(event) {
event.preventDefault();
axisY = event.screenY;
scrollbarMousedown = true;
docEl.one('mouseup', function() {
scrollbarMousedown = false;
if (!config.show && !mouseInElement) {
hideScrollbar();
}
// docEl.off('mouseup', arguments.callee);
});
});
docEl.on('mousemove', function(event) {
if(scrollbarMousedown) {
event.preventDefault();
scroll(-(event.screenY - axisY) * config.dragSpeed * getContentHeight() / getContainerHeight());
axisY = event.screenY;
}
});
$timeout(function() {
reset();
if (!!document.createStyleSheet) { //if the browser is ie browser
contentElement.on('DOMNodeInserted', reset);
contentElement.on('DOMNodeRemoved', reset);
} else {
var observer = new MutationObserver(function(mutations){
if (mutations.length) {
reset();
}
});
observer.observe(contentElement[0], {childList:true, subtree: true});
}
}, 5);
// Redraw the scrollbar when window size changes.
if (config.autoResize) {
// Closure to guard against leaking variables.
(function () {
var redrawTimer;
ctrl.winEl.on('resize', function (e) {
if (redrawTimer) {
clearTimeout(redrawTimer);
}
redrawTimer = setTimeout(function () {
redrawTimer = null;
reset();
}, 50);
});
})();
}
};
}
};
}])
.directive('ngScrollbarX', ['$timeout', function($timeout) {
return {
restrict: 'AE',
replace: true,
require: '^ngScrollbar',
template: '<div class="ngscrollbar-container-x" ng-style="styles.scrollbarContainer"><div class="ngscrollbar-x" ng-style="styles.scrollbar"></div></div>',
compile: function() {
return function(scope, element, attrs, ctrl) {
var config = ctrl.getConfig(),
docEl = angular.element(document),
containerElement = ctrl.getContainerElement(),
containerDom = containerElement[0],
contentElement = ctrl.getContentElement(), //the container of content
scrollbar = angular.element(element[0].querySelector('.ngscrollbar-x')),
scrollbarMargin = ctrl.getScrollbarMargin(),
scrollbarHoverMargin = ctrl.getScrollbarHoverMargin();
scope.styles = {
scrollbarContainer: {
position: 'absolute',
width: '100%',
transition: 'background .3s ease-in-out',
'border-radius': config.scrollbarContainer.width / 2 + 'px'
},
scrollbar: {
position: 'absolute',
cursor: 'default',
opacity: 0,
transition: 'opacity .3s ease-in-out, border-radius .1s linear, width .1s linear, right .1s linear',
background: config.scrollbar.color,
'border-radius': config.scrollbar.width / 2 + 'px'
}
};
element.css('height', config.scrollbarContainer.width + 'px'); // set the scrollbarContainer height;
element.css('bottom', 0); // set scrollbarContainer top
element.css('left', 0); //set scrollbarContainer left
scrollbar.css('top', scrollbarMargin + 'px'); //set scrollbar top
scrollbar.css('height', config.scrollbar.width + 'px');
var getContentWidth = function() {
return contentElement[0].offsetWidth;
};
var getContainerWidth = function() {
return containerDom.offsetWidth;
};
var getScrollbarWidth = function() {
return Math.pow(getContainerWidth(), 2) / getContentWidth() - scrollbarMargin * 2;
};
var showScrollbar = function() {
scrollbar.css('opacity', 1);
};
var hideScrollbar = function() {
scrollbar.css('opacity', 0);
};
var isOverflow = function() {
return getContentWidth() > getContainerWidth();
};
var reset = function() {
var oldMarginLeft = parseInt(contentElement.css('margin-left'), 10);
contentElement.css('margin-left', '0px');
if (isOverflow()) {
element.css('display', 'block');
scrollbar.css('width', getScrollbarWidth() + 'px');
scrollTo(oldMarginLeft);
if (config.show) {
showScrollbar();
}
} else {
element.css('display', 'none');
}
};
var scrollTo = function(left) {
left = Math.min(0, Math.max(left, getContainerWidth() - getContentWidth()));
contentElement.css('margin-left', left + 'px');
scrollbar.css('left', -left/getContentWidth()*getContainerWidth() + scrollbarMargin + 'px');
};
var scroll = function(distance) {
var left = parseInt(contentElement.css('margin-left'), 10) + distance;
scrollTo(left);
};
element.on('mouseenter', function() {
element.css('background', config.scrollbarContainer.color);
scrollbar.css('height', config.scrollbar.hoverWidth + 'px');
scrollbar.css('top', scrollbarHoverMargin + 'px');
scrollbar.css('border-radius', config.scrollbar.hoverWidth / 2 + 'px');
});
element.on('mouseleave', function() {
element.css('background', 'none');
scrollbar.css('height', config.scrollbar.width + 'px');
scrollbar.css('top', scrollbarMargin + 'px');
scrollbar.css('border-radius', config.scrollbar.width / 2 + 'px');
});
var scrollbarMousedown = false,
axisX,
mouseInElement = false;
if (!config.show) {
containerElement.on('mouseenter', function() {
mouseInElement = true;
showScrollbar();
});
containerElement.on('mouseleave', function() {
mouseInElement = false;
if (scrollbarMousedown) {
return;
}
hideScrollbar();
});
}
scrollbar.on('mousedown', function(event) {
event.preventDefault();
scrollbarMousedown = true;
axisX = event.screenX;
docEl.one('mouseup', function() {
scrollbarMousedown = false;
if (!config.show && !mouseInElement) {
hideScrollbar();
}
// docEl.off('mouseup', arguments.callee);
});
});
docEl.on('mousemove', function(event) {
if(scrollbarMousedown) {
event.preventDefault();
scroll(-(event.screenX - axisX) * config.dragSpeed * getContentWidth() / getContainerWidth());
axisX = event.screenX;
}
});
$timeout(function() {
reset();
if (!!document.createStyleSheet) { //if the browser is ie browser
contentElement.on('DOMNodeInserted', reset);
contentElement.on('DOMNodeRemoved', reset);
} else {
var observer = new MutationObserver(function(mutations){
if (mutations.length) {
reset();
}
});
observer.observe(contentElement[0], {childList:true, subtree: true});
}
}, 5);
// Redraw the scrollbar when window size changes.
if (config.autoResize) {
// Closure to guard against leaking variables.
(function () {
var redrawTimer;
ctrl.winEl.on('resize', function (e) {
if (redrawTimer) {
clearTimeout(redrawTimer);
}
redrawTimer = setTimeout(function () {
redrawTimer = null;
reset();
}, 50);
});
})();
}
};
}
};
}]);
Thanks for any help to resolve this problem.

You could just use vanilla javascript:
window.scrollTo(0,document.body.scrollHeight);
Run the code above on the event of a new message.
Edit: added example
angular.module('app', [])
.controller('TestCtrl', function($scope) {
$scope.scrollToBottom = function() {
window.scrollTo(0, document.body.scrollHeight);
};
});
#some-content {
height: 10000px;
}
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app="app" ng-controller="TestCtrl">
top
<button ng-click="scrollToBottom()">Scroll to bottom</button>
<div id="some-content"></div>
bottom
</div>

I found a very extravagant kosher solution.
I changed code ngScrollbar like this:
angular.module('widget.scrollbar', [])
.directive('ngScrollbar', [
function() {
return {
restrict: 'AE',
transclude: true,
scope: {
name: '#',
scrollbarConfig: '=scrollbarConfig',
scrollbarX: '#', // the value is true or false, to configure the x scrollbar create or no create.
scrollbarY: '#' // the value is true or false, to configure the y scrollbar create or no create.
},
template: '<div style="position:relative;width:100%;height:100%;">\
<div class="ngscroll-content-container" style="display:inline-block;margin-top:0;margin-left:0" ng-transclude>\
</div>\
<ng-scrollbar-x ng-if="scrollbarX || scrollbarX === undefined"></ng-scrollbar-x>\
<ng-scrollbar-y ng-if="scrollbarY || scrollbarY === undefined"></ng-scrollbar-y>\
</div>',
controller: 'scrollbarController',
compile: function(element) {
element.css('overflow', 'hidden');
return function(scope, element, attrs, ctrl) {
ctrl.init(element, scope.scrollbarConfig);
};
}
};
}
])
.controller('scrollbarController', [function() {
var defaultConfig = {
dragSpeed: 1, //default browser delta value is 120 or -120
autoResize: false, // if need auto resize, default false
show: false, // if need show when mouse not enter the container element which need scrollbar, default false.
scrollbar: {
width: 6, //scrollbar width
hoverWidth: 8, //scrollbar width when the mouse hover on it
color: 'rgba(0,0,0,.6)' //scrollbar background color
},
scrollbarContainer: {
width: 12, //scrollbarContainer width
color: 'rgba(0,0,0,.1)' // scrollbarContainer background
}
};
var containerElement, // the element which need the directive of ngscrollbar
contentElement, // the element which transclude the true content
config, // config
scrollbarMargin, // the variable is used to descide the scrollbar element top or left to its parent element scrollbarContainer
scrollbarHoverMargin; // the variable is used to descide the scrollbar element top or left to its parent element scrollbarContainer when the mouse hover on the scrollbar
/**
* it must be called before the controller is used.
* #param {jqlite object} element it's necessary variable
* #param {object} scrollbarConfig the config which is defined by user
* #return
*/
this.init = function(element, scrollbarConfig) {
containerElement = element;
config = angular.copy(angular.extend(defaultConfig, scrollbarConfig || {}));
contentElement = angular.element(element[0].querySelector('.ngscroll-content-container'));
scrollbarMargin = (config.scrollbarContainer.width - config.scrollbar.width) / 2;
scrollbarHoverMargin = (config.scrollbarContainer.width - config.scrollbar.hoverWidth) / 2;
};
angular.extend(this, {
/**
* get the element which need the directive of ngscrollbar
* #return {jqlite object}
*/
getContainerElement: function() {
return containerElement;
},
/**
* the element which transclude the true content
* #return {jqlite object}
*/
getContentElement: function() {
return contentElement;
},
/**
* get the config
* #return {object}
*/
getConfig: function() {
return config;
},
/**
* get the scrollbarMargin
* #return {number}
*/
getScrollbarMargin: function() {
return scrollbarMargin;
},
/**
* get the scrollbarHoverMargin
* #return {number}
*/
getScrollbarHoverMargin: function() {
return scrollbarHoverMargin;
}
});
}])
.directive('ngScrollbarY', ['$timeout', 'ScrollbarDelegate', function($timeout, ScrollbarDelegate){
return {
restrict: 'AE',
require: '^ngScrollbar',
replace: true,
template: '<div class="ngscrollbar-container-y" ng-style="styles.scrollbarContainer"><div class="ngscrollbar-y" ng-style="styles.scrollbar"></div></div>',
compile: function() {
return function(scope, element, attrs, ctrl) {
var config = ctrl.getConfig(),
docEl = angular.element(document),
containerElement = ctrl.getContainerElement(),
contentElement = ctrl.getContentElement(),
scrollbar = angular.element(element[0].querySelector('.ngscrollbar-y')),
scrollbarMargin = ctrl.getScrollbarMargin(),
scrollbarHoverMargin = ctrl.getScrollbarHoverMargin();
scope.styles = {
scrollbarContainer: {
position: 'absolute',
width: config.scrollbarContainer.width + 'px',
height: '100%',
top: 0,
right: 0,
transition: 'background .3s ease-in-out',
'border-radius': config.scrollbarContainer.width / 2 + 'px'
},
scrollbar: {
position: 'absolute',
width: config.scrollbar.width + 'px',
right: scrollbarMargin + 'px',
cursor: 'default',
opacity: 0,
transition: 'opacity .3s ease-in-out, border-radius .1s linear, width .1s linear, right .1s linear',
background: config.scrollbar.color,
'border-radius': config.scrollbar.width / 2 + 'px'
}
};
var getContentHeight = function() {
return contentElement[0].offsetHeight;
};
var getContainerHeight = function() {
return containerElement[0].offsetHeight;
};
var getScrollbarHeight = function() {
var height = Math.pow(getContainerHeight(), 2) / getContentHeight() - scrollbarMargin*2;
return height;
};
var isOverflow = function() {
return getContentHeight() > getContainerHeight();
};
var hideScrollbar = function() {
scrollbar.css('opacity', 0);
};
var showScrollbar = function() {
scrollbar.css('opacity', 1);
};
var reset = function() {
var oldMarginTop = parseInt(contentElement.css('margin-top'), 10);
contentElement.css('margin-top', '0px'); // this is for the element which has the attribute of max-height
if (isOverflow()) {
element.css('display', 'block');
scrollbar.css('height', getScrollbarHeight() + 'px');
scrollTo(oldMarginTop);
if (config.show) {
showScrollbar();
}
} else {
element.css('display', 'none');
}
};
var scrollTo = function(top) {
top = Math.min(0, Math.max(top, getContainerHeight() - getContentHeight()));
contentElement.css('margin-top', top + 'px');
scrollbar.css('top', -top/getContentHeight()*getContainerHeight() + scrollbarMargin + 'px');
};
var scroll = function(distance) {
var newTop = parseInt(contentElement.css('margin-top'), 10) + distance;
scrollTo(newTop);
};
containerElement.on('mousewheel', function(event) {
if (!isOverflow()) {
return;
}
event.preventDefault();
if (event.originalEvent !== undefined) {
event = event.originalEvent;
}
scroll(event.wheelDeltaY || event.wheelDelta);
});
if(window.navigator.userAgent.toLowerCase().indexOf('firefox') >= 0) {
containerElement.on('wheel', function(event) {
if (!isOverflow()) {
return;
}
event.preventDefault();
if (event.originalEvent !== undefined) {
event = event.originalEvent;
}
scroll(-event.deltaY * 40);// the ff delta value is 3 or -3 when scroll and the chrome or ie is -120 or 120, so it must multiply by 40
});
}
element.on('mouseenter', function() {
element.css('background', config.scrollbarContainer.color);
scrollbar.css('width', config.scrollbar.hoverWidth + 'px');
scrollbar.css('right', scrollbarHoverMargin + 'px');
scrollbar.css('border-radius', config.scrollbar.hoverWidth / 2 + 'px');
});
element.on('mouseleave', function() {
element.css('background', 'none');
scrollbar.css('width', config.scrollbar.width + 'px');
scrollbar.css('right', scrollbarMargin + 'px');
scrollbar.css('border-radius', config.scrollbar.width / 2 + 'px');
});
var scrollbarMousedown = false,
axisY,
mouseInElement = false;
if (!config.show) {
containerElement.on('mouseenter', function() {
mouseInElement = true;
showScrollbar();
});
containerElement.on('mouseleave', function() {
mouseInElement = false;
if (scrollbarMousedown) {
return;
}
hideScrollbar();
});
}
scrollbar.on('mousedown', function(event) {
event.preventDefault();
axisY = event.screenY;
scrollbarMousedown = true;
docEl.one('mouseup', function() {
scrollbarMousedown = false;
if (!config.show && !mouseInElement) {
hideScrollbar();
}
// docEl.off('mouseup', arguments.callee);
});
});
docEl.on('mousemove', function(event) {
if(scrollbarMousedown) {
event.preventDefault();
scroll(-(event.screenY - axisY) * config.dragSpeed * getContentHeight() / getContainerHeight());
axisY = event.screenY;
}
});
$timeout(function() {
reset();
if (!!document.createStyleSheet) { //if the browser is ie browser
contentElement.on('DOMNodeInserted', reset);
contentElement.on('DOMNodeRemoved', reset);
} else {
var observer = new MutationObserver(function(mutations){
if (mutations.length) {
reset();
}
});
observer.observe(contentElement[0], {childList:true, subtree: true});
}
}, 5);
var scrollToBottom = function() {
var offset = getContainerHeight() - getContentHeight();
scrollTo(offset);
};
ctrl.scrollTo = scrollTo;
ctrl.scrollToBottom = scrollToBottom;
ctrl.getContentHeight = getContentHeight;
ctrl.getContainerHeight = getContainerHeight;
ctrl.getScrollbarHeight = getScrollbarHeight;
ScrollbarDelegate.registerInstance(scope.name, ctrl);
};
}
};
}])
.directive('ngScrollbarX', ['$timeout', function($timeout) {
return {
restrict: 'AE',
replace: true,
require: '^ngScrollbar',
template: '<div class="ngscrollbar-container-x" ng-style="styles.scrollbarContainer"><div class="ngscrollbar-x" ng-style="styles.scrollbar"></div></div>',
compile: function() {
return function(scope, element, attrs, ctrl) {
var config = ctrl.getConfig(),
docEl = angular.element(document),
containerElement = ctrl.getContainerElement(),
containerDom = containerElement[0],
contentElement = ctrl.getContentElement(), //the container of content
scrollbar = angular.element(element[0].querySelector('.ngscrollbar-x')),
scrollbarMargin = ctrl.getScrollbarMargin(),
scrollbarHoverMargin = ctrl.getScrollbarHoverMargin();
scope.styles = {
scrollbarContainer: {
position: 'absolute',
width: '100%',
transition: 'background .3s ease-in-out',
'border-radius': config.scrollbarContainer.width / 2 + 'px'
},
scrollbar: {
position: 'absolute',
cursor: 'default',
opacity: 0,
transition: 'opacity .3s ease-in-out, border-radius .1s linear, width .1s linear, right .1s linear',
background: config.scrollbar.color,
'border-radius': config.scrollbar.width / 2 + 'px'
}
};
element.css('height', config.scrollbarContainer.width + 'px'); // set the scrollbarContainer height;
element.css('bottom', 0); // set scrollbarContainer top
element.css('left', 0); //set scrollbarContainer left
scrollbar.css('top', scrollbarMargin + 'px'); //set scrollbar top
scrollbar.css('height', config.scrollbar.width + 'px');
var getContentWidth = function() {
return contentElement[0].offsetWidth;
};
var getContainerWidth = function() {
return containerDom.offsetWidth;
};
var getScrollbarWidth = function() {
return Math.pow(getContainerWidth(), 2) / getContentWidth() - scrollbarMargin * 2;
};
var showScrollbar = function() {
scrollbar.css('opacity', 1);
};
var hideScrollbar = function() {
scrollbar.css('opacity', 0);
};
var isOverflow = function() {
return getContentWidth() > getContainerWidth();
};
var reset = function() {
var oldMarginLeft = parseInt(contentElement.css('margin-left'), 10);
contentElement.css('margin-left', '0px');
if (isOverflow()) {
element.css('display', 'block');
scrollbar.css('width', getScrollbarWidth() + 'px');
scrollTo(oldMarginLeft);
if (config.show) {
showScrollbar();
}
} else {
element.css('display', 'none');
}
};
var scrollTo = function(left) {
left = Math.min(0, Math.max(left, getContainerWidth() - getContentWidth()));
contentElement.css('margin-left', left + 'px');
scrollbar.css('left', -left/getContentWidth()*getContainerWidth() + scrollbarMargin + 'px');
};
var scroll = function(distance) {
var left = parseInt(contentElement.css('margin-left'), 10) + distance;
scrollTo(left);
};
element.on('mouseenter', function() {
element.css('background', config.scrollbarContainer.color);
scrollbar.css('height', config.scrollbar.hoverWidth + 'px');
scrollbar.css('top', scrollbarHoverMargin + 'px');
scrollbar.css('border-radius', config.scrollbar.hoverWidth / 2 + 'px');
});
element.on('mouseleave', function() {
element.css('background', 'none');
scrollbar.css('height', config.scrollbar.width + 'px');
scrollbar.css('top', scrollbarMargin + 'px');
scrollbar.css('border-radius', config.scrollbar.width / 2 + 'px');
});
var scrollbarMousedown = false,
axisX,
mouseInElement = false;
if (!config.show) {
containerElement.on('mouseenter', function() {
mouseInElement = true;
showScrollbar();
});
containerElement.on('mouseleave', function() {
mouseInElement = false;
if (scrollbarMousedown) {
return;
}
hideScrollbar();
});
}
scrollbar.on('mousedown', function(event) {
event.preventDefault();
scrollbarMousedown = true;
axisX = event.screenX;
docEl.one('mouseup', function() {
scrollbarMousedown = false;
if (!config.show && !mouseInElement) {
hideScrollbar();
}
// docEl.off('mouseup', arguments.callee);
});
});
docEl.on('mousemove', function(event) {
if(scrollbarMousedown) {
event.preventDefault();
scroll(-(event.screenX - axisX) * config.dragSpeed * getContentWidth() / getContainerWidth());
axisX = event.screenX;
}
});
$timeout(function() {
reset();
if (!!document.createStyleSheet) { //if the browser is ie browser
contentElement.on('DOMNodeInserted', reset);
contentElement.on('DOMNodeRemoved', reset);
} else {
var observer = new MutationObserver(function(mutations){
if (mutations.length) {
reset();
}
});
observer.observe(contentElement[0], {childList:true, subtree: true});
}
}, 5);
};
}
};
}]);
I added this code:
name: '#',
var scrollToBottom = function() {
var offset = getContainerHeight() - getContentHeight();
scrollTo(offset);
};
ctrl.scrollTo = scrollTo;
ctrl.scrollToBottom = scrollToBottom;
ctrl.getContentHeight = getContentHeight;
ctrl.getContainerHeight = getContainerHeight;
ctrl.getScrollbarHeight = getScrollbarHeight;
ScrollbarDelegateService.registerInstance(scope.name, ctrl);
ScrollbarDelegateService - is an angular service through which controls all the scrollbars.
let ScrollbarDelegateService = function () {
let instances = {};
let getInstances = () => {
return instances;
};
let registerInstance = (name, ctrl) => {
instances[name || ''] = ctrl;
};
let deregisterInstance = (name) => {
delete instances[name || ''];
};
let instanceByName = (name) => {
let instance;
if (!(instance = instances[name || ''])) {
return undefined;
}
return instance;
};
return { getInstances, registerInstance, deregisterInstance, instanceByName };
};
export default ScrollbarDelegateService;
And last, to control the scrolling:
In template:
<section ng-scrollbar name="orders" scrollbar-x="false" scrollbar-y="true" scrollbar-config="vm.scrollbarConfig" class="tab-content-inner">
In controller:
let scrollbar = ScrollbarDelegateService.instanceByName('orders');
if (scrollbar !== undefined) {
scrollbar.scrollToBottom();
}

Related

Transforming img - white dots appear on chronium

I am trying to get 3d transform effect of the bacground image on mouse move.
I have checked f.e. jquery.plate tilt.js and many others plugins, BUT, each of them has problem on chronium browsers like Chrome or Opera (it works fine even on IE11 -.-)
See the attachment and please adwise what is that and if it is fixable? The "dots" appear on mouse move (when background moves) randomly but in line within image.
(function($) {
'use strict';
var namespace = 'jquery-plate';
function Plate($element, options) {
this.config(options);
this.$container = $element;
if (this.options.element) {
if (typeof this.options.element === 'string') {
this.$element = this.$container.find(this.options.element);
} else {
this.$element = $(this.options.element);
}
} else {
this.$element = $element;
}
this.originalTransform = this.$element.css('transform');
this.$container
.on('mouseenter.' + namespace, this.onMouseEnter.bind(this))
.on('mouseleave.' + namespace, this.onMouseLeave.bind(this))
.on('mousemove.' + namespace, this.onMouseMove.bind(this));
}
Plate.prototype.config = function(options) {
this.options = $.extend({
inverse: false,
perspective: 500,
maxRotation: 10,
animationDuration: 200
}, this.options, options);
};
Plate.prototype.destroy = function() {
this.$element.css('transform', this.originalTransform);
this.$container.off('.' + namespace);
};
Plate.prototype.update = function(offsetX, offsetY, duration) {
var rotateX;
var rotateY;
if (offsetX || offsetX === 0) {
var height = this.$container.outerHeight();
var py = (offsetY - height / 2) / (height / 2);
rotateX = this.round(this.options.maxRotation * -py);
} else {
rotateY = 0;
}
if (offsetY || offsetY === 0) {
var width = this.$container.outerWidth();
var px = (offsetX - width / 2) / (width / 2);
rotateY = this.round(this.options.maxRotation * px);
} else {
rotateX = 0;
}
if (this.options.inverse) {
rotateX *= -1;
rotateY *= -1;
}
if (duration) {
this.animate(rotateX, rotateY, duration);
} else if (this.animation && this.animation.remaining) {
this.animation.targetX = rotateX;
this.animation.targetY = rotateY;
} else {
this.transform(rotateX, rotateY);
}
};
Plate.prototype.reset = function(duration) {
this.update(null, null, duration);
};
Plate.prototype.transform = function(rotateX, rotateY) {
this.currentX = rotateX;
this.currentY = rotateY;
this.$element.css('transform',
(this.originalTransform && this.originalTransform !== 'none' ? this.originalTransform + ' ' : '') +
'perspective(' + this.options.perspective + 'px) ' +
'rotateX(' + rotateX + 'deg) rotateY(' + rotateY + 'deg)'
);
};
Plate.prototype.animate = function(rotateX, rotateY, duration) {
if (duration) {
this.animation = this.animation || {};
var remaining = this.animation.remaining;
this.animation.time = performance.now();
this.animation.remaining = duration || null;
this.animation.targetX = rotateX;
this.animation.targetY = rotateY;
if (!remaining) {
requestAnimationFrame(this.onAnimationFrame.bind(this));
}
} else {
this.transform(rotateX, rotateY);
}
};
Plate.prototype.round = function(number) {
return Math.round(number * 1000) / 1000;
};
Plate.prototype.offsetCoords = function(event) {
var offset = this.$container.offset();
return {
x: event.pageX - offset.left,
y: event.pageY - offset.top
};
};
Plate.prototype.onAnimationFrame = function(timestamp) {
this.animation = this.animation || {};
var delta = timestamp - (this.animation.time || 0);
this.animation.time = timestamp;
var duration = this.animation.remaining || 0;
var percent = Math.min(delta / duration, 1);
var currentX = this.currentX || 0;
var currentY = this.currentY || 0;
var targetX = this.animation.targetX || 0;
var targetY = this.animation.targetY || 0;
var rotateX = this.round(currentX + (targetX - currentX) * percent);
var rotateY = this.round(currentY + (targetY - currentY) * percent);
this.transform(rotateX, rotateY);
var remaining = duration - delta;
this.animation.remaining = remaining > 0 ? remaining : null;
if (remaining > 0) {
requestAnimationFrame(this.onAnimationFrame.bind(this));
}
};
Plate.prototype.onMouseEnter = function(event) {
var offset = this.offsetCoords(event);
this.update(offset.x, offset.y, this.options.animationDuration);
};
Plate.prototype.onMouseLeave = function(event) {
this.reset(this.options.animationDuration);
};
Plate.prototype.onMouseMove = function(event) {
var offset = this.offsetCoords(event);
this.update(offset.x, offset.y);
};
$.fn.plate = function(options) {
return this.each(function() {
var $element = $(this);
var plate = $element.data(namespace);
if (options === 'remove') {
plate.destroy();
$element.data(namespace, null);
} else {
if (!plate) {
plate = new Plate($element, options);
$element.data(namespace, plate);
plate.reset();
} else {
plate.config(options);
}
}
});
};
})(jQuery);
$('#ab12cd').plate()
<div id="ab12cd" styles="width:100%;height:100%">
<img src="http://eskipaper.com/images/dark-background-8.jpg" />
</div>
<script
src="https://code.jquery.com/jquery-3.2.1.min.js"
integrity="sha256-hwg4gsxgFZhOsEEamdOYGBf13FyQuiTwlAQgxVSNgt4="
crossorigin="anonymous"></script>
// please open in new window, most visible effect you cen see if you move mouse bottom left/right

How do you make JQuery WebTicket full-screen width?

Basically, the webticket only goes to about a little over 2/5ths of the screen, I'm trying to figure out how I can stretch the width out so that it covers the entire screen's width.
Fiddle: http://fiddle.jshell.net/Wf43X/56/light/
Javascript:
/*!
* webTicker 1.3
* Examples and documentation at:
* http://jonmifsud.com
* 2011 Jonathan Mifsud
* Version: 1.2 (26-JUNE-2011)
* Dual licensed under the MIT and GPL licenses:
* http://www.opensource.org/licenses/mit-license.php
* http://www.gnu.org/licenses/gpl.html
* Requires:
* jQuery v1.4.2 or later
*
*/
(function($) {
var globalSettings = new Array();
var methods = {
init: function(settings) { // THIS
settings = jQuery.extend({
travelocity: 0.05,
direction: 1,
moving: true
}, settings);
globalSettings[jQuery(this).attr('id')] = settings;
return this.each(function() {
var $strip = jQuery(this);
$strip.addClass("newsticker")
var stripWidth = 0;
var $mask = $strip.wrap("<div class='mask'></div>");
$mask.after("<span class='tickeroverlay-left'> </span><span class='tickeroverlay-right'> </span>")
var $tickercontainer = $strip.parent().wrap("<div class='tickercontainer'></div>");
$strip.find("li").each(function(i) {
stripWidth += jQuery(this, i).outerWidth(true);
});
$strip.width(stripWidth + 200); //20 used for ie9 fix
function scrollnews(spazio, tempo) {
if (settings.direction == 1) $strip.animate({
left: '-=' + spazio
}, tempo, "linear", function() {
$strip.children().last().after($strip.children().first());
var first = $strip.children().first();
var width = first.outerWidth(true);
var defTiming = width / settings.travelocity;
//$strip.css("left", left);
$strip.css("left", '0');
scrollnews(width, defTiming);
});
else $strip.animate({
right: '-=' + spazio
}, tempo, "linear", function() {
$strip.children().last().after($strip.children().first());
var first = $strip.children().first();
var width = first.outerWidth(true);
var defTiming = width / settings.travelocity;
//$strip.css("left", left);
$strip.css("right", '0');
scrollnews(width, defTiming);
});
}
var first = $strip.children().first();
var travel = first.outerWidth(true);
var timing = travel / settings.travelocity;
scrollnews(travel, timing);
$strip.hover(function() {
jQuery(this).stop();
}, function() {
if (globalSettings[jQuery(this).attr('id')].moving) {
var offset = jQuery(this).offset();
var first = $strip.children().first();
var width = first.outerWidth(true);
var residualSpace;
if (settings.direction == 1) residualSpace = parseInt(jQuery(this).css('left').replace('px', '')) + width;
else residualSpace = parseInt(jQuery(this).css('right').replace('px', '')) + width;
var residualTime = residualSpace / settings.travelocity;
scrollnews(residualSpace, residualTime);
}
});
});
},
stop: function() {
if (globalSettings[jQuery(this).attr('id')].moving) {
globalSettings[jQuery(this).attr('id')].moving = false;
return this.each(function() {
jQuery(this).stop();
});
}
},
cont: function() { // GOOD
if (!(globalSettings[jQuery(this).attr('id')].moving)) {
globalSettings[jQuery(this).attr('id')].moving = true;
var settings = globalSettings[jQuery(this).attr('id')];
return this.each(function() {
var $strip = jQuery(this);
function scrollnews(spazio, tempo) {
if (settings.direction == 1) $strip.animate({
left: '-=' + spazio
}, tempo, "linear", function() {
$strip.children().last().after($strip.children().first());
var first = $strip.children().first();
var width = first.outerWidth(true);
var defTiming = width / settings.travelocity;
//$strip.css("left", left);
$strip.css("left", '0');
scrollnews(width, defTiming);
});
else $strip.animate({
right: '-=' + spazio
}, tempo, "linear", function() {
$strip.children().last().after($strip.children().first());
var first = $strip.children().first();
var width = first.outerWidth(true);
var defTiming = width / settings.travelocity;
//$strip.css("left", left);
$strip.css("right", '0');
scrollnews(width, defTiming);
});
}
var offset = jQuery(this).offset();
var first = $strip.children().first();
var width = first.outerWidth(true);
var residualSpace;
if (settings.direction == 1) residualSpace = parseInt(jQuery(this).css('left').replace('px', '')) + width;
else residualSpace = parseInt(jQuery(this).css('right').replace('px', '')) + width;
var residualTime = residualSpace / settings.travelocity;
scrollnews(residualSpace, residualTime);
});
}
}
};
$.fn.webTicker = function(method) {
// Method calling logic
if (methods[method]) {
return methods[method].apply(this, Array.prototype.slice.call(arguments, 1));
} else if (typeof method === 'object' || !method) {
return methods.init.apply(this, arguments);
} else {
$.error('Method ' + method + ' does not exist on jQuery.webTicker');
}
};
})(jQuery);
jQuery('#webticker').webTicker()
CSS:
.tickercontainer { /* the outer div with the black border */
width: 500px;
height: 27px;
margin: 0;
padding: 0;
overflow: hidden;
}
.tickercontainer .mask { /* that serves as a mask. so you get a sort of padding both left and right */
position: relative;
top: 8px;
height: 18px;
/*width: 718px;*/
overflow: hidden;
}
ul.newsticker { /* that's your list */
position: relative;
/*left: 750px;*/
font: bold 10px Verdana;
list-style-type: none;
margin: 0;
padding: 0;
}
ul.newsticker li {
float: left; /* important: display inline gives incorrect results when you check for elem's width */
margin: 0;
padding-right: 15px;
/*background: #fff;*/
}
Thanks,
Dan

Jquery word for word fade in effect

ive been looking in about for this exact script for a while and i cant get it to work. Im looking to use a fade in effect from left to right word by word.
For example
<div class="box5">
<h1>Lorem ipsum dolor sit amet, ne mel vero impetus voluptatibus
</h1>
</div>
I want this to fade in then enough line to fade in word by word slightly later using a delay.
My current fade in works but it does it by the full container it looks like this
.reveal {
position: relative;
overflow: hidden;
}
/*initial - hidden*/
.reveal .reveal__cover {
position: absolute;
top: 0;
left: -250px;
height: 100%;
margin: 2px;
width: calc(100% + 250px);
}
.reveal .reveal__cover.reveal__uncovered {
position: absolute;
top: 0;
left: 100%;
height: 100%;
width: calc(100% + 250px);
margin: 2px;
transition: left 2500ms ease-out 0ms;
}
.reveal__cover-section {
height: 100%;
float: right;
/* NOTE: Background must match existing background */
/*background: #000;*/
background: #fff;
width: 2%;
}
.reveal__10 {
opacity: 0.1;
}
.reveal__20 {
opacity: 0.2;
}
.reveal__30 {
opacity: 0.3;
}
.reveal__40 {
opacity: 0.4;
}
.reveal__50 {
opacity: 0.5;
}
.reveal__60 {
opacity: 0.6;
}
.reveal__70 {
opacity: 0.7;
}
.reveal__80 {
opacity: 0.8;
}
.reveal__90 {
opacity: 0.9;
}
.reveal__100 {
opacity: 1;
width: 82%;
}
Then JS
function replaceAllInstances(source, search, replacement) {
var regex = new RegExp(search, "g");
var result = source.replace(regex, replacement);
return result;
}
$.fn.isOnScreen = function (x, y) {
if (x == null || typeof x == 'undefined')
x = 1;
if (y == null || typeof y == 'undefined')
y = 1;
var win = $(window);
var viewport = {
top: win.scrollTop(),
left: win.scrollLeft()
};
viewport.right = viewport.left + win.width();
viewport.bottom = viewport.top + win.height();
var height = this.outerHeight();
var width = this.outerWidth();
if (!width || !height) {
return false;
}
var bounds = this.offset();
bounds.right = bounds.left + width;
bounds.bottom = bounds.top + height;
var visible = (!(viewport.right < bounds.left || viewport.left > bounds.right || viewport.bottom < bounds.top || viewport.top > bounds.bottom));
if (!visible) {
return false;
}
var deltas = {
top: Math.min(1, (bounds.bottom - viewport.top) / height),
bottom: Math.min(1, (viewport.bottom - bounds.top) / height),
left: Math.min(1, (bounds.right - viewport.left) / width),
right: Math.min(1, (viewport.right - bounds.left) / width)
};
return (deltas.left * deltas.right) >= x && (deltas.top * deltas.bottom) >= y;
};
/*
* Init specified element so it can be gradually revealed.
*
* Limitations:
* Only works on backgrounds with a solid color.
*
* #param options = {
* id:'box3'
* ,background='#ffffff' //default
* ,delay='0' //default
* }
*
*/
$.fn.initReveal = function (options) {
console.log('-------------');
console.log('selector:' + this.selector);
var parent = $(this).parent();
//grab a copy of the contents, then remove it from DOM
var contents = $(this).clone();
$(this).empty();
var revealHtmlBlock = "<div class='reveal'> <div class='text reveal__inner reveal__inner-{class}'> </div> <div class='reveal__cover reveal__cover-{class}'> <div class='reveal__cover-section reveal__100'></div> <div class='reveal__cover-section reveal__90'></div> <div class='reveal__cover-section reveal__80'></div> <div class='reveal__cover-section reveal__70'></div> <div class='reveal__cover-section reveal__60'></div> <div class='reveal__cover-section reveal__50'></div> <div class='reveal__cover-section reveal__40'></div> <div class='reveal__cover-section reveal__30'></div> <div class='reveal__cover-section reveal__20'></div> <div class='reveal__cover-section reveal__10'></div> </div> </div>";
revealHtmlBlock = replaceAllInstances(revealHtmlBlock, "{class}", options.id);
$(revealHtmlBlock).appendTo(parent);
contents.appendTo($('.reveal__inner-' + options.id));
//handle options
//delay
if (options.delay === undefined) {
console.log('delay set to 0');
options.delay = 0; //set default
} else {
console.log('delay set to:' + options.delay);
}
var revealElementFunction = function (options) {
$(this).performReveal(options);
};
//background
if (options.background !== undefined) {
$('.reveal__cover-' + options.id + ' .reveal__cover-section').css({'background-color': options.background});
}
//trigger the reveal at the specified time, unless auto is present and set to false
if (options.auto === undefined || (options.auto !== undefined && options.auto)) {
setTimeout(function () {
console.log('call');
revealElementFunction(options);
}, options.delay);
}
//trigger on-visible
if (options.trigger !== undefined) {
var revealOnScreenIntervalIdMap = {};
function uncoverText() {
var onscreen = $('.reveal__inner-box4').isOnScreen();
if ($('.reveal__inner-' + options.id).isOnScreen()) {
$('.reveal__cover-' + options.id).addClass('reveal__uncovered');
revealOnScreenIntervalIdMap[options.id] = window.clearInterval(revealOnScreenIntervalIdMap[options.id]);
}
}
function showTextWhenVisible() {
revealOnScreenIntervalIdMap[options.id] = setInterval(uncoverText, 800);
}
showTextWhenVisible();
}
};
//--------------------
/*
* trigger options:
* immediately (on page load)
* on event, eg. onclick
* on becoming visible, after it scrolls into view, or is displayed after bein ghidden
*
* #param options = {
* id:'box3'
* }
*
*/
$.fn.performReveal = function (options) {
var _performReveal = function () {
$('.reveal__cover-' + options.id).addClass('reveal__uncovered');
};
//allow time for init code to complete
setTimeout(_performReveal, 250);
};
Main JS
jQuery(function () {
//Box 1: reveal immediately - on page load
//NOTE: id does refer to an element id, It is used to
// uniquely refer to the element to be revealed.
var options1 = {
id: 'box1',
background: '#008d35'
};
$('.box1').initReveal(options1);
//------------------------
//Box 2: reveal after specified delay
var options2 = {
id: 'box2'
, delay: 3000
, background: '#008d35'
};
$('.box2').initReveal(options2);
//------------------------
//Box 3: reveal on event - eg. onclick
var options3 = {
id: 'box3'
, auto: false
};
var box3 = $('.box3');
box3.initReveal(options3);
$('.btn-reveal').on('click', function () {
box3.performReveal(options3);
});
//------------------------
//Box 4: Reveal when element scrolls into the viewport
var options4 = {
id: 'box4'
, auto: false
, trigger: 'on-visible'
};
$('.box4').initReveal(options4);
});
//------------------------
//Box 5 reveal
var options5 = {
id: 'box5'
, delay: 2500 ,
background: '#008d35'
};
$('.box5').initReveal(options5);
does anyone have any idea how to make it work word by word and not line by line
Here's a simple approach that you can build on. It creates the needed spans and fades them in based on interval value you set.
var fadeInterval = 300
$('h1').html(function(_, txt){
var words= $.trim(txt).split(' ');
return '<span>' + words.join('</span> <span>') + '</span>';
}).find('span').each(function(idx, elem){
$(elem).delay(idx * fadeInterval).fadeIn();
});
DEMO

Cloudzoom and woocommerce attributes

I cannot get cloudzoom to work with my woocommerce site, every time I choose an attribute ie size the main image disappears, it is like cloudzoom is trying to force an attribute image. I am absolutely pants at javascript and looking through the file I cannot see where I need to edit or delete the code. Any help would be greatly appreciated, I don't need the atribute image function to work at all so just stripping out the code would suit me. Here is the code...
(function ($) {
$(document).ready(function () {
$('.cloud-zoom, .cloud-zoom-gallery').CloudZoom();
});
function format(str) {
for (var i = 1; i < arguments.length; i++) {
str = str.replace('%' + (i - 1), arguments[i]);
}
return str;
}
function CloudZoom(jWin, opts) {
var sImg = $('img', jWin);
var img1;
var img2;
var zoomDiv = null;
var $mouseTrap = null;
var lens = null;
var $tint = null;
var softFocus = null;
var $ie6Fix = null;
var zoomImage;
var controlTimer = 0;
var cw, ch;
var destU = 0;
var destV = 0;
var currV = 0;
var currU = 0;
var filesLoaded = 0;
var mx,
my;
var ctx = this, zw;
// Display an image loading message. This message gets deleted when the images have loaded and the zoom init function is called.
// We add a small delay before the message is displayed to avoid the message flicking on then off again virtually immediately if the
// images load really fast, e.g. from the cache.
//var ctx = this;
setTimeout(function () {
// <img src="/images/loading.gif"/>
if ($mouseTrap === null) {
var w = jWin.width();
jWin.parent().append(format('<div style="width:%0px;position:absolute;top:75%;left:%1px;text-align:center" class="cloud-zoom-loading" >Loading...</div>', w / 3, (w / 2) - (w / 6))).find(':last').css('opacity', 0.5);
}
}, 200);
var ie6FixRemove = function () {
if ($ie6Fix !== null) {
$ie6Fix.remove();
$ie6Fix = null;
}
};
// Removes cursor, tint layer, blur layer etc.
this.removeBits = function () {
//$mouseTrap.unbind();
if (lens) {
lens.remove();
lens = null;
}
if ($tint) {
$tint.remove();
$tint = null;
}
if (softFocus) {
softFocus.remove();
softFocus = null;
}
ie6FixRemove();
$('.cloud-zoom-loading', jWin.parent()).remove();
};
this.destroy = function () {
jWin.data('zoom', null);
if ($mouseTrap) {
$mouseTrap.unbind();
$mouseTrap.remove();
$mouseTrap = null;
}
if (zoomDiv) {
zoomDiv.remove();
zoomDiv = null;
}
//ie6FixRemove();
this.removeBits();
// DON'T FORGET TO REMOVE JQUERY 'DATA' VALUES
};
// This is called when the zoom window has faded out so it can be removed.
this.fadedOut = function () {
if (zoomDiv) {
zoomDiv.remove();
zoomDiv = null;
}
this.removeBits();
//ie6FixRemove();
};
this.controlLoop = function () {
if (lens) {
var x = (mx - sImg.offset().left - (cw * 0.5)) >> 0;
var y = (my - sImg.offset().top - (ch * 0.5)) >> 0;
if (x < 0) {
x = 0;
}
else if (x > (sImg.outerWidth() - cw)) {
x = (sImg.outerWidth() - cw);
}
if (y < 0) {
y = 0;
}
else if (y > (sImg.outerHeight() - ch)) {
y = (sImg.outerHeight() - ch);
}
lens.css({
left: x,
top: y
});
lens.css('background-position', (-x) + 'px ' + (-y) + 'px');
destU = (((x) / sImg.outerWidth()) * zoomImage.width) >> 0;
destV = (((y) / sImg.outerHeight()) * zoomImage.height) >> 0;
currU += (destU - currU) / opts.smoothMove;
currV += (destV - currV) / opts.smoothMove;
zoomDiv.css('background-position', (-(currU >> 0) + 'px ') + (-(currV >> 0) + 'px'));
}
controlTimer = setTimeout(function () {
ctx.controlLoop();
}, 30);
};
this.init2 = function (img, id) {
filesLoaded++;
//console.log(img.src + ' ' + id + ' ' + img.width);
if (id === 1) {
zoomImage = img;
}
//this.images[id] = img;
if (filesLoaded === 2) {
this.init();
}
};
/* Init function start. */
this.init = function () {
// Remove loading message (if present);
$('.cloud-zoom-loading', jWin.parent()).remove();
/* Add a box (mouseTrap) over the small image to trap mouse events.
It has priority over zoom window to avoid issues with inner zoom.
We need the dummy background image as IE does not trap mouse events on
transparent parts of a div.
*/
$mouseTrap = jWin.parent().append(format("<div class='mousetrap' style='background-image:url(\".\");z-index:3;position:absolute;width:%0px;height:%1px;left:%2px;top:%3px;\'></div>", sImg.outerWidth(), sImg.outerHeight(), 0, 0)).find(':last');
//////////////////////////////////////////////////////////////////////
/* Do as little as possible in mousemove event to prevent slowdown. */
$mouseTrap.bind('mousemove', this, function (event) {
// Just update the mouse position
mx = event.pageX;
my = event.pageY;
});
//////////////////////////////////////////////////////////////////////
$mouseTrap.bind('mouseleave', this, function (event) {
clearTimeout(controlTimer);
//event.data.removeBits();
if(lens) { lens.fadeOut(299); }
if($tint) { $tint.fadeOut(299); }
if(softFocus) { softFocus.fadeOut(299); }
zoomDiv.fadeOut(300, function () {
ctx.fadedOut();
});
return false;
});
//////////////////////////////////////////////////////////////////////
$mouseTrap.bind('mouseenter', this, function (event) {
mx = event.pageX;
my = event.pageY;
zw = event.data;
if (zoomDiv) {
zoomDiv.stop(true, false);
zoomDiv.remove();
}
var xPos = opts.adjustX,
yPos = opts.adjustY;
var siw = sImg.outerWidth();
var sih = sImg.outerHeight();
var w = opts.zoomWidth;
var h = opts.zoomHeight;
if (opts.zoomWidth == 'auto') {
w = siw;
}
if (opts.zoomHeight == 'auto') {
h = sih;
}
//$('#info').text( xPos + ' ' + yPos + ' ' + siw + ' ' + sih );
var appendTo = jWin.parent(); // attach to the wrapper
switch (opts.position) {
case 'top':
yPos -= h; // + opts.adjustY;
break;
case 'right':
xPos += siw; // + opts.adjustX;
break;
case 'bottom':
yPos += sih; // + opts.adjustY;
break;
case 'left':
xPos -= w; // + opts.adjustX;
break;
case 'inside':
w = siw;
h = sih;
break;
// All other values, try and find an id in the dom to attach to.
default:
appendTo = $('#' + opts.position);
// If dom element doesn't exit, just use 'right' position as default.
if (!appendTo.length) {
appendTo = jWin;
xPos += siw; //+ opts.adjustX;
yPos += sih; // + opts.adjustY;
} else {
w = appendTo.innerWidth();
h = appendTo.innerHeight();
}
}
zoomDiv = appendTo.append(format('<div id="cloud-zoom-big" class="cloud-zoom-big" style="display:none;position:absolute;left:%0px;top:%1px;width:%2px;height:%3px;background-image:url(\'%4\');z-index:2;"></div>', xPos, yPos, w, h, zoomImage.src)).find(':last');
// Add the title from title tag.
if (sImg.attr('title') && opts.showTitle) {
zoomDiv.append(format('<div class="cloud-zoom-title">%0</div>', sImg.attr('title'))).find(':last').css('opacity', opts.titleOpacity);
}
// Fix ie6 select elements wrong z-index bug. Placing an iFrame over the select element solves the issue...
if ($.browser.msie && $.browser.version < 7) {
$ie6Fix = $('<iframe frameborder="0" src="#"></iframe>').css({
position: "absolute",
left: xPos,
top: yPos,
zIndex: 99,
width: w,
height: h
}).insertBefore(zoomDiv);
}
zoomDiv.fadeIn(500);
if (lens) {
lens.remove();
lens = null;
} /* Work out size of cursor */
cw = (sImg.outerWidth() / zoomImage.width) * zoomDiv.width();
ch = (sImg.outerHeight() / zoomImage.height) * zoomDiv.height();
// Attach mouse, initially invisible to prevent first frame glitch
lens = jWin.append(format("<div class = 'cloud-zoom-lens' style='display:none;z-index:1;position:absolute;width:%0px;height:%1px;opacity:0.4'></div>", cw, ch)).find(':last');
$mouseTrap.css('cursor', lens.css('cursor'));
var noTrans = false;
// Init tint layer if needed. (Not relevant if using inside mode)
if (opts.tint) {
/* lens.css('background', 'url("' + sImg.attr('src') + '")'); */
$tint = jWin.append(format('<div style="display:none;position:absolute; left:0px; top:0px; width:%0px; height:%1px; background-color:%2;" />', sImg.outerWidth(), sImg.outerHeight(), opts.tint)).find(':last');
$tint.css('opacity', opts.tintOpacity);
noTrans = true;
$tint.fadeIn(500);
}
if (opts.softFocus) {
lens.css('background', 'url("' + sImg.attr('src') + '")');
softFocus = jWin.append(format('<div style="position:absolute;display:none;top:2px; left:2px; width:%0px; height:%1px;" />', sImg.outerWidth() - 2, sImg.outerHeight() - 2, opts.tint)).find(':last');
softFocus.css('background', 'url("' + sImg.attr('src') + '")');
softFocus.css('opacity', 0.5);
noTrans = true;
softFocus.fadeIn(500);
}
if (!noTrans) {
lens.css('opacity', opts.lensOpacity);
}
if ( opts.position !== 'inside' ) { lens.fadeIn(500); }
// Start processing.
zw.controlLoop();
return; // Don't return false here otherwise opera will not detect change of the mouse pointer type.
});
};
img1 = new Image();
$(img1).load(function () {
ctx.init2(this, 0);
});
img1.src = sImg.attr('src');
img2 = new Image();
$(img2).load(function () {
ctx.init2(this, 1);
});
img2.src = jWin.attr('href');
}
$.fn.CloudZoom = function (options) {
// IE6 background image flicker fix
try {
document.execCommand("BackgroundImageCache", false, true);
} catch (e) {}
this.each(function () {
var relOpts, opts;
// Hmm...eval...slap on wrist.
eval('var a = {' + $(this).attr('rel') + '}');
relOpts = a;
if ($(this).is('.cloud-zoom')) {
$(this).css({
'position': 'relative',
'display': 'block'
});
$('img', $(this)).css({
'display': 'block'
});
// Wrap an outer div around the link so we can attach things without them becoming part of the link.
// But not if wrap already exists.
if ($(this).parent().attr('id') != 'wrap') {
$(this).wrap('<div id="wrap" style="top:0px;z-index:4;position:relative;"></div>');
}
opts = $.extend({}, $.fn.CloudZoom.defaults, options);
opts = $.extend({}, opts, relOpts);
$(this).data('zoom', new CloudZoom($(this), opts));
} else if ($(this).is('.cloud-zoom-gallery')) {
opts = $.extend({}, relOpts, options);
$(this).data('relOpts', opts);
$(this).bind('click', $(this), function (event) {
var data = event.data.data('relOpts');
// Destroy the previous zoom
$('#' + data.useZoom).data('zoom').destroy();
// Change the biglink to point to the new big image.
$('#' + data.useZoom).attr('href', event.data.attr('href'));
// Change the small image to point to the new small image.
$('#' + data.useZoom + ' img').attr('src', event.data.data('relOpts').smallImage);
// Init a new zoom with the new images.
$('#zoom-cb').attr('href', event.data.attr('href'));
$('#' + event.data.data('relOpts').useZoom).CloudZoom();
return false;
});
}
});
return this;
};
$.fn.CloudZoom.defaults = {
zoomWidth: 'auto',
zoomHeight: 'auto',
position: 'right',
tint: false,
tintOpacity: 0.5,
lensOpacity: 0.5,
softFocus: false,
smoothMove: 3,
showTitle: false,
titleOpacity: 0.5,
adjustX: 0,
adjustY: 0
};
})(jQuery);

How to make my script affects only it's own image in jquery?

i'm trying to implement SpaceGallery script. WWW: http://www.eyecon.ro/spacegallery/. It takes the images from #div and make the slide like on online demo.
Part of my HTML file:
<div id="myGallery0" class="spacegallery">
<img class="imaz" src="ADDITIONAL.jpg" alt="" atr1="lupa" />
<img class="aaa" src=images/bw1.jpg alt="" atr1="bw1" />
<img class="aaa" src=images/bw2.jpg alt="" atr1="bw2" />
<img class="aaa" src=images/bw3.jpg alt="" atr1="bw3" />
</div>
<div id="myGallery1" class="spacegallery">
<img class="imaz" src="ADDITIONAL.jpg" alt="" atr1="lupa" />
<img class="aaa" src=images3/bw1.jpg alt="" atr1="bw1" />
<img class="aaa" src=images3/bw2.jpg alt="" atr1="bw2" />
<img class="aaa" src=images3/lights2.jpg alt="" atr1="bw3" />
</div>
<script>
var initLayout = function() {
$('#myGallery0').spacegallery({loadingClass: 'loading'});
$('#myGallery1').spacegallery({loadingClass: 'loading'});
};
EYE.register(initLayout, 'init');
</script>
And now, the script works good when I'm calling $('img.aaa')! The script slides only images from it's own ID (mygallery0 or mygallery1). Let's say I have the following .onclick thing in my main .js file.
$('img.imaz').fadeOut();
And when i'm sliding the images in one of my galleries (mygaller0 or mygallery1), the img "ADDITIONAL.jpg" (it's class = imaz) fadeOuts in all of my galleries! Why is that? How to fix it?
Spacegallery.js
(function($){
EYE.extend({
spacegallery: {
//default options (many options are controled via CSS)
defaults: {
border: 6, // border arround the image
perspective: 100, // perpective height
minScale: 0.1, // minimum scale for the image in the back
duration: 800, // aimation duration
loadingClass: null, // CSS class applied to the element while looading images
before: function(){
$('img.imaz').fadeOut();
return false
},
after: function(el){
$('img.imaz').fadeIn();
return false
}
},
animated: false,
//position images
positionImages: function(el) {
var top = 0;
EYE.spacegallery.animated = false;
$(el)
.find('a')
.removeClass(el.spacegalleryCfg.loadingClass)
.end()
.find('img.aaa')
.each(function(nr){
console.log('WYSOKOSC ' + $(this).attr('height'));
var newWidth = this.spacegallery.origWidth - (this.spacegallery.origWidth - this.spacegallery.origWidth * el.spacegalleryCfg.minScale) * el.spacegalleryCfg.asins[nr];
$(this)
.css({
top: el.spacegalleryCfg.tops[nr] + 'px',
marginLeft: - parseInt((newWidth + el.spacegalleryCfg.border)/2, 10) + 'px',
opacity: 1 - el.spacegalleryCfg.asins[nr]
})
.attr('width', parseInt(newWidth));
this.spacegallery.next = el.spacegalleryCfg.asins[nr+1];
this.spacegallery.nextTop = el.spacegalleryCfg.tops[nr+1] - el.spacegalleryCfg.tops[nr];
this.spacegallery.origTop = el.spacegalleryCfg.tops[nr];
this.spacegallery.opacity = 1 - el.spacegalleryCfg.asins[nr];
this.spacegallery.increment = el.spacegalleryCfg.asins[nr] - this.spacegallery.next;
this.spacegallery.current = el.spacegalleryCfg.asins[nr];
this.spacegallery.width = newWidth;
})
},
//animate to nex image
next: function(e) {
if (EYE.spacegallery.animated === false) {
EYE.spacegallery.animated = true;
var el = this.parentNode;
el.spacegalleryCfg.before.apply(el);
$(el)
.css('spacegallery', 0)
.animate({
spacegallery: 100
},{
easing: 'easeOut',
duration: el.spacegalleryCfg.duration,
complete: function() {
$(el)
.find('img.aaa:last')
.prependTo(el);
EYE.spacegallery.positionImages(el);
el.spacegalleryCfg.after.apply(el);
},
step: function(now) {
$('img.aaa', this)
.each(function(nr){
console.log('step: ' + $(this).attr('atr1'));
var newWidth, top, next;
if (nr + 1 == el.spacegalleryCfg.images) {
top = this.spacegallery.origTop + this.spacegallery.nextTop * 4 * now /100;
newWidth = this.spacegallery.width * top / this.spacegallery.origTop;
$(this)
.css({
top: top + 'px',
opacity: 0.7 - now/100,
marginLeft: - parseInt((newWidth + el.spacegalleryCfg.border)/2, 10) + 'px'
})
.attr('width', newWidth);
}
else {
next = this.spacegallery.current - this.spacegallery.increment * now /100;
newWidth = this.spacegallery.origWidth - (this.spacegallery.origWidth - this.spacegallery.origWidth * el.spacegalleryCfg.minScale) * next;
$(this).css({
top: this.spacegallery.origTop + this.spacegallery.nextTop * now /100 + 'px',
opacity: 1 - next,
marginLeft: - parseInt((newWidth + el.spacegalleryCfg.border)/2, 10) + 'px'
})
.attr('width', newWidth);
}
});
}
});
}
this.blur();
return false;
},
//constructor
init: function(opt) {
opt = $.extend({}, EYE.spacegallery.defaults, opt||{});
return this.each(function(){
var el = this;
if ($(el).is('.spacegallery')) {
$('')
.appendTo(this)
.addClass(opt.loadingClass)
.bind('click', EYE.spacegallery.next);
el.spacegalleryCfg = opt;
el.spacegalleryCfg.images = 3;
el.spacegalleryCfg.loaded = 0;
el.spacegalleryCfg.asin = Math.asin(1);
el.spacegalleryCfg.asins = {};
el.spacegalleryCfg.tops = {};
el.spacegalleryCfg.increment = parseInt(el.spacegalleryCfg.perspective/el.spacegalleryCfg.images, 10);
var top = 0;
$('img.aaa', el)
.each(function(nr){
var imgEl = new Image();
var elImg = this;
el.spacegalleryCfg.asins[nr] = 1 - Math.asin((nr+1)/el.spacegalleryCfg.images)/el.spacegalleryCfg.asin;
top += el.spacegalleryCfg.increment - el.spacegalleryCfg.increment * el.spacegalleryCfg.asins[nr];
el.spacegalleryCfg.tops[nr] = top;
elImg.spacegallery = {};
imgEl.src = this.src;
if (imgEl.complete) {
el.spacegalleryCfg.loaded ++;
elImg.spacegallery.origWidth = imgEl.width;
elImg.spacegallery.origHeight = imgEl.height
} else {
imgEl.onload = function() {
el.spacegalleryCfg.loaded ++;
elImg.spacegallery.origWidth = imgEl.width;
elImg.spacegallery.origHeight = imgEl.height
if (el.spacegalleryCfg.loaded == el.spacegalleryCfg.images) {
EYE.spacegallery.positionImages(el);
}
};
}
});
el.spacegalleryCfg.asins[el.spacegalleryCfg.images] = el.spacegalleryCfg.asins[el.spacegalleryCfg.images - 1] * 1.3;
el.spacegalleryCfg.tops[el.spacegalleryCfg.images] = el.spacegalleryCfg.tops[el.spacegalleryCfg.images - 1] * 1.3;
if (el.spacegalleryCfg.loaded == el.spacegalleryCfg.images) {
EYE.spacegallery.positionImages(el);
}
}
});
}
}
});
$.fn.extend({
/**
* Create a space gallery
* #name spacegallery
* #description create a space gallery
* #option int border Images' border. Default: 6
* #option int perspective Perpective height. Default: 140
* #option float minScale Minimum scale for the image in the back. Default: 0.2
* #option int duration Animation duration. Default: 800
* #option string loadingClass CSS class applied to the element while looading images. Default: null
* #option function before Callback function triggered before going to the next image
* #option function after Callback function triggered after going to the next image
*/
spacegallery: EYE.spacegallery.init
});
$.extend($.easing,{
easeOut:function (x, t, b, c, d) {
return -c *(t/=d)*(t-2) + b;
}
});
})(jQuery);
You can try to limit the matched image to the context of the current element by passing in this as the second argument tot he selector.
defaults: {
/* options */
before: function(){
$('img.imaz', this).fadeOut();
},
after: function(el){
$('img.imaz', this).fadeIn();
}
}
Whe we pass in this, as the second argument in the selector, we're telling jQuery to target "img.imaz", but only when it's found within this, meaning the current element being handled. In your project, this will be either #myGallery0, or #myGallery1.
You can learn more about the context argument online at http://api.jquery.com/jQuery/

Categories