MooTools Effect Chaining - mootools

I'd like to be able to do something like this:
var fx = new Fx.Tween($('element'), {
duration: 500,
property: 'opacity',
transition: Fx.Transitions.Quart.easeOut,
link: 'chain'
});
fx.start(0, 1)
.chain(function() {
alert('foo');
})
.start(1, 0)
.chain(function() {
alert('bar');
});
Which then fades in #element, and then runs a function. However, I can't get it to run the second start after the first chain(), which means that #element isn't fading back in.
Thanks for your help

It turns out that something very similar to the above code can work except you need to use callChain() in order for the next "link" to fire.. This is what I'm using now:
var effect = new Fx.Tween($('element'));
effect.start('opacity', 1)
.chain(function() { /* Do stuff */ this.callChain();)
.chain(function() { /* Do stuff */ this.callChain();)
.chain(function() { /* Do stuff */ this.callChain();)
.chain(function() { /* Do stuff */ this.callChain();)
.chain(function() { /* Do stuff */);
And so on.
This is because chain returns and instance of the Chain class, rather than an instance of Fx.Tween. I'm a little annoyed that I need to use callChain() but it's better than having loads of nested functions.

Related

Prevent static files inside a CSS from being displayed before the page is loaded

I am modifying some JSP files, and every time I upload a new version, if people don't update the cache, the styles are not rendered as they should be; it is looking not good and without styles applied.
To solve this problem, I have followed an example from Stack Overflow that adds a numeric value to the CSS file, preventing it from being cached in the browser. The specific link I've seen is this one:
https://wpreset.com/force-reload-cached-css/
But I've found that whenever I press F5 or navigate to other JSP's that apply the same stylesheet, the files that are part of that CSS file are always seen just before rendering. I added a GIF with a dummy example to exhibit what I mean:
Animated GIF demonstrating the problem
How could I avoid this?
Would something like the following help?
/* CSS */
.no-js #loader { display: none; }
.js #loader { display: block; position: absolute; left: 100px; top: 0; }
|
// Js
$(window).load(function() { // Wait for window load
// Animate loader off screen
$("#loader").animate({
top: -200
}, 1500);
});
Like it is used here.
I have already been able to solve it.
In the end I have chosen to nest inside a window.onload, the document.ready like this:
window.onload = function () {
document.getElementsByTagName("html")[0].style.visibility = "visible";
var h, a, f;
a = document.getElementsByTagName('link');
for (h = 0; h < a.length; h++) {
f = a[h];
if (f.rel.toLowerCase().match(/stylesheet/) && f.href && f.href.indexOf("custom-common.css") != -1) {
var g = f.href.replace(/(&|\?)rnd=\d+/, '');
f.href = g + (g.match(/\?/) ? '&' : '?');
f.href += 'rnd=' + (new Date().valueOf());
}
}
$(document).ready(function () {
$('.main-link').click(function () {
And change the visibility of the html document. I have omitted the rest of the code, but you can get an idea. Many thanks to Robert Bradley and Adam for shedding light and helping me.

Using CSS Variables on Stripe Elements

I am using Stripe Elements for a credit card checkout. The issue is, that I am not able (or I simply don't know how) to use my own CSS variables on this Stripe Element.
I need to use CSS variables for the sake of changing colors when the user changes the theme. Here is my current implementation:
Variable definitions (I'm using SASS)
.theme1
--color-1: red
--color-2: pink
// ...
.theme2
--color-1: blue
--color-2: lilec
// ...
.theme3
--color-1: orange
--color-2: yellow
// ...
// ...
The CSS variables are defined under the scope of a class, that is put to the body depending which theme is currently selected.
HTML (I am using Angular 6)
<div #stripe></div>
Typescript
#ViewChild('stripe') el: ElementRef;
card: any;
cardHandler = this.onChange.bind(this);
async onSubmit() { /* ... */ }
setupStripe(): void {
this.card = stripeElements.create('card', {
iconStyle: 'solid',
style: {
base: {
iconColor: 'var(--some-var)',
// using css variables here does not work
// ...
},
}
});
this.card.mount(this.el.nativeElement);
this.card.addEventListener('change', this.cardHandler);
}
destroyStripe(): void {
this.card.removeEventListener('change', this.cardHandler);
this.card.destroy();
}
ngAfterViewInit() {
this.setupStripe();
}
ngOnDestroy() {
this.destroyStripe();
}
onChange({ error }) { /* ... */ }
Styles (I am using SASS)
.StripeElement
background-color: var(--dy-bg-1)
// I don't have access to font colors etc here
color: var(--dy-txt-1) !important
// !important also does not work
P.S.: It's important for me, that the variables will change at runtime (which is the reason I'm using CSS variables.
The Stripe documentation says
Elements creates UI components for you that are hosted by Stripe
i.e. their input fields are in a different document, so don't have access to your custom CSS variables.
A 'good enough' solution might be to read the CSS Custom Property values in your setupStripe method, and pass the values over as plain strings:
// Note: document.body is just an example:
const styles = getComputedStyle(document.body);
this.card = stripeElements.create("card", {
iconStyle: "solid",
style: {
base: {
iconColor: styles.getPropertyValue("--some-var")
// ...etc
}
}
});

Disconnect between adding a class and CSS getting applied [closed]

Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
Questions concerning problems with code you've written must describe the specific problem — and include valid code to reproduce it — in the question itself. See SSCCE.org for guidance.
Closed 9 years ago.
Improve this question
I'm having some annoying issues between Bootstrap/JQuery/my own CSS, tell me if this sounds like a problem you know how to fix.
I'm implementing my own "slider", with AJAX calls loading content onto the page depending on the navigation the user does. The problem comes in with my navbar. When an onhashchange event happens, I'm loading the correct content in, clearing the active class from the <li> element, and re-adding the active class to the appropriate <li> element.
Unfortunately, setting the active class isn't causing the appropriate CSS I have written to be applied, a slight darkening. There could be a million things causing THAT, I realize. But hardcoding an active class gives exactly the desired result. I don't know where the disconnect is. I ask myself, is a page loading problem getting in the way of the CSS being applied? I don't know.
Thanks in advance.
HTML:
...
<div class="collapse navbar-collapse navbar-ex1-collapse">
<ul class="sections nav navbar-nav">
<li>Call</li>
<li>Police</li>
<li>Charges</li>
<li>Jail</li>
<li>Courts</li>
<li>Resources</li>
</ul>
...
</div>
...
My CSS:
.navbar {
background-color: #231f20;
}
.navbar .sections>li>a:hover {
background-color: #4f4c4d;
}
/* Overriding */
.navbar a { color: #DDD !important; }
.navbar a:hover { color: #AAA !important; }
.navbar-nav>.active>a { background-color: #4f4c4d !important; }
My JS:
/* Constants */
var elem = $('.sections li a');
var pages = [];
for(i=0; i<elem.length; i++) {
//console.log(elem[i])
pages[i] = elem[i].hash;
}
var first = 0;
var last = pages.length;
...
function loadPage(hash, callback) {
/* Loads the content inside the "#main" element on the
page found at <url> into the "#main" element of the
current page. Then sets the links and buttons
accordingly. */
url = hash.split('#')[1] + '.html'
$('#main').load(url + "#main", callback);
setLinks(hash);
}
function setLinks(hash) {
for (i=0; i<=last; i++) {
if (pages[i] == hash) {
page_num = i;
}
}
var previous = page_num - 1;
var next = page_num + 1;
...
$('.sections li').removeClass('active');
$('.sections li').eq(page_num).addClass('active');
}
$(document).ready(function() {
...
$(window).on('hashchange', function() {
loadPage(window.location.hash);
});
});
You should make use of the callback functionality offered in the function loadpage. You are doing an asynchronic call, and directly applying the css. However, the page has not been updated yet (it takes some time). You should do something like this (only the updated functions):
function loadPage(hash, callback) {
/* Loads the content inside the "#main" element on the
page found at <url> into the "#main" element of the
current page. Then sets the links and buttons
accordingly. */
url = hash.split('#')[1] + '.html'
$('#main').load(url + "#main", callback);
// setLinks(hash); <-- don't do this, it will be executed to early!
}
$(document).ready(function() {
...
$(window).on('hashchange', function() {
loadPage(window.location.hash, setLinks); // <-- making use of the callback functionality
});
});
And remove the setLinks call from the loadPage function itself. By passing it in as the callback function, it will get executed once the $('#main').load is finished.

Fabric.js - problem with drawing multiple images zindex

I'm using this script:
var canvas = new fabric.Canvas('game_canvas', { selection: false });
fabric.Image.fromURL('images/bg.jpg', function(img) {
img.set('left', 1024/2).set('top', 600/2).set('zindex', 0);
canvas.add(img);
});
fabric.Image.fromURL('images/panel-2-bg-l-r.png', function(img) {
img.set('left', 262/2).set('top', (390/2)+110).set('zindex', 1);
canvas.add(img);
});
fabric.Image.fromURL('images/player-board.png', function(img) {
img.set('left', 254/2).set('top', (122/2)).set('zindex', 2);
canvas.add(img);
});
fabric.Image.fromURL('images/player-board-top-red.png', function(img) {
img.set('left', 203/2).set('top', (109/2)).set('zindex', 3);
canvas.add(img).bringToFront(img);
});
3rd image draw is working properly and showing one on top of the other. But if I add 4th one it's hiding behind 3rd. If I specify zindex of the image it's still under 3rd only.
What is wrong with this? Am I doing something wrong here? Please help.
Thanks
Peter
There are couple of issues here.
1) You can't change zindex of images by setting their zindex property. Fabric images simply don't have such property and changing it doesn't change z index of images on canvas. This makes all those .set('zindex', 0), .set('zindex', 1), etc. pretty much a no-op.
2) bringToFront works as expected here, bringing last image all the way to the top of the drawing stack. But the problem is that "images/player-board-top-red.png" image which you're loading last is not guaranteed to be the last one added. Those 4 requests are asynchronous; they are coming in any order, and so callbacks are executed in any order as well. In my test, for example, the last image comes second, callback executes, image is brought to the front, but is then "overwritten" by following 2 callbacks.
How to make last image render on top? Well, we can simply check that all images are loaded before attempting to bring last one to the top:
var img4;
// ...
function checkAllLoaded() {
if (canvas.getObjects().length === 4) {
canvas.bringToFront(img4);
}
}
// ...
fabric.Image.fromURL('images/1.png', function(img) {
img.set('left', 0).set('top', 0);
canvas.add(img);
checkAllLoaded(img);
});
// load other images, making sure to include `checkAllLoaded` in callback
fabric.Image.fromURL('images/4.png', function(img) {
img4 = img.set('left', 0).set('top', 0);
canvas.add(img);
checkAllLoaded(img);
});
By the way, don't forget that you can pass an object to set method like so:
img.set({ left: ..., top: ... });
And since set is chainable and returns reference to an instance, you can even pass it to add like so:
canvas.add(img.set({ left: ..., top: ... }));
Hope this helps.
You can use canvas.insertAt(object,index); instead of canvas.add(object) to set object's zIndex as per your choice.
Also you can get any object by using:
canvas_object = canvas.item(index);
If you want to bring that object in front, use:
canvas_object.bringForward()
//or
canvas_object.bringToFront()

Changing style of :hover selector in mootools

I have tried google, but I can not definite answer.
I am trying to edit the styles of #sidebar:hover from mootools. My css is as follows:
#hoverzone:hover {
background: #EEE;
}
Now, I am trying to edit the background color from mootools when the page loads, to signify javascript is enabled. I know I can do:
$('hoverzone').addEvent('mouseenter', function(){
this.setStyle('background','000');
});
But I was wondering if there is a function I could call at the load of the page, that does this in one line with out the user doing anything.
Thanks
Edit: Yes, I was rushing, and anciently typed over instead of mouseenter
you cannot target a pseudo selector with javascript. so you need to create a new CSS rule that overrides the old one.
http://jsfiddle.net/dimitar/Z9RPP/
var StyleWriter = new Class({
// css classes on the fly, based on by Aaaron Newton's old work
createStyle: function(css, id) {
try {
if (document.id(id) && id) return;
var style = new Element('style', {id: id||'',type:'text/css'}).inject(document.getElements('head')[0]);
if (Browser.ie)
style.styleSheet.cssText = css;
else
style.set('text', css);
} catch(e) {
//console.log("failed:", e);
}
}
});
new StyleWriter().createStyle("#hoverzone:hover { background:red;}", "foo");
You can use the events domready or load of the windows object.
For example something like:
window.addEvent('load', function(){
$('hoverzone').setStyle('background-color','000');
});
Why use javascript. Why not just css:
#hoverzone { background: #000 }
#hoverzone:hover { background: #EEE }