JavaScript tooltip div stays in DOM when going back one page - javascript

When I click on a tooltip the content is shown on the page. The <div> which holds the content of the tooltip is shown in the page. However, when I go back to the previous page the tooltip div is still showing.
I tried adding adding an event listener onHashChange and add element hidden but that didn't work.
Here is the div when going back to a previous page:
I try adding the onHashChange event listener to the hidden() which is in charge of hiding the tooltip by adding a class hidden. Here is the code.
'use strict';
import $ from 'jquery';
import _ from 'underscore';
/**
* Creates a tooltip. The constructor is passed an HTML element that serves as
* the trigger to show or hide the tooltip. The tooltip should have an
* `aria-describedby` attribute, the value of which is the ID of the tooltip
* content to show or hide.
*/
class Tooltip {
/**
* #param {HTMLElement} el - The trigger element for the component.
* #constructor
*/
constructor(el) {
/** #private {HTMLElment} The triggering HTML element. */
this._trigger = el;
/** #private {HTMLElement} The tooltip element. */
this._tooltip = document.getElementById($(el).attr('aria-describedby'));
/** #private {boolean} Whether the tooltip is visible. */
this._active = false;
}
/**
* Sets event listeners, decorates the tooltip element, and appends the
* tooltip to the body to avoid positioning issues.
* #method
* #return {this} Tooltip
*/
init() {
$(this._tooltip).addClass(`${Tooltip.CssClass.TOOLTIP}
${Tooltip.CssClass.HIDDEN}`).attr({
'aria-hidden': true,
'role': 'tooltip'
}).on('click', e => {
// Stop click propagation so clicking on the tip doesn't trigger a
// click on body, which would close the tooltip.
e.stopPropagation();
}).detach().appendTo('body');
$(this._trigger).on('click', e => {
e.preventDefault();
e.stopPropagation();
this.toggle();
});
Tooltip.AllTips.push(this);
return this;
}
/**
* Displays the tooltip. Sets a one-time listener on the body to close the
* tooltip when a click event bubbles up to it.
* #method
* #return {this} Tooltip
*/
show() {
Tooltip.hideAll();
$(this._tooltip).removeClass(Tooltip.CssClass.HIDDEN)
.attr('aria-hidden', false);
$('body').one('click.tooltip', () => {
this.hide();
});
$(window).on('resize.tooltip', _.debounce(() => {
this.reposition();
}, 200));
this.reposition();
this._active = true;
return this;
}
/**
* Hides the tooltip and removes the click event listener on the body.
* #method
* #return {this} Tooltip
*/
hide() {
$(this._tooltip).addClass(Tooltip.CssClass.HIDDEN)
.attr('aria-hidden', true);
$(this._tooltip).onhashchange = function() {
$(this._tooltip).addClass(Tooltip.CssClass.HIDDEN)
.attr('aria-hidden', true);
}
$('body').off('click.tooltip');
this._active = false;
return this;
}
/**
* Hides the tooltip when changing pages.
* #method
* #return {this} Tooltip
*/
/**
* Toggles the state of the tooltip.
* #method
* #return {this} Tooltip
*/
toggle() {
if (this._active) {
this.hide();
} else {
this.show();
}
return this;
}
/**
* Positions the tooltip beneath the triggering element.
* #method
* #return {this} Tooltip
*/
reposition() {
const positioning = {
'left': 'auto',
'position': 'absolute',
'right': 'auto',
'top': 'auto',
'width': ''
};
// TODO(jjandoc): For RTL languages, we should make the default right
// alignment. Right now, the default is left alignment.
// const isRTL = $('html').attr('dir') === 'rtl';
// Reset positioning.
$(this._tooltip).css(positioning);
const triggerOffset = $(this._trigger).offset();
const tooltipWidth = $(this._tooltip).outerWidth();
const viewportWidth = $(window).innerWidth();
const gutter = 15; // Minimum distance from screen edge.
const topPos = triggerOffset.top + $(this._trigger).outerHeight();
let leftPos = 'auto';
let rightPos = 'auto';
// Determine left or right alignment.
// If the tooltip is wider than the screen minus gutters, then position
// the tooltip to extend to the gutters.
if (tooltipWidth >= viewportWidth - (2 * gutter)) {
leftPos = `${gutter}px`;
rightPos = `${gutter}px`;
positioning.width = 'auto';
} else if (triggerOffset.left + tooltipWidth + gutter > viewportWidth) {
// If the tooltip, when left aligned with the trigger, would cause the
// tip to go offscreen (determined by taking the trigger left offset and
// adding the tooltip width and the left gutter) then align the tooltip
// to the right side of the trigger element.
leftPos = 'auto';
rightPos = viewportWidth -
(triggerOffset.left + $(this._trigger).outerWidth()) + 'px';
} else {
// Align the tooltip to the left of the trigger element.
leftPos = `${triggerOffset.left}px`;
rightPos = 'auto';
}
// Set styling positions, reversing left and right if this is an RTL
// language.
positioning.left = leftPos;
positioning.right = rightPos;
positioning.top = topPos;
$(this._tooltip).css(positioning);
return this;
}
}
/**
* Array of all the instantiated tooltips.
* #type {Array<Tooltip>}
*/
Tooltip.AllTips = [];
/**
* Hide all Tooltips.
* #public
*/
Tooltip.hideAll = function() {
_.each(Tooltip.AllTips, tip => {
tip.hide();
});
};
/**
* CSS classes used by this component.
* #enum {string}
*/
Tooltip.CssClass = {
HIDDEN: 'hidden',
TOOLTIP: 'tooltip-bubble',
TRIGGER: 'js-tooltip-trigger'
};
export default Tooltip;
How to remove from DOM when going back one page?

Related

Signature pad not working in mobile browser

I use this code bellow for signature input, the signature pad working fine with web browser but not working means not draw on mobile browser.
I use this code bellow for signature input, the signature pad working fine with web browser but not working means not draw on mobile browser.
<script type="text/javascript">
/*! http://keith-wood.name/signature.html
Signature plugin for jQuery UI v1.2.1.
Requires excanvas.js in IE.
Written by Keith Wood (wood.keith{at}optusnet.com.au) April 2012.
Available under the MIT (http://keith-wood.name/licence.html) license.
Please attribute the author if you use it. */
/* globals G_vmlCanvasManager */
(function($) { // Hide scope, no $ conflict
'use strict';
var signatureOverrides = {
options: {
distance: 0,
background: '#fff',
color: '#000',
thickness: 2,
guideline: false,
guidelineColor: '#a0a0a0',
guidelineOffset: 50,
guidelineIndent: 10,
notAvailable: 'Your browser doesn\'t support signing',
scale: 1,
syncField: null,
syncFormat: 'JSON',
svgStyles: false,
change: null
},
/** Initialise a new signature area.
#memberof Signature
#private */
_create: function() {
this.element.addClass(this.widgetFullName || this.widgetBaseClass);
try {
this.canvas = $('<canvas width="' + this.element.width() + '" height="' +
this.element.height() + '">' + this.options.notAvailable + '</canvas>')[0];
this.element.append(this.canvas);
}
catch (e) {
$(this.canvas).remove();
this.resize = true;
this.canvas = document.createElement('canvas');
this.canvas.setAttribute('width', this.element.width());
this.canvas.setAttribute('height', this.element.height());
this.canvas.innerHTML = this.options.notAvailable;
this.element.append(this.canvas);
/* jshint -W106 */
if (G_vmlCanvasManager) { // Requires excanvas.js
G_vmlCanvasManager.initElement(this.canvas);
}
/* jshint +W106 */
}
this.ctx = this.canvas.getContext('2d');
this._refresh(true);
this._mouseInit();
},
/** Refresh the appearance of the signature area.
#memberof Signature
#private
#param {boolean} init <code>true</code> if initialising. */
_refresh: function(init) {
if (this.resize) {
var parent = $(this.canvas);
$('div', this.canvas).css({width: parent.width(), height: parent.height()});
}
this.ctx.fillStyle = this.options.background;
this.ctx.strokeStyle = this.options.color;
this.ctx.lineWidth = this.options.thickness;
this.ctx.lineCap = 'round';
this.ctx.lineJoin = 'round';
this.clear(init);
},
/** Clear the signature area.
#memberof Signature
#param {boolean} init <code>true</code> if initialising - internal use only.
#example $(selector).signature('clear') */
clear: function(init) {
if (this.options.disabled) {
return;
}
this.ctx.clearRect(0, 0, this.element.width(), this.element.height());
this.ctx.fillRect(0, 0, this.element.width(), this.element.height());
if (this.options.guideline) {
this.ctx.save();
this.ctx.strokeStyle = this.options.guidelineColor;
this.ctx.lineWidth = 1;
this.ctx.beginPath();
this.ctx.moveTo(this.options.guidelineIndent,
this.element.height() - this.options.guidelineOffset);
this.ctx.lineTo(this.element.width() - this.options.guidelineIndent,
this.element.height() - this.options.guidelineOffset);
this.ctx.stroke();
this.ctx.restore();
}
this.lines = [];
if (!init) {
this._changed();
}
},
/** Synchronise changes and trigger a change event.
#memberof Signature
#private
#param {Event} event The triggering event. */
_changed: function(event) {
if (this.options.syncField) {
var output = '';
switch (this.options.syncFormat) {
case 'PNG':
output = this.toDataURL();
break;
case 'JPEG':
output = this.toDataURL('image/jpeg');
break;
case 'SVG':
output = this.toSVG();
break;
default:
output = this.toJSON();
}
$(this.options.syncField).val(output);
}
this._trigger('change', event, {});
},
/** Refresh the signature when options change.
#memberof Signature
#private
#param {object} options The new option values. */
_setOptions: function(/* options */) {
if (this._superApply) {
this._superApply(arguments); // Base widget handling
}
else {
$.Widget.prototype._setOptions.apply(this, arguments); // Base widget handling
}
var count = 0;
var onlyDisable = true;
for (var name in arguments[0]) {
if (arguments[0].hasOwnProperty(name)) {
count++;
onlyDisable = onlyDisable && name === 'disabled';
}
}
if (count > 1 || !onlyDisable) {
this._refresh();
}
},
/** Determine if dragging can start.
#memberof Signature
#private
#param {Event} event The triggering mouse event.
#return {boolean} <code>true</code> if allowed, <code>false</code> if not */
_mouseCapture: function(/* event */) {
return !this.options.disabled;
},
/** Start a new line.
#memberof Signature
#private
#param {Event} event The triggering mouse event. */
_mouseStart: function(event) {
this.offset = this.element.offset();
this.offset.left -= document.documentElement.scrollLeft || document.body.scrollLeft;
this.offset.top -= document.documentElement.scrollTop || document.body.scrollTop;
this.lastPoint = [this._round(event.clientX - this.offset.left),
this._round(event.clientY - this.offset.top)];
this.curLine = [this.lastPoint];
this.lines.push(this.curLine);
},
/** Track the mouse.
#memberof Signature
#private
#param {Event} event The triggering mouse event. */
_mouseDrag: function(event) {
var point = [this._round(event.clientX - this.offset.left),
this._round(event.clientY - this.offset.top)];
this.curLine.push(point);
this.ctx.beginPath();
this.ctx.moveTo(this.lastPoint[0], this.lastPoint[1]);
this.ctx.lineTo(point[0], point[1]);
this.ctx.stroke();
this.lastPoint = point;
},
/** End a line.
#memberof Signature
#private
#param {Event} event The triggering mouse event. */
_mouseStop: function(event) {
if (this.curLine.length === 1) {
event.clientY += this.options.thickness;
this._mouseDrag(event);
}
this.lastPoint = null;
this.curLine = null;
this._changed(event);
},
/** Round to two decimal points.
#memberof Signature
#private
#param {number} value The value to round.
#return {number} The rounded value. */
_round: function(value) {
return Math.round(value * 100) / 100;
},
/** Convert the captured lines to JSON text.
#memberof Signature
#return {string} The JSON text version of the lines.
#example var json = $(selector).signature('toJSON') */
toJSON: function() {
return '{"lines":[' + $.map(this.lines, function(line) {
return '[' + $.map(line, function(point) {
return '[' + point + ']';
}) + ']';
}) + ']}';
},
/** Convert the captured lines to SVG text.
#memberof Signature
#return {string} The SVG text version of the lines.
#example var svg = $(selector).signature('toSVG') */
toSVG: function() {
var attrs1 = (this.options.svgStyles ? 'style="fill: ' + this.options.background + ';"' :
'fill="' + this.options.background + '"');
var attrs2 = (this.options.svgStyles ?
'style="fill: none; stroke: ' + this.options.color + '; stroke-width: ' + this.options.thickness + ';"' :
'fill="none" stroke="' + this.options.color + '" stroke-width="' + this.options.thickness + '"');
return '<?xml version="1.0"?>\n<!DOCTYPE svg PUBLIC ' +
'"-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">\n' +
'<svg xmlns="http://www.w3.org/2000/svg" width="15cm" height="15cm">\n' +
' <g ' + attrs1 + '>\n' +
' <rect x="0" y="0" width="' + this.canvas.width + '" height="' + this.canvas.height + '"/>\n' +
' <g ' + attrs2 + '>\n'+
$.map(this.lines, function(line) {
return ' <polyline points="' +
$.map(line, function(point) { return point + ''; }).join(' ') + '"/>\n';
}).join('') +
' </g>\n </g>\n</svg>\n';
},
/** Convert the captured lines to an image encoded in a <code>data:</code> URL.
#memberof Signature
#param {string} [type='image/png'] The MIME type of the image.
#param {number} [quality=0.92] The image quality, between 0 and 1.
#return {string} The signature as a data: URL image.
#example var data = $(selector).signature('toDataURL', 'image/jpeg') */
toDataURL: function(type, quality) {
return this.canvas.toDataURL(type, quality);
},
/** Draw a signature from its JSON or SVG description or <code>data:</code> URL.
<p>Note that drawing a <code>data:</code> URL does not reconstruct the internal representation!</p>
#memberof Signature
#param {object|string} sig An object with attribute <code>lines</code> being an array of arrays of points
or the text version of the JSON or SVG or a <code>data:</code> URL containing an image.
#example $(selector).signature('draw', sigAsJSON) */
draw: function(sig) {
if (this.options.disabled) {
return;
}
this.clear(true);
if (typeof sig === 'string' && sig.indexOf('data:') === 0) { // Data URL
this._drawDataURL(sig, this.options.scale);
} else if (typeof sig === 'string' && sig.indexOf('<svg') > -1) { // SVG
this._drawSVG(sig, this.options.scale);
} else {
this._drawJSON(sig, this.options.scale);
}
this._changed();
},
/** Draw a signature from its JSON description.
#memberof Signature
#private
#param {object|string} sig An object with attribute <code>lines</code> being an array of arrays of points
or the text version of the JSON.
#param {number} scale A scaling factor. */
_drawJSON: function(sig, scale) {
if (typeof sig === 'string') {
sig = $.parseJSON(sig);
}
this.lines = sig.lines || [];
var ctx = this.ctx;
$.each(this.lines, function() {
ctx.beginPath();
$.each(this, function(i) {
ctx[i === 0 ? 'moveTo' : 'lineTo'](this[0] * scale, this[1] * scale);
});
ctx.stroke();
});
},
/** Draw a signature from its SVG description.
#memberof Signature
#private
#param {string} sig The text version of the SVG.
#param {number} scale A scaling factor. */
_drawSVG: function(sig, scale) {
var lines = this.lines = [];
$(sig).find('polyline').each(function() {
var line = [];
$.each($(this).attr('points').split(' '), function(i, point) {
var xy = point.split(',');
line.push([parseFloat(xy[0]), parseFloat(xy[1])]);
});
lines.push(line);
});
var ctx = this.ctx;
$.each(this.lines, function() {
ctx.beginPath();
$.each(this, function(i) {
ctx[i === 0 ? 'moveTo' : 'lineTo'](this[0] * scale, this[1] * scale);
});
ctx.stroke();
});
},
/** Draw a signature from its <code>data:</code> URL.
<p>Note that this does not reconstruct the internal representation!</p>
#memberof Signature
#private
#param {string} sig The <code>data:</code> URL containing an image.
#param {number} scale A scaling factor. */
_drawDataURL: function(sig, scale) {
var image = new Image();
var context = this.ctx;
image.onload = function() {
context.drawImage(this, 0, 0, image.width * scale, image.height * scale);
};
image.src = sig;
},
/** Determine whether or not any drawing has occurred.
#memberof Signature
#return {boolean} <code>true</code> if not signed, <code>false</code> if signed.
#example if ($(selector).signature('isEmpty')) ... */
isEmpty: function() {
return this.lines.length === 0;
},
/** Remove the signature functionality.
#memberof Signature
#private */
_destroy: function() {
this.element.removeClass(this.widgetFullName || this.widgetBaseClass);
$(this.canvas).remove();
this.canvas = this.ctx = this.lines = null;
this._mouseDestroy();
}
};
if (!$.Widget.prototype._destroy) {
$.extend(signatureOverrides, {
/* Remove the signature functionality. */
destroy: function() {
this._destroy();
$.Widget.prototype.destroy.call(this); // Base widget handling
}
});
}
if ($.Widget.prototype._getCreateOptions === $.noop) {
$.extend(signatureOverrides, {
/* Restore the metadata functionality. */
_getCreateOptions: function() {
return $.metadata && $.metadata.get(this.element[0])[this.widgetName];
}
});
}
$.widget('kbw.signature', $.ui.mouse, signatureOverrides);
// Make some things more accessible
$.kbw.signature.options = $.kbw.signature.prototype.options;
})(jQuery);
</script>
<script>
var sig = $('#sig').signature({syncField: '#signature64', syncFormat: 'PNG'});
$('#clear').click(function(e) {
e.preventDefault();
sig.signature('clear');
$("#signature64").val('');
});
</script>
I use it laravel, hope anyone can help me.
I was also stuck at this, try following:
<script src="https://cdnjs.cloudflare.com/ajax/libs/jqueryui-touch-punch/0.2.3/jquery.ui.touch-punch.min.js" ></script>

Java Script scroll top with transition duration

this is my function. i cant find how to add transition duration in it. it just takes me straight upto top. syntax is what i'm looking for. idk much about js.
function topFunction() {
document.body.scrollTop=0 ;
document.documentElement.scrollTop =0 ;
}
Try using this in place of your function:
window.scrollTo({
top: 100,
left: 100,
behavior: 'smooth'
});
Reference
You can add transition duration by using below code.
function topFunction() {
currentYOffset = self.pageYOffset;
initYOffset = currentYOffset;
var intervalId = setInterval(function(){
currentYOffset -= initYOffset*0.05;
document.body.scrollTop = currentYOffset ;
document.documentElement.scrollTop = currentYOffset;
if(self.pageYOffset == 0){
clearInterval(intervalId);
}
}, 20);
}
You can set smoothness of the transition by editing the value of interval. I have set it as 20.
Here is a jQuery solution, using the jQuery.animate function.
The function gives you the ability to change the animation time, as well as the selector on which the animation is being applied, so that you can scroll other elements, too.
/**
* Scroll to a given point on the page with animation
*
* #param {int} scrollValue - The top position to scroll to
* #param {int} [animationTime] - Speed of the animation (in milliseconds)
* #param {string} [selector] - Which element to scroll. By default, it is the html/body
*/
function animateScrollTo(scrollValue, animationTime, selector){
if(typeof animationTime === "undefined"){
animationTime = 520;
}
if(typeof selector === "undefined"){
selector = "html, body";
}
jQuery(selector).animate({scrollTop: scrollValue}, animationTime);
}
body {
scroll-behavior: smooth;
}
Just use this property and document.getElementById('some-id').scrollTop = 0 will work with smooth transition/animation.

Issue with smoothing out javascript animation

I'm currently working on a javascript animation that transitions details on an event action - however, I am having an issue removing a certain rogue div.
I have my init function as follows:
var demo = (function(window, undefined) {
function init() {
_mapPolygons(pattern);
_bindCards();
$(document.getElementsByClassName("card__overlay")).addClass(CLASSES.overlayHidden);
};
return {
init: init
};
})(window);
window.onload = demo.init;
The full snippet is here:
'use strict';
/**
* Demo.
*/
var demo = (function(window, undefined) {
/**
* Enum of CSS selectors.
*/
var SELECTORS = {
pattern: '.pattern',
card: '.card',
cardImage: '.card__image',
cardClose: '.card__btn-close',
};
/**
* Enum of CSS classes.
*/
var CLASSES = {
patternHidden: 'pattern--hidden',
polygon: 'polygon',
polygonHidden: 'polygon--hidden',
overlayHidden: 'overlay--hidden',
};
/**
* Map of svg paths and points.
*/
var polygonMap = {
paths: null,
points: null
};
/**
* Container of Card instances.
*/
var layout = {};
/**
* Initialise demo.
*/
function init() {
// For options see: https://github.com/qrohlf/Trianglify
var pattern = Trianglify({
width: window.innerWidth,
height: window.innerHeight,
cell_size: 90,
variance: 1,
stroke_width: 0.6,
color_function : function(x, y) {
return '#f0f3f5';
}
}).svg(); // Render as SVG.
_mapPolygons(pattern);
_bindCards();
$(document.getElementsByClassName("card__overlay")).addClass(CLASSES.overlayHidden);
};
/**
* Store path elements, map coordinates and sizes.
* #param {Element} pattern The SVG Element generated with Trianglify.
* #private
*/
function _mapPolygons(pattern) {
// Append SVG to pattern container.
$(SELECTORS.pattern).append(pattern);
// Convert nodelist to array,
// Used `.childNodes` because IE doesn't support `.children` on SVG.
polygonMap.paths = [].slice.call(pattern.childNodes);
polygonMap.points = [];
polygonMap.paths.forEach(function(polygon) {
// Hide polygons by adding CSS classes to each svg path (used attrs because of IE).
$(polygon).attr('class', CLASSES.polygon + ' ' + CLASSES.polygonHidden);
var rect = polygon.getBoundingClientRect();
var point = {
x: rect.left + rect.width / 2,
y: rect.top + rect.height / 2
};
polygonMap.points.push(point);
});
// All polygons are hidden now, display the pattern container.
$(SELECTORS.pattern).removeClass(CLASSES.patternHidden);
};
/**
* Bind Card elements.
* #private
*/
function _bindCards() {
var elements = $(SELECTORS.card);
$.each(elements, function(card, i) {
var instance = new Card(i, card);
layout[i] = {
card: instance
};
var cardImage = $(card).find(SELECTORS.cardImage);
var cardClose = $(card).find(SELECTORS.cardClose);
$(cardImage).on('click', _playSequence.bind(this, true, i));
$(cardClose).on('click', _playSequence.bind(this, false, i));
});
};
/**
* Create a sequence for the open or close animation and play.
* #param {boolean} isOpenClick Flag to detect when it's a click to open.
* #param {number} id The id of the clicked card.
* #param {Event} e The event object.
* #private
*
*/
function _playSequence(isOpenClick, id, e) {
var card = layout[id].card;
// Prevent when card already open and user click on image.
if (card.isOpen && isOpenClick) return;
// Create timeline for the whole sequence.
var sequence = new TimelineLite({paused: true});
var tweenOtherCards = _showHideOtherCards(id);
if (!card.isOpen) {
// Open sequence.
sequence.add(tweenOtherCards);
sequence.add(card.openCard(_onCardMove), 0);
} else {
// Close sequence.
var closeCard = card.closeCard();
var position = closeCard.duration() * 0.8; // 80% of close card tween.
sequence.add(closeCard);
sequence.add(tweenOtherCards, position);
}
sequence.play();
};
/**
* Show/Hide all other cards.
* #param {number} id The id of the clcked card to be avoided.
* #private
*/
function _showHideOtherCards(id) {
var TL = new TimelineLite;
var selectedCard = layout[id].card;
for (var i in layout) {
var card = layout[i].card;
// When called with `openCard`.
if (card.id !== id && !selectedCard.isOpen) {
TL.add(card.hideCard(), 0);
}
// When called with `closeCard`.
if (card.id !== id && selectedCard.isOpen) {
TL.add(card.showCard(), 0);
}
}
return TL;
};
/**
* Callback to be executed on Tween update, whatever a polygon
* falls into a circular area defined by the card width the path's
* CSS class will change accordingly.
* #param {Object} track The card sizes and position during the floating.
* #private
*/
function _onCardMove(track) {
var radius = track.width / 2;
var center = {
x: track.x,
y: track.y
};
polygonMap.points.forEach(function(point, i) {
if (_detectPointInCircle(point, radius, center)) {
$(polygonMap.paths[i]).attr('class', CLASSES.polygon);
} else {
$(polygonMap.paths[i]).attr('class', CLASSES.polygon + ' ' + CLASSES.polygonHidden);
}
});
}
/**
* Detect if a point is inside a circle area.
* #private
*/
function _detectPointInCircle(point, radius, center) {
var xp = point.x;
var yp = point.y;
var xc = center.x;
var yc = center.y;
var d = radius * radius;
var isInside = Math.pow(xp - xc, 2) + Math.pow(yp - yc, 2) <= d;
return isInside;
};
// Expose methods.
return {
init: init
};
})(window);
// Kickstart Demo.
window.onload = demo.init;
)
I'm essentially adding a class which should completely hide a div element, for which I have overkilled due in part to major frustrations:
.overlay--hidden {
display: none !important;
overflow: hidden !important;
opacity: 0 !important;
}
So this should completely kill the card__overlay div. I have added the same css "stylings" within the inspector and it works as should.
<div class="card__content card__overlay">
<div class="card__caption">
<p class="card__subtitle overlay">NEWS</p>
</div>
</div>
My issue is that essentially the getElementsByClassName method in the init function doesn't seem to be working - the class I want which is essentially hiding the div is not being added!

Mousewheel script gives error in IE

Ok, here is the working cross-browser code, which has easing is well:
function handle(delta) {
var time = 1500;
var easing = 'easeInOutExpo';
var distance = document.getElementById('Element').scrollHeight;
$('html, body').stop().animate({
scrollTop: $(window).scrollTop() - (distance * delta)
}, time, easing );
}
/** Event handler for mouse wheel event.
*/
function wheel(event){
var delta = 0;
if (!event) /* For IE. */
event = window.event;
if (event.wheelDelta) { /* IE/Opera. */
delta = event.wheelDelta/120;
} else if (event.detail) { /** Mozilla case. */
/** In Mozilla, sign of delta is different than in IE.
* Also, delta is multiple of 3.
*/
delta = -event.detail/3;
}
/** If delta is nonzero, handle it.
* Basically, delta is now positive if wheel was scrolled up,
* and negative, if wheel was scrolled down.
*/
if (delta)
handle(delta);
/** Prevent default actions caused by mouse wheel.
* That might be ugly, but we handle scrolls somehow
* anyway, so don't bother here..
*/
if (event.preventDefault)
event.preventDefault();
event.returnValue = false;
}
/** Initialization code.
* If you use your own event management code, change it as required.
*/
if (window.addEventListener)
/** DOMMouseScroll is for mozilla. */
window.addEventListener('DOMMouseScroll', wheel, false);
/** IE/Opera. */
window.onmousewheel = document.onmousewheel = wheel;
To get the distance there are two options:
1. manually by giving a value
2. automatically through css by defining "Element"
Hope to have helped.

Calculating window dragging and skewing in JavaScript

I am using JavaScript and trying to make a skew effect on a div.
First, take a look at this video: http://www.youtube.com/watch?v=ny5Uy81smpE (0:40-0:60 should be enough). The video shows some nice transformations (skew) when you move the window. What I want to do is the same thing: to skew a div when I move it.
Currently I just have a plain simple div:
<div id="a" style="background: #0f0; position: absolute; left: 0px; top: 0px;"></div>
I have done a simple skew transformation using the CSS3's transform property, but my implementation is buggy. Are there good tutorials or maths sites or resources that describe the logic behind this? I know JavaScript and CSS well enough to implement, if I just knew the logic and maths. I tried reading FreeWins source code, but I am not good in C.
I am accepting any resourceful answers or pseudo code. My dragging system is part of a bigger system, thus, now that I post some real code, it does not work without giving you the entire system (that I can not do at this point). So, you can't run this code as is. The code I use is this (slightly modified though) to demonstrate my idea:
/**
* The draggable object.
*/
Draggable = function(targetElement, options) {
this.targetElement = targetElement;
// Initialize drag data.
this.dragData = {
startX: null,
startY: null,
lastX: null,
lastY: null,
offsetX: null,
offsetY: null,
lastTime: null,
occuring: false
};
// Set the cursor style.
targetElement.style.cursor = 'move';
// The element to move.
this.applyTo = options.applyTo || targetElement;
// Event methods for "mouse down", "up" and "move".
// Mouse up and move are binded to window.
// We can attach and deattach "move" and "up" events as needed.
var me = this;
targetElement.addEventListener('mousedown', function(event) {
me.onMouseDown.call(me, event);
}, false);
this.mouseUp = function(event) {
me.onMouseUp.call(me, event);
};
this.mouseMove = function(event) {
me.onMouseMove.call(me, event);
};
};
/**
* The mouse down event.
* #param {Object} event
*/
Draggable.prototype.onMouseDown = function(event) {
// New drag event.
if (this.dragData.occuring === false) {
this.dragData.occuring = true;
this.dragData.startX = this.dragData.lastX = event.clientX;
this.dragData.startY = this.dragData.lastY = event.clientY;
this.dragData.offsetX = parseInt(this.applyTo.style.left, 10) - event.clientX;
this.dragData.offsetY = parseInt(this.applyTo.style.top, 10) - event.clientY;
this.dragData.lastTime = (new Date()).getTime();
// Mouse up and move events.
var me = this;
window.addEventListener('mousemove', this.mouseMove, false);
window.addEventListener('mouseup', this.mouseUp, false);
}
};
/**
* The mouse movement event.
* #param {Object} event
*/
Draggable.prototype.onMouseMove = function(event) {
if (this.dragData.occuring === true) {
// He is dragging me now, we move if there is need for that.
var moved = (this.dragData.lastX !== event.clientX || this.dragData.lastY !== event.clientY);
if (moved === true) {
var element = this.applyTo;
// The skew animation. :)
var skew = (this.dragData.lastX - event.clientX) * 1;
var limit = 25;
if (Math.abs(skew) > limit) {
skew = limit * (skew > 0 ? 1 : -1);
}
var transform = 'translateX(' + (event.clientX + this.dragData.offsetX - parseInt(element.style.left, 10)) + 'px)';
transform += 'translateY(' + (event.clientY + this.dragData.offsetY - parseInt(element.style.top, 10)) + 'px)';
transform += 'skew(' + skew + 'deg)';
element.style.MozTransform = transform;
element.style.webkitTransform = transform;
this.dragData.lastX = event.clientX;
this.dragData.lastY = event.clientY;
this.dragData.lastTime = (new Date()).getTime();
}
}
};
/**
* The mouse up event.
* #param {Object} event
*/
Draggable.prototype.onMouseUp = function(event) {
this.dragData.occuring = false;
var element = this.applyTo;
// Reset transformations.
element.style.MozTransform = '';
element.style.webkitTransform = '';
// Save the new position.
element.style.left = (this.dragData.lastX + this.dragData.offsetX) + 'px';
element.style.top = (this.dragData.lastY + this.dragData.offsetY) + 'px';
// Remove useless events.
window.removeEventListener('mousemove', this.mouseMove, false);
window.removeEventListener('mousemove', this.mouseUp, false);
};
Currently my dragging system is buggy and simple. I need more information on the logic that I should be applying.
Wow, the idea rocks. :) I've cleaned your code a bit, and solved the problems with initialization. Now it works fine for me on Firefox and Chrome (even though you said it shouldn't).
A few notes:
you need to grab the starting top and left positions during initialization (getBoundingClientRect)
store references like this.dragData and element.style for shortness and faster execution
dragData can be initialized as an empty object. It's fine in javascript. You can add properties later.
options should be conditionally initialized as an empty object, so that you can take zero options
moved and dragData.occuring were totally useless because of the event management
preventDefault is needed in order not to select text during dragging
you may want to keep track of z-indexes to be the active element always visible
Have fun!
Code [See it in action]
/**
* The draggable object.
*/
Draggable = function(targetElement, options) {
this.targetElement = targetElement;
// we can take zero options
options = options || {};
// Initialize drag data.
// #props: startX, startY, lastX, lastY,
// offsetX, offsetY, lastTime, occuring
this.dragData = {};
// Set the cursor style.
targetElement.style.cursor = 'move';
// The element to move.
var el = this.applyTo = options.applyTo || targetElement;
// Event methods for "mouse down", "up" and "move".
// Mouse up and move are binded to window.
// We can attach and deattach "move" and "up" events as needed.
var me = this;
targetElement.addEventListener('mousedown', function(event) {
me.onMouseDown.call(me, event);
}, false);
this.mouseUp = function(event) {
me.onMouseUp.call(me, event);
};
this.mouseMove = function(event) {
me.onMouseMove.call(me, event);
};
// initialize position, so it will
// be smooth even on the first drag
var position = el.getBoundingClientRect();
el.style.left = position.left + "px";
el.style.top = position.top + "px";
el.style.position = "absolute";
if (el.style.zIndex > Draggable.zindex)
Draggable.zindex = el.style.zIndex + 1;
};
Draggable.zindex = 0;
/**
* Sets the skew and saves the position
* #param {Number} skew
*/
Draggable.prototype.setSkew = function(skew) {
var data = this.dragData;
var style = this.applyTo.style;
// Set skew transformations.
data.skew = skew;
style.MozTransform = skew ? 'skew(' + skew + 'deg)' : '';
style.webkitTransform = skew ? 'skew(' + skew + 'deg)' : '';
// Save the new position.
style.left = (data.lastX + data.offsetX) + 'px';
style.top = (data.lastY + data.offsetY) + 'px';
}
/**
* The mouse down event.
* #param {Object} event
*/
Draggable.prototype.onMouseDown = function(event) {
var data = this.dragData;
// New drag event.
var style = this.applyTo.style;
data.startX = data.lastX = event.clientX;
data.startY = data.lastY = event.clientY;
data.offsetX = parseInt(style.left, 10) - event.clientX;
data.offsetY = parseInt(style.top, 10) - event.clientY;
style.zIndex = Draggable.zindex++;
data.lastTime = (new Date()).getTime();
// Mouse up and move events.
window.addEventListener('mousemove', this.mouseMove, false);
window.addEventListener('mouseup', this.mouseUp, false);
event.preventDefault(); // prevent text selection
};
/**
* The mouse movement event.
* #param {Object} event
*/
Draggable.prototype.onMouseMove = function(event) {
// He is dragging me now
var me = this;
var data = me.dragData;
var element = me.applyTo;
var clientX = event.clientX;
var clientY = event.clientY;
data.moving = true;
// The skew animation. :)
var skew = (data.lastX - clientX) * 1;
var limit = 25;
if (Math.abs(skew) > limit) {
skew = limit * (skew > 0 ? 1 : -1);
}
var style = element.style;
var left = parseInt(style.left, 10);
var top = parseInt(style.top, 10);
var transform =
'translateX(' + (clientX + data.offsetX - left) + 'px)' +
'translateY(' + (clientY + data.offsetY - top) + 'px)' +
'skew(' + skew + 'deg)';
style.MozTransform = transform;
style.webkitTransform = transform;
data.lastX = clientX;
data.lastY = clientY;
data.lastTime = (new Date()).getTime();
// here is the cooldown part in order
// not to stay in disorted state
var pre = skew > 0 ? 1 : -1;
clearInterval(data.timer);
data.timer = setInterval(function() {
var skew = data.skew - (pre * 10);
skew = pre * skew < 0 ? 0 : skew;
me.setSkew(skew);
if (data.moving || skew === 0)
clearInterval(data.timer);
}, 20);
data.moving = false;
};
/**
* The mouse up event.
* #param {Object} event
*/
Draggable.prototype.onMouseUp = function(event) {
this.setSkew('');
// Remove useless events.
window.removeEventListener('mousemove', this.mouseMove, false);
window.removeEventListener('mousemove', this.mouseUp, false);
};

Categories

Resources