I want to change ng-style multiple times in a JS function - javascript

My HTML is:
<nav id="card-set-menu-nav" ng-style="cardSetMenuNavStyle">
...
</nav>
And my Javascript code using AngularJS is like:
$scope.openCardSetMenu = function(cardSet) {
$scope.cardSetMenuNavStyle = {'transition':'0.25s', 'left':'100%'};
$scope.cardSetMenuNavStyle = {'transition':'0.25s', 'left':'50%'};
};
I want to implement simple side menu by changing $scope.cardSetMenuNavStyle variable.
HTML element card-set-menu-nav will be put at left:100% then be pulled out to left:50% like.
But it does not work. It does not move at all after the first unfolding... Maybe transitions are ignored because the final result is the same?
How can I apply multiple CSS transitions on an HTML element?
Add:
Considering the transition time, it seems like only the last transition is applied.

Overwriting a property with two different values one line after the other will not do you any good. Only the last one assigned will have any effect.
If you want to apply one style change, and then apply another 0.25s later, you can inject the $timeout service and use it:
$scope.openCardSetMenu = function(cardSet) {
$scope.cardSetMenuNavStyle = {'transition':'0.25s', 'left':'100%'};
$timeout(function () {
$scope.cardSetMenuNavStyle = {'transition':'0.25s', 'left':'50%'};
}, 250);
};

Related

Trigger a fade when swapping between classes using jQuery

I have following code working so far: JSFIDDLE DEMO
The relevant JS is here:
// Define classes & background element.
var classes = ['bg1','bg2','bg3','bg4'],
$bg = document.getElementById('blah');
// On first run:
$bg.className = sessionStorage.getItem('currentClass') || classes[0];
// On button click:
$('.swapper').mousedown(function () {
// (1) Get current class of background element,
// find its index in "classes" Array.
var currentClassIndex = classes.indexOf($bg.className);
// (2) Get new class from list.
var nextClass = classes[(currentClassIndex + 1)%classes.length];
// (3) Assign new class to background element.
$bg.className = nextClass;
// (4) Save new class in sessionStorage.
sessionStorage.setItem('currentClass', nextClass);
});
For my purposes, this functionally working great -- I can click a single button to continually swap between those four classes while also storing the current class to sessionStorage, so that when I click links on my website, the currentClass is loaded right away. (Note: on my website the setup is the same, but the classes bg1, bg2, bg3, and bg4 contain background images.)
What I'd like it to do:
When swapping from one class to another, I'd like it to do a quick/short cross-fade. Right now it just snaps from one class/background to another.
My thinking was: is there a way I can trigger a CSS class transition or animation that contains the fade, perhaps as a parent class? I know there's a jQuery fade function, but I haven't been able to get it working with my setup so that it triggers on mouseClick.
Here's an updated jsfiddle based on your comment where you said you've sort of having it work.
I've added the timeout functions
setTimeout(function(){$bg.className = nextClass}, 500);
setTimeout(function(){$($bg).fadeIn(500)}, 500)
The first timeout makes it so that the image is swapped right after the first image fades out. The second timeout gives it a bit of time to load in so it's not so jittery.
You can play with the }, 500); number to get it timed just like you want, 500 is half a second, 1000 is a second etc.

Javascript cannot unhide element after cloning?

I'm working on something where multiple functions will add various Event listeners to an initially hidden div, let's just call it secretBlock. Only one will ever be active at any given point, but all said functions will manipulate it by:
First cloning sercetBlock to ensure no previous listeners are still attached
Then setting the display to flex
HTML:
<div id="secretBlock" hidden>Secret</div>
JavaScript:
function exampleFuction() {
var secretBlock = document.getElementById('secretBlock');
var secretClone = secretBlock.cloneNode(true);
secretBlock.parentNode.replaceChild(secretClone, secretBlock);
secretBlock.style.display = 'flex';
....
}
but the last part, setting the display, is not firing.
I assumed this had something to do with async-ness, but
setTimeout(function(){ secretBlock.style.display = 'flex' }, 999);
also had no effect.
However, one of the functions appends the div inside of another div right after setting the display, causing it to fire properly:
secretBlock.parentNode.replaceChild(secretClone, secretBlock);
secretBlock.style.display = 'flex';
otherDiv.appendChild(secretBlock);
After a bit of testing, I found out it doesn't matter when I set the display (now vs later) or where it is in the code, as long as secretBlock gets appended to another div, the display change will register, otherwise staying hidden.
.......which sorta left me clueless as to what's going on, any insight would thus be much appreciated~~
Was a reference issue.
After .replaceChild() replaces secretBlock, the initial reference:
var secretBlock = document.getElementById('secretBlock')
becomes obsolete as it still points to the old, original element which is not apart of the html document anymore. Thus you need to redirect the reference to the cloned element:
secretBlock.parentNode.replaceChild(secretClone, secretBlock);
secretBlock = document.getElementById('secretBlock');
secretBlock.style.display = 'flex';
Thanks Dr.Molle!

fadeIn() / fadeOut() animation not playing

Below I have this piece of code which I use to filter products with using a drop-down menu. The content of the #child_cat division changes based on the value attribute of the anchor tag:
$('#brandsort').change(function(){
$('#child_cat a').fadeOut(500);
$('[value="' + $(this).val() + '"]').fadeIn();
if ($('#brandsort option:selected').text() === "") {
$('#child_cat a').fadeIn(500);
}
});
The code will filter out the products that do not match their option value, but it won't play the animation. Right now, it acts more like a delayed .show() / .hide() function than anything. Please enlighten me from any wrongdoing in my code or what I could possibly be doing wrong aside from that.
EDIT:
I know the people on SO would normally like some hands-on help from one of you, but in this case I was specifically only asking for "enlightenment". Just some verbal input of what I could have been doing wrong.
To fulfill your request of providing some HTML, you'll find it here: http://jsfiddle.net/HJPN8/3/
There was a few mistakes in the logic that made this not work. Firstly, the reason you couldn't see the fade animate happen is because fade uses the css property opacity. Opacity only works on block and inline-block elements, and you were using the .fadeOut() on a tags which are display:inline. So that can be fixed easily with this:
#child_cat a{
display:block;
}
Next you're using .fadeOut() and .fadeIn() which both run at the same time meaning that the animations would both collide and not work properly. So you need to use callback functions to correctly time them. Below is the code I have refactored, I've included a lot of comments so you can see how it all works. The fade functions have been replaced with .animate() which is a lower end function that gives you more control which we need in this situation.
One last thing is that you were using the value attribute on your products, this isn't recommended as this property is specific to the options tag. If you wish to create custom attributes then the standard way is to prepend them with "data-" which you can see I've done here: http://jsfiddle.net/HJPN8/6/
$(function(){
var brandsort = $('#brandsort');
var products = $('#child_cat a');
brandsort.on('change', function(e){
var val = brandsort.val();
// If search is blank then select all products to show else filter specific products.
var filteredProducts = (val == '') ? products : products.filter('[data-value="' + val + '"]');
// Hide products and set callback for when the animation has finished.
// If we don't use a callback, the products will animate out and in at the same time, ruining the effect.
products.animate({opacity: 0}, 300).promise().done(function(){
// Now that he products' opacity is 0, we set them to display block to remove them from the flow of the DOM.
products.css({display: 'none'});
// Now Bring the filtered products back and animate them in again.
filteredProducts.css({display: 'block'}).animate({opacity: 1}, 500);
});
});
});

Possible to "listen" to a CSS value for a DOM element and tell another DOM element to match it?

I'm trying to hack Drupal's colorpicker module so that as my user drags it around picking colors, he sees colors changing on the web site's in real-time.
Right now the colorpicker's js changes the color of the picker widget in real-time.
I want to hack the js so that the color of the picker widget AND a specific DOM element change background colors at once.
Is there a way I can write some code that "listens" to the background-color setting of the colorpicker input and then changes the background-color of ?
Here's the code where Drupal is applying settings from the colorpicker widget to its input:
Drupal.behaviors.colorpicker = function(context) {
$("input.colorpicker_textfield:not(.colorpicker-processed)", context).each(function() {
var index = $('body').find('input.colorpicker_textfield').index($(this));
Drupal.colorpickers[index] = new Drupal.colorpicker($(this).addClass('colorpicker-processed'));
Drupal.colorpickers[index].init();
});
What can I add to this to tell it to "listen" to the background color of "input.colorpicker_textfield" and then set that value to "body" in real time as it changes?
Try using change() to apply it to the bg.
$("input").change( function () {
//var below would obviously have to be correctly formatted.
var newColor$(this).val();
$(body).css({background-color: newColor});
});
Similar to Cole's answer with some improvements (assuming '#' is not included by the colorpicker):
$('input.colorpicker_textfield').live('change', function() {
var color = this.value;
if(color.search((/^[A-Fa-f0-9]{6}/) != -1) {
body.style.backgroundColor = '#'+this.value;
}
});
Uses more specific selector
uses the 'live' event handling method, ensuring the handler will be attached to any dynamically created colorpickers
It will not change the background color if the input is not a hex value
It uses the style attribute directly instead of wrapping in the jQuery object.

How can I undo the setting of element.style properties?

I have an element in my document that has a background color and image set through a regular CSS rule.
When a certain event happens, I want to animate that item, highlighting it (I'm using Scriptaculous, but this question applies to any framework that'll do the same).
new Effect.Highlight(elHighlight, { startcolor: '#ffff99', endcolor: '#ffffff', afterFinish: fnEndOfFadeOut });
The problem i'm facing is that after the animation is done, the element is left with the following style (according to FireBug):
element.style {
background-color:transparent;
background-image:none;
}
Which overrides the CSS rule, since it's set at the element level, so I'm losing the background that the item used to have...
What I'm trying to do is, in the callback function I'm running after the animation is done, set the style properties to a value that'll make them "go away".
var fnEndOfFadeOut = function() {
elHighlight.style.backgroundColor = "xxxxx";
elHighlight.style.backgroundImage = "xxxxx";
}
What I'm trying to figure out is what to put in "xxxx" (or how to do the same thing in a different way).
I tried 'auto', 'inherit', and '' (blank string), and neither worked (I didn't really expect them to work, but I'm clueless here).
I also tried elHighlight.style = ""; which, expectably, threw an exception.
What can I do to overcome this?
I know I can put a span inside the element that I'm highlighting and highlight that span instead, but I'm hoping I'll be able to avoid the extra useless markup.
Chances are you're not setting the style on the correct element. It's probably being set somewhere up the line in a parent node.
elHighlight.style.backgroundColor = "";
elHighlight.style.backgroundImage = "";
You can also remove all the default styling by calling:
elHighlight.style.cssText = "";
In any case, you'll still have to do this on the specific element that is setting these properties, which means you may need to do a recursion on parentNode until you find it.
Try
elHighlight.style.removeProperty('background-color')
elHighlight.style.removeProperty('background-image')
have you tried elHightlight.style.background = "";?
I have a highlighter code on my site and this works
function highlight(id) {
var elements = getElementsByClass("softwareItem");
for (var ix in elements){
elements[ix].style.background = ""; //This clears any previous highlight
}
document.getElementById(id).style.background = "#E7F3FA";
}
An HTML element can have multiple CSS classes. Put your highlight information inside a CSS class. Add this class to your element to highlight it. Remove the class to undo the effect.

Categories

Resources