Animation fade | jQuery vs pure js | setInterval vs. setTimeout - javascript

I have this tested function below that works fine for fading an element in or out.
What do I gain by using JQuery?
Thanks
Effects.prototype.fade = function( direction, max_time, element )
{
var elapsed = 0;
function next() {
elapsed += 10;
if (direction === 'up')
{
element.style.opacity = elapsed / max_time;
}
else if (direction === 'down')
{
element.style.opacity = (max_time - elapsed) / max_time;
}
if (elapsed <= max_time) {
setTimeout(next, 10);
}
}
next();
};
Running a search on fadeIn() on the core jquery library I get one hit here:
jQuery.each({
slideDown: genFx( "show", 1 ),
slideUp: genFx( "hide", 1 ),
slideToggle: genFx( "toggle", 1 ),
fadeIn: { opacity: "show" },
fadeOut: { opacity: "hide" },
fadeToggle: { opacity: "toggle" }
}, function( name, props ) {
jQuery.fn[ name ] = function( speed, easing, callback ) {
return this.animate( props, speed, easing, callback );
};
});
Using the JQuery Source Viewer
function (prop, speed, easing, callback) {
var optall = jQuery.speed(speed, easing, callback);
if (jQuery.isEmptyObject(prop)) {
return this.each(optall.complete, [false]);
}
prop = jQuery.extend({},
prop);
return this[optall.queue === false ? "each" : "queue"](function () {
if (optall.queue === false) {
jQuery._mark(this);
}
var opt = jQuery.extend({},
optall),
isElement = this.nodeType === 1,
hidden = isElement && jQuery(this).is(":hidden"),
name, val, p, display, e, parts, start, end, unit;
opt.animatedProperties = {};
for (p in prop) {
name = jQuery.camelCase(p);
if (p !== name) {
prop[name] = prop[p];
delete prop[p];
}
val = prop[name];
if (jQuery.isArray(val)) {
opt.animatedProperties[name] = val[1];
val = prop[name] = val[0];
} else {
opt.animatedProperties[name] = opt.specialEasing && opt.specialEasing[name] || opt.easing || "swing";
}
if (val === "hide" && hidden || val === "show" && !hidden) {
return opt.complete.call(this);
}
if (isElement && (name === "height" || name === "width")) {
opt.overflow = [this.style.overflow, this.style.overflowX, this.style.overflowY];
if (jQuery.css(this, "display") === "inline" && jQuery.css(this, "float") === "none") {
if (!jQuery.support.inlineBlockNeedsLayout) {
this.style.display = "inline-block";
} else {
display = defaultDisplay(this.nodeName);
if (display === "inline") {
this.style.display = "inline-block";
} else {
this.style.display = "inline";
this.style.zoom = 1;
}
}
}
}
}
if (opt.overflow != null) {
this.style.overflow = "hidden";
}
for (p in prop) {
e = new jQuery.fx(this, opt, p);
val = prop[p];
if (rfxtypes.test(val)) {
e[val === "toggle" ? hidden ? "show" : "hide" : val]();
} else {
parts = rfxnum.exec(val);
start = e.cur();
if (parts) {
end = parseFloat(parts[2]);
unit = parts[3] || (jQuery.cssNumber[p] ? "" : "px");
if (unit !== "px") {
jQuery.style(this, p, (end || 1) + unit);
start = (end || 1) / e.cur() * start;
jQuery.style(this, p, start + unit);
}
if (parts[1]) {
end = (parts[1] === "-=" ? -1 : 1) * end + start;
}
e.custom(start, end, unit);
} else {
e.custom(start, val, "");
}
}
}
return true;
});
}

Usually you don't include a library like jQuery just for a single effect, but as a general purpose library in order to simplify things such as DOM manipulation, AJAX calls, setting CSS properties in a way that's cross-browser, in addition to applying effects (such as .fadeIn/.fadeOut) and other applications.
Tipically it's recommended you don't add jQuery for just a simple call. But my reasoning is that you are probably be going to exploit more and more of it's features in the long run, so I don't see a real reason not to use it.
On the subject of implementing your own fadeIn or fadeOut functions, you could look at the jQuery source and extract those methods, or make your own implementation from scratch. But given the fact that jQuery already implemented this method, I don't see why you would want to replicate it, other than for educational purposes.

The biggest reason to use JQuery over your custom code, in my opinion, is that you don't have to maintain the code for multiple browsers and multiple versions. JQuery does a good job of handling the quirks of the major browsers for you.
In addition, there are many other excellent uses for JQuery that you may want to use later.
Concerning the code, when you download JQuery: http://docs.jquery.com/Downloading_jQuery you can get the uncompressed version, which is intended to be readable.
I don't know of a simple way to get only those functions out of JQuery. Why not use the full library?

Related

How to determine if mouse is not over an element?

I know that there are many similar questions, but I can't understand what is the mistake in my if statement.
So basically I want to stop clicking nextBtn once I hover over timeoutArea,
but this: timeoutArea.mouseover != true doesn't seems to work.
const timeoutArea = document.getElementById("slider");
var time = 1;
let interval = setInterval(function() {
if (time <= 20 && window.pageYOffset < 393) {
if (timeoutArea.mouseover != true) {
nextBtn.click();
};
time++;
}
else {
time = 1;
}
}, 2000);
if u are using jquery u can use $('#slider').is(':hover') in if statement.
if u use only pure javascript u can use with one function
example fiddle https://jsfiddle.net/9x5hjpk3/
function isHover(e) {
return (e.parentElement.querySelector(':hover') === e);
}
so change
if (timeoutArea.mouseover != true) {
nextBtn.click();
};
to
if (!isHover(timeoutArea)) {
nextBtn.click();
};

Rewrite script from js to jquery

I have a script that I want to make more bulletproof. At the moment the page breaks because class box-tip is not found. To make this bulletproof and not throw an error how can I rewrote the below code to jquery getting the same results as js
function applyRecommendedSleeveLength(selectedVal) {
if (selectedVal !== undefined) {
var recommendedVal = map[selectedVal.trim()];
var selected = $('.attribute__swatch--selected:first div').text().trim();
if (recommendedVal === null || recommendedVal === undefined) {
selectedVal = $('.attribute__swatch--selected:first div').text().trim();
recommendedVal = map[selectedVal.trim()];
}
if (selected === null || selected === '' || selected === undefined) return;
var recommendedLis = document.querySelectorAll('[class*="attribute__swatch--length-' + recommendedVal + '"] div');
recommendedLis.forEach(function(recommendedLi, i) {
if (recommendedLi !== null && recommendedLi !== undefined) {
recommendedLi.classList.add('showBorder');
$('.box-tip').show();
var currentPosition = $('.showBorder').parent().position().left;
var sleeveRecom = document.getElementsByClassName('box-tip');
var info = sleeveRecom.length ? sleeveRecom[0] : false;
info.style.paddingLeft = currentPosition + -75 + 'px';
}
});
}
}
If you want to check if the div exists, you can use this (using JQuery):
if ( $('.box-tip').length != 0 ){
//do something
}
OR- since you've edited your post- without JQuery:
if ( document.getElementsByClassName('box-tip').length != 0 ){
//do something
}
Just use jQuery for all of this. If the class doesn't exist the jQuery methods won't cause errors
function applyRecommendedSleeveLength() {
$('.box-tip').show().first().css('paddingLeft', (currentPosition - 75) + 'px');
}

Disable bounce on first and last item in Owl Carousel

I'm using a Owl Carousel slider.
When you reach the last or first item of the slider you can still drag the slider although there aren't anymore items. Instead there is a bounce effect like when you pull down a native mobile app to refresh the content.
Demo: (link removed since the official docs aren't there anymore)
Drag the slider to the right and it will bounce back.
Is there a possibility to disable that bounce effect?
Yes, you can disable the bounce effect. I struggled finding it but I did it.
Just remove or comment out this lines code in owl.carousel.js:
base.newPosX = Math.max(Math.min(base.newPosX, minSwipe()), maxSwipe());
if (base.browser.support3d === true) {
base.transition3d(base.newPosX);
} else {
base.css2move(base.newPosX);
}
E.g.
owl.carousel.js
function dragMove(event) {
var ev = event.originalEvent || event || window.event,
minSwipe,
maxSwipe;
base.newPosX = getTouches(ev).x - locals.offsetX;
base.newPosY = getTouches(ev).y - locals.offsetY;
base.newRelativeX = base.newPosX - locals.relativePos;
if (typeof base.options.startDragging === "function" && locals.dragging !== true && base.newRelativeX !== 0) {
locals.dragging = true;
base.options.startDragging.apply(base, [base.$elem]);
}
if ((base.newRelativeX > 8 || base.newRelativeX < -8) && (base.browser.isTouch === true)) {
if (ev.preventDefault !== undefined) {
ev.preventDefault();
} else {
ev.returnValue = false;
}
locals.sliding = true;
}
if ((base.newPosY > 10 || base.newPosY < -10) && locals.sliding === false) {
$(document).off("touchmove.owl");
}
minSwipe = function () {
return base.newRelativeX / 5;
};
maxSwipe = function () {
return base.maximumPixels + base.newRelativeX / 5;
};
// base.newPosX = Math.max(Math.min(base.newPosX, minSwipe()), maxSwipe());
// if (base.browser.support3d === true) {
// base.transition3d(base.newPosX);
// } else {
// base.css2move(base.newPosX);
// }
}
Hope it helps.

How to make object move in js?

I'm trying to learn object oriented programming in javascript so I try to make a simple game. I would like to make a character that moves. There is the code in js:
function move(event)
{
var k=event.keyCode;
var chr = {
updown : function (){
var y=0;
if (k==38)
{--y;
}else if (k==40)
{++y;}
return y;
},
leftright : function (){
var x=0;
if (k==37)
{--x;
}else if (k==39)
{++x;}
return x;
}
};
chrId.style.top = (chr.updown())+"px";
chrId.style.left = (chr.leftright())+"px";
}
html:
<!DOCTYPE html>
<html>
<head>
<link rel="stylesheet" type="text/css" href="jumpOPP.css">
<script src="jumpOPP.js"></script>
</head>
<body onkeydown="move(event)">
<img id="chrId" src="TrackingDot.png" >
</body>
</html>
and CSS:
#chrId {
position: relative;
top: 0px;
left: 0px;
}
When I press and hold up, down, left, right the dot moves only for a one place. How to make it moving whole time I' m holding some key. I have made it without var char to move. I used function move(event) and then a switch, cases 38, 37, 39 and 40 and then it change style.top but I can't make it in one object.
Is it possible to make a object chr = {objekt movement, life, power...} and then a object ground = {some code that stops the chr} and other interacting objects ? Can somebody recomend a good tutorial for that? :)
Thank you
Here working jsfiddle - http://jsfiddle.net/t5ya4j26/
You error in define local variables in scopes that always will equal to 0. So for fix that, you must get current left and top of element, not define x = 0 and y = 0.
function move(event) {
var k = event.keyCode,
chrId = document.getElementById('test'),
chr = {
updown: function () {
var y = parseInt(getComputedStyle(chrId).top);
if (k == 38) {
--y;
} else if (k == 40) {
++y;
}
return y;
},
leftright: function () {
var x = parseInt(getComputedStyle(chrId).left);
if (k == 37) {
--x;
} else if (k == 39) {
++x;
}
return x;
}
};
chrId.style.top = (chr.updown()) + "px";
chrId.style.left = (chr.leftright()) + "px";
}
document.addEventListener('keydown', move);
I would recommend that you use the <canvas> element for stuff like this. But use window.setInterval(function, milliseconds) to have it repeatedly run your 'move' function and then when a key is released, window.onkeyup clear that interval.
clearInterval(intervalName);
This requires you to make a new event listener. Instead of having your event listener in body, use:
window.onkeydown = function(event) {
var k = event.which || event.keyCode; // This adds compatibilty across all browsers
// Code to be run
}
I know that you are looking for the function in an object, but moving an element is really quick and easy with this, I just made this today for my beginners game:
var change = (parseInt(chrId.style.left.replace('%',''),10) + 3).toString() + "%"
chrId.style.left = change
The % signs can be replaced with 'px' if you are using pixel values to move, and the ' + 3 ' is how many pixels or percentage points you want your element to move per execution.
The same can be done for up by changing the 'left' to 'top'.
My code might not be to your liking, but I'm just trying to demonstrate how I work around this problem, I am positively sure that there are hundreds of better ways, but this one seems to save me a lot of trouble for a lot of other stuff.
Hope I was able understand the question and help though, sorry if I couldn't :)
<!DOCTYPE html>
<html>
<head>
<meta charset = "utf-8">
<title> MOVEMENT </title>
</head>
<body>
<script type = "text/javascript">
//------------------------------------------------------------------------------
// VARIABLES are set here so they're GLOBAL (everything may access them)
//------------------------------------------------------------------------------
let lock_left = true
let lock_top = true
let lock_right = true
let lock_bottom = true
//------------------------------------------------------------------------------
let html; let htmls
let body; let bodys
let avatar; let avatars
//------------------------------------------------------------------------------
let avatar_x = 0
let avatar_y = 0
//------------------------------------------------------------------------------
// EVERY map will be an object, and every object needs a CREATE function that
// will happen only ONCE and an UPDATE function that will repeat itself
//------------------------------------------------------------------------------
const map_main =
{
create: function()
{
html = document.querySelector( "html" ); htmls = html.style
body = document.querySelector( "body" ); bodys = body.style
},
//--------------------------------------------------------------------------
update: function()
{
htmls.width = "100%"
htmls.height = "100%"
htmls.margin = "0"
bodys.width = "100%"
bodys.height = "100%"
bodys.margin = "0"
bodys.backgroundColor = "rgb( 120, 200, 80 )"
},
}
//------------------------------------------------------------------------------
const map_avatar =
{
create: function()
{
avatar = document.createElement( "div" ); avatars = avatar.style
body.appendChild( avatar )
},
//--------------------------------------------------------------------------
update: function()
{
avatars.width = "64px"
avatars.height = "64px"
avatars.backgroundColor = "rgb( 200, 80, 120 )"
avatars.position = "absolute"
avatars.top = avatar_y + "px"
avatars.left = avatar_x + "px"
},
}
//------------------------------------------------------------------------------
// BELOW are the 2 main gears of the engine
//------------------------------------------------------------------------------
// EVERY code that only needs to happen once is called here
const master_create = function()
{
map_main.create()
map_avatar.create()
}
//------------------------------------------------------------------------------
// EVERYTHING that needs constant updates is called here
const master_update = function()
{
map_main.update()
map_avatar.update()
movement()
window.requestAnimationFrame( master_update )
}
//------------------------------------------------------------------------------
// BELOW is showing how the keyboard affects the locks
//------------------------------------------------------------------------------
const press = function( pressed )
{
if( pressed.keyCode === 37 || pressed.keyCode === 69 ) lock_left = false
if( pressed.keyCode === 38 || pressed.keyCode === 82 ) lock_top = false
if( pressed.keyCode === 39 || pressed.keyCode === 70 ) lock_right = false
if( pressed.keyCode === 40 || pressed.keyCode === 68 ) lock_bottom = false
}
//------------------------------------------------------------------------------
const release = function( released )
{
if( released.keyCode === 37 || released.keyCode === 69 ) lock_left = true
if( released.keyCode === 38 || released.keyCode === 82 ) lock_top = true
if( released.keyCode === 39 || released.keyCode === 70 ) lock_right = true
if( released.keyCode === 40 || released.keyCode === 68 ) lock_bottom = true
}
//------------------------------------------------------------------------------
// BELOW will check the LOCKS and use them to change AVATAR_X and AVATAR_Y
//------------------------------------------------------------------------------
const movement = function()
{
if( lock_left === false ) avatar_x -= 10
if( lock_top === false ) avatar_y -= 10
if( lock_right === false ) avatar_x += 10
if( lock_bottom === false ) avatar_y += 10
}
//------------------------------------------------------------------------------
// BELOW we call the 2 gears and everything will work
//------------------------------------------------------------------------------
master_create() // will be called only ONCE
master_update() // will repeat forever due to "window.requestAnimationFrame()"
//------------------------------------------------------------------------------
// LISTENERS should go after the engine starts rolling
//------------------------------------------------------------------------------
body.addEventListener( "keydown", press, false )
body.addEventListener( "keyup", release, false )
//------------------------------------------------------------------------------
</script>
</body>
</html>

Fade out elements on page without jquery

I would like to fade out some elements on my page with javascript but without jquery. How should I do this onclick?
After our small discussion in the comments of your question you mentioned you were primarily targeting mobile devices. CSS transition, therefore, might be your best option as it's supported by all versions of iOS and Android and doesn't perform any expensive JavaScript loops.
Here's a fiddle of a working minimal implementation.
HTML:
fade
<div id="toFade">...</div>
CSS:
#toFade {
-webkit-transition: opacity 2s;
opacity: 1;
}
#toFade.faded {
opacity: 0;
}
Javascript:
document.getElementById('doFade').addEventListener('click', function() {
document.getElementById('toFade').className += 'faded';
});
var s = document.getElementById('thing').style;
s.opacity = 1;
(function fade(){(s.opacity-=.1)<0?s.display="none":setTimeout(fade,40)})();
taken from http://vanilla-js.com/
I guess you'd make your own fadeOut function?
function fade(element, speed) {
var op = 1,
timer = setInterval(function () {
if (op <= 0.1){
clearInterval(timer);
element.style.display = 'none';
}
element.style.opacity = op;
element.style.filter = 'alpha(opacity=' + op * 100 + ")";
op -= op * 0.1;
}, speed);
}
FIDDLE
If you're only targeting browsers that support CSS3 fade options, go for CSS3, but if not you'll want something like:
function addEvent(obj,event,func)
{
if(typeof func !== 'function')
{
return false;
}
if(typeof obj.addEventListener == 'function' || typeof obj.addEventListener == 'object')
{
return obj.addEventListener(event.replace(/^on/,''), func, false);
}
else if(typeof obj.attachEvent == 'function' || typeof obj.attachEvent == 'object')
{
return obj.attachEvent(event,func);
}
}
addEvent(elem,'onclick',function(e) {
var target = e.srcElement || e.target;
target.style.opacity = 1;
var fadeOutInt = setInterval(function() {
target.style.opacity -= 0.1;
if(target.style.opacity <= 0) clearInterval(fadeOutInt);
},50);
});
JSFiddle
CSS
.fade{
opacity: 0;
}
JavaScript
var myEle=document.getElementById("myID");
myEle.className += " fade"; //to fadeIn
myEle.className.replace( /(?:^|\s)fade(?!\S)/ , '' ) //to fadeOut

Categories