I'm working on this site where the product images are being shown with a little "color filtering" feature.
The problem is that both images are visible untill you hover over a color-box, because at that time my Javascript takes over and shows/hides the current image/color (see code in the bottom).
I'm using a plugin called Slimsy to Umbraco 7 which makes the cropUrl's responsive but it doesn't work if I put a display: none on the .categoryImage containers, it must be something within the plugins.
What I need is to NOT use display: none on each .categoryImage container, but somehow hide all the images except the first one so the plugin can determine the width/height/whatever it is it needs.
My javascript:
$(".frameColor").each(function () {
var categoryImage = $(this).parent("div").next("a").find(".categoryImage");
categoryImage.first().show();
if ($(categoryImage).length > 1) {
$(this).on('mouseover', function () {
var color = $(this).data('color').replace('#', '');
$(".frameColor").removeClass("active");
$(this).addClass("active");
$(categoryImage).hide().filter(function () {
return $(this).data('frame-color') === color;
}).show();
});
}
else {
$(this).hide();
}
});
My frame color:
#foreach (var bikeColor in images)
{
string color = bikeColor.GetPropertyValue("frameColor");
string[] colorSplit = color.Split(',');
if (colorSplit.Length == 1)
{
<div class="frameColor" data-color="##color" style="background-color:##colorSplit[0]"></div>
}
else
{
<div class="frameColor" data-color="##color" style="background-image:linear-gradient(-30deg, ##colorSplit[0] 0%, ##colorSplit[0] 50%, ##colorSplit[1] 50%, ##colorSplit[1] 60%);"></div>
}
}
To target all of .frameColor except for the first one, in your $.each() loop, you can do
$(".frameColor:not(:first)").each(function () {});
And to hide them without using display: none; you can use opacity: 0; or visibility: hidden;
Related
So currently, I have jQuery in a function that reduces a div to 20px when a certain toggle button is clicked. I want all the divs inside of that div to hide as well, but I don't want to resort to recursive functions/loops if at all possible. Currently, my toggle button kind of works, but when I hide a div all of its children (if it has any) remain where they were before. Can I simply force the height to 20px and make all the containing divs disappear as well? A good example of what I need would be like hiding a comment chain on a board (such as reddit). Thanks.
Sure, code:
function toggleComment(child)
{
if (child.innerHTML.includes("–"))
{
//Minimizing
child.innerHTML = "[+]";
$(child).parent().addClass("minimized");
hideChildren($(child).parent());
}
else
{
//Maximizing
child.innerHTML = "[–]";
$(child).parent().removeClass("minimized");
showChildren($(child).parent());
}
}
function hideChildren(parent)
{
for (var i = 0; i < parent.children().length; i++)
{
var child = parent.children().eq(i);
if (!child.hasClass('ignoreOnHide'))
{
parent.children().eq(i).hide();
}
if (child.has("div"))
{
hideChildren(child);
}
}
}
function showChildren(parent)
{
for (var i = 0; i < parent.children().length; i++)
{
var child = parent.children().eq(i);
parent.children().eq(i).show();
}
}
This code partially works. It visually functions as intended, but there become more complicated problems. I would like to not use recursive functions and loops, because, again, it doesn't work exactly as intended. The exact problems are difficult to explain and not pertinent to this question. Is there any other way to go about this problem, to minimize a div and completely hide its content, without loops & such?
Try adding
overflow: hidden;
to your parent div to hide the elements positioned outside its width/height.
You can use the CSS property 'overflow' such that the content of the div will be clipped.
.my_div { overflow: hidden; }
Playing with transitions, you may also hide the content using the 'opacity' style:
.my_div > * { opacity: 1; transition: opacity 2s ease; }
.my_div.reduced > * { opacity: 0; }
This will fade the content smoothly.
Use jQuery to hide the children of your container:
$('div.container div').fadeOut();
I have the following code:
$(document).ready(function() {
$('.anchor_clicker').click(function(){
if( $('.anchor_clicker').data('stored-height') == '930' ) {
$('.anchor_clicker').data('stored-height','100');
$('#desc').animate({height:'100'})
} else {
$('.anchor_clicker').data('stored-height','930');
$('#desc').animate({height:'930'})
}
})
});
Click
Right now I have text "Click" to do this but instead I want to have a default image icon when it is clicked the code above will expand the div and when clicked again it will shorten it. how can I use two different images instead of "CLick"?
Create a sprite with your arrows, Add a class to your CSS that will change the background position on jQuery click. Than just toggleClass('opened')
LIVE DEMO
$(document).ready(function() {
$('.anchor_clicker').on('click', function(e){
e.preventDefault();
var $btn = $(this);
$btn.toggleClass('opened');
var heights = $btn.hasClass('opened') ? 930 : 100 ;
$('#desc').stop().animate({height: heights });
});
});
CSS:
a.anchor_clicker{
padding-right: 16px
background:url(http://i.imgur.com/u3GpDiC.png?1?1426) no-repeat right 0;
}
a.anchor_clicker.opened{
background-position: right -16px;
}
The good part on having a sprite instead of 2 separate images is the removal of an additional request for the new image on click, and the time gap that is created by that request in showing the loaded new image.
Very simply, do this:
(FIDDLE)
CSS
.anchor_clicker
{
background-image:url(/path/to/sprite);
}
jQuery
$(document).ready(function() {
$('.anchor_clicker').click(function(){
if( $('.anchor_clicker').data('stored-height') == '930' ) {
$('.anchor_clicker').data('stored-height','100');
$('#desc').animate({height:'100'})
$(this).css('background-position','-50px 0px');
} else {
$('.anchor_clicker').data('stored-height','930');
$('#desc').animate({height:'930'});
$(this).css('background-position','0px 0px');
}
})
});
For two images rather than a sprite:
CSS
.anchor_clicker
{
background-image:url(/path/to/image1);
}
.anchor_clicker.b
{
background-image:url(/path/to/image2) !important;
}
jQuery
$(document).ready(function() {
$('.anchor_clicker').click(function(){
if( $('.anchor_clicker').data('stored-height') == '930' ) {
$('.anchor_clicker').data('stored-height','100');
$('#desc').animate({height:'100'})
$(this).addClass('b');
} else {
$('.anchor_clicker').data('stored-height','930');
$('#desc').animate({height:'930'});
$(this).removeClass('b');
}
})
});
$('.anchor_clicker').click(function(){
$(this).find('img').prop('src', function(src) {
return src === 'img1' ? 'img2' : 'img1'
})
})
You could change the src property of the image on the fly, based on the src. This is if you want to swap 2 different images.
But if you have a sprite with different images , then manipulating class is the way to go.
I am trying to use this menu for my wordpress site.
I am just wondering how can I make the float line change color for each nav item hovered/selected, cos it is red (background-color:#800; height:2px;) for all at the moment.
This is what I am trying to achieve:
Menu 1 - the hovering float line is green,
Menu 2 - the float line is yellow,
Menu 3 - red, menu4 - blue and so on.
Any help is appreciated.
Thank you.
There is a more "CSS" way to achieve this but with some javascript you can get something quite readable. With this approach, your pages will need to correctly initialize the float line (.hightlight) and the nav border (#sses1 > ul).
The ideal solution would be a class for each float lines but here's what I got with javascript only :
<!-- added individual classes for nav items -->
<div id="sse1">
<div id="sses1">
<ul>
<li><a class="nav-item-1" href="?menu=1&skin=2&p=Javascript-Menus">Javascript Menus</a></li>
<li><a class="nav-item-2" href="?menu=1&skin=2&p=Horizontal-Menus">Horizontal Menus</a></li>
<li><a class="nav-item-3" href="?menu=1&skin=2&p=Web-Menus">Web Menus</a></li>
</ul>
</div>
</div>
Before the body or window is loaded :
function customHandleMenu() {
// get nav selector
var nav = $('#sses1 > ul');
// get float line selector
var floatLine = $('.highlight'); // .hightlight must exist at this point
// get colors for the current page
var defaultBGcolor = floatLine.css('background-color');
var defaultBorderColor = floatLine.css('border-color');
var defaultNavBorderColor = nav.css('border-bottom-color');
// change background-color and border-color on mouseenter event
$('.nav-item-1').on({
mouseenter: function () {
setColors({floatColor:'#0f0', borderColor:'#0f0'});
}
});
$('.nav-item-2').on({
mouseenter: function () {
setColors({floatColor:'#ee0', borderColor:'#ee0'});
}
});
$('.nav-item-3').on({
mouseenter: function () {
setColors({floatColor:'#05f', borderColor:'#05f'});
}
});
/*
...
*/
// put back default colors on the mouseleave event
$('#sses1 > ul > li').on({
mouseleave: function() {
setColors({floatColor:defaultBGcolor, borderColor:defaultNavBorderColor});
}
});
function setColors(args) {
if (typeof args.floatColor != "undefined") {
floatLine.css('background-color', args.floatColor);
}
if (typeof args.borderColor != "undefined") {
floatLine.css('border-color', args.borderColor);
nav.css('border-bottom-color', args.borderColor);
}
}
}
To ensure that the selector is only use once .highlight exists, I suggest to modify the end of the original javascript to this:
function initMenu() {
sse1.builMenu();
customHandleMenu();
}
if (window.addEventListener) {
window.addEventListener("load", initMenu, false);
}
else if (window.attachEvent) {
window.attachEvent("onload", initMenu);
}
else {
window["onload"] = initMenu;
}
Take a look at this jsfiddle.
P.S.: the event chain is slighly modified to fit into jsfiddle.
What you're asking for is actually non-trivial. The author of the plugin is actually animating an li element's, "li.highlight", width and left positioning based on where you hover the mouse. You can easily change the color of this thing by altering the CSS definition for this item. For example to make it yellow, just include this css definition below the menu's css file:
#sses1 li.highlight {
background-color: yellow;
top: 36px;
height: 2px;
border-bottom: solid 1px yellow;
z-index: 1;
position: absolute;
overflow: hidden;
}
I know this isn't the complete solution... but, if you're ambitious you could alter the javascript add a new class depending on which li element the .highlight element is under.
I have a CSS menu that sets the parent li's color when hovering over it and it's child ul (submenu). Basically, when you hover over the menu, it changes colour and remains that way until you mouseoff the menu and it's submenu. It looks nice.
I've added some jQuery code to change the colour of the menu items when until a certain page is opened. Then, those menus will fade back in and regain colour. At which point, waiting for a hover to change colour.
The problem I'm having is, when you change the colour back to it's original state (set in CSS) with jQuery, it removes the :hover class preventing the colour change when hovering over it and it's child submenu. Any ideas on how to fix this? Is there a selector with jQuery that'll allow me to set the :hover class back to normal?
/* ---- Menu Colours ---- */
$(document).ready(function()
{
var colours = ['d50091', 'c8fa00', '00b4ff', 'b158fc', 'ffa800', '00b72f'];
var counter = 0; // Loop for the colurs
var status = 0; // Status of the colours (greyed out or visible)
$('ul.menu-horiz').children('li').children('a').hover(function()
{
$(this).parent()[0].css('color', '#d50091');
}, function()
{
$(this).parent()[0].css('color', '#b6b6b6');
});
$('ul.menu-horiz').children('li').children('a').each(function()
{
$(this).css({opacity: 0.2, color: '#' + colours[counter]});
counter++;
});
$('.haccordion .header').click(function()
{
if (window.location.hash.substr(1) == 'photogallery')
{
$('ul.menu-horiz').children('li').children('a').each(function()
{
if ($(this).css('opacity') != '1.1')
{
$(this).animate({opacity: 1.1}, 1000).css('color', '#b6b6b6');
}
});
}
else
{
counter = 0;
if ($('ul.menu-horiz').children('li').children('a').css('opacity') != '0.2')
{
$('ul.menu-horiz').children('li').children('a').animate({opacity: 0.2}, 1000, function()
{
$('ul.menu-horiz').children('li').children('a').each(function()
{
$(this).css('color', '#' + colours[counter]);
counter++;
});
});
}
}
});
});
You should be able to use the :hover selector and pass in an over() and out() function that set and unset the hover color respectively. See the :hover documentation for more.
Simple Example
given the CSS:
<style>
.blue { background-color: blue; }
.red { background-color: red; }
</style>
do something like this:
$('li').hover(function() {
$(this).removeClass('red');
$(this).addClass('blue');
},
function() {
$(this).removeClass('blue');
$(this).addClass('red');
})
I was having issues applying the colour change to the when hovering over it's parent (as you can see in the code posted above).
Took me until now to realise it needed to be changed to
$('ul.menu-horiz').children('li').hover(function()
{
$(this).children('a').css('color', '#d50091');
}, function()
{
$(this).children('a').css('color', '#b6b6b6');
});
Ignore me >_>
Is it possible to set the cursor to 'wait' on the entire html page in a simple way? The idea is to show the user that something is going on while an ajax call is being completed. The code below shows a simplified version of what I tried and also demonstrate the problems I run into:
if an element (#id1) has a cursor style set it will ignore the one set on body (obviously)
some elements have a default cursor style (a) and will not show the wait cursor on hover
the body element has a certain height depending on the content and if the page is short, the cursor will not show below the footer
The test:
<html>
<head>
<style type="text/css">
#id1 {
background-color: #06f;
cursor: pointer;
}
#id2 {
background-color: #f60;
}
</style>
</head>
<body>
<div id="id1">cursor: pointer</div>
<div id="id2">no cursor</div>
Do something
</body>
</html>
Later edit...
It worked in firefox and IE with:
div#mask { display: none; cursor: wait; z-index: 9999;
position: absolute; top: 0; left: 0; height: 100%;
width: 100%; background-color: #fff; opacity: 0; filter: alpha(opacity = 0);}
<a href="#" onclick="document.getElementById('mask').style.display = 'block'; return false">
Do something</a>
The problem with (or feature of) this solution is that it will prevent clicks because of the overlapping div (thanks Kibbee)
Later later edit...
A simpler solution from Dorward:
.wait, .wait * { cursor: wait !important; }
and then
Do something
This solution only shows the wait cursor but allows clicks.
If you use this slightly modified version of the CSS you posted from Dorward,
html.wait, html.wait * { cursor: wait !important; }
you can then add some really simple jQuery to work for all ajax calls:
$(document).ready(function () {
$(document).ajaxStart(function () { $("html").addClass("wait"); });
$(document).ajaxStop(function () { $("html").removeClass("wait"); });
});
or, for older jQuery versions (before 1.9):
$(document).ready(function () {
$("html").ajaxStart(function () { $(this).addClass("wait"); });
$("html").ajaxStop(function () { $(this).removeClass("wait"); });
});
I understand you may not have control over this, but you might instead go for a "masking" div that covers the entire body with a z-index higher than 1. The center part of the div could contain a loading message if you like.
Then, you can set the cursor to wait on the div and don't have to worry about links as they are "under" your masking div. Here's some example CSS for the "masking div":
body { height: 100%; }
div#mask { cursor: wait; z-index: 999; height: 100%; width: 100%; }
This seems to work in firefox
<style>
*{ cursor: inherit;}
body{ cursor: wait;}
</style>
The * part ensures that the cursor doesn't change when you hover over a link. Although links will still be clickable.
I have been struggling with this problem for hours today.
Basically everything was working just fine in FireFox but (of course) not in IE.
In IE the wait cursor was showing AFTER the time consuming function was executed.
I finally found the trick on this site:
http://www.codingforums.com/archive/index.php/t-37185.html
Code:
//...
document.body.style.cursor = 'wait';
setTimeout(this.SomeLongFunction, 1);
//setTimeout syntax when calling a function with parameters
//setTimeout(function() {MyClass.SomeLongFunction(someParam);}, 1);
//no () after function name this is a function ref not a function call
setTimeout(this.SetDefaultCursor, 1);
...
function SetDefaultCursor() {document.body.style.cursor = 'default';}
function SomeLongFunction(someParam) {...}
My code runs in a JavaScript class hence the this and MyClass (MyClass is a singleton).
I had the same problems when trying to display a div as described on this page. In IE it was showing after the function had been executed. So I guess this trick would solve that problem too.
Thanks a zillion time to glenngv the author of the post. You really made my day!!!
Easiest way I know is using JQuery like this:
$('*').css('cursor','wait');
css: .waiting * { cursor: 'wait' }
jQuery: $('body').toggleClass('waiting');
Why don't you just use one of those fancy loading graphics (eg: http://ajaxload.info/)? The waiting cursor is for the browser itself - so whenever it appears it has something to do with the browser and not with the page.
To set the cursor from JavaScript for the whole window, use:
document.documentElement.style.cursor = 'wait';
From CSS:
html { cursor: wait; }
Add further logic as needed.
Try the css:
html.waiting {
cursor: wait;
}
It seems that if the property body is used as apposed to html it doesn't show the wait cursor over the whole page. Furthermore if you use a css class you can easily control when it actually shows it.
Here is a more elaborate solution that does not require external CSS:
function changeCursor(elem, cursor, decendents) {
if (!elem) elem=$('body');
// remove all classes starting with changeCursor-
elem.removeClass (function (index, css) {
return (css.match (/(^|\s)changeCursor-\S+/g) || []).join(' ');
});
if (!cursor) return;
if (typeof decendents==='undefined' || decendents===null) decendents=true;
let cname;
if (decendents) {
cname='changeCursor-Dec-'+cursor;
if ($('style:contains("'+cname+'")').length < 1) $('<style>').text('.'+cname+' , .'+cname+' * { cursor: '+cursor+' !important; }').appendTo('head');
} else {
cname='changeCursor-'+cursor;
if ($('style:contains("'+cname+'")').length < 1) $('<style>').text('.'+cname+' { cursor: '+cursor+' !important; }').appendTo('head');
}
elem.addClass(cname);
}
with this you can do:
changeCursor(, 'wait'); // wait cursor on all decendents of body
changeCursor($('#id'), 'wait', false); // wait cursor on elem with id only
changeCursor(); // remove changed cursor from body
I used a adaptation of Eric Wendelin's solution. It will show a transparent, animated overlay wait-div over the whole body, the click will be blocked by the wait-div while visible:
css:
div#waitMask {
z-index: 999;
position: absolute;
top: 0;
right: 0;
height: 100%;
width: 100%;
cursor: wait;
background-color: #000;
opacity: 0;
transition-duration: 0.5s;
-webkit-transition-duration: 0.5s;
}
js:
// to show it
$("#waitMask").show();
$("#waitMask").css("opacity"); // must read it first
$("#waitMask").css("opacity", "0.8");
...
// to hide it
$("#waitMask").css("opacity", "0");
setTimeout(function() {
$("#waitMask").hide();
}, 500) // wait for animation to end
html:
<body>
<div id="waitMask" style="display:none;"> </div>
... rest of html ...
My Two pence:
Step 1:
Declare an array. This will be used to store the original cursors that were assigned:
var vArrOriginalCursors = new Array(2);
Step 2:
Implement the function cursorModifyEntirePage
function CursorModifyEntirePage(CursorType){
var elements = document.body.getElementsByTagName('*');
alert("These are the elements found:" + elements.length);
let lclCntr = 0;
vArrOriginalCursors.length = elements.length;
for(lclCntr = 0; lclCntr < elements.length; lclCntr++){
vArrOriginalCursors[lclCntr] = elements[lclCntr].style.cursor;
elements[lclCntr].style.cursor = CursorType;
}
}
What it does:
Gets all the elements on the page. Stores the original cursors assigned to them in the array declared in step 1. Modifies the cursors to the desired cursor as passed by parameter CursorType
Step 3:
Restore the cursors on the page
function CursorRestoreEntirePage(){
let lclCntr = 0;
var elements = document.body.getElementsByTagName('*');
for(lclCntr = 0; lclCntr < elements.length; lclCntr++){
elements[lclCntr].style.cursor = vArrOriginalCursors[lclCntr];
}
}
I have run this in an application and it works fine.
Only caveat is that I have not tested it when you are dynamically adding the elements.
BlockUI is the answer for everything. Give it a try.
http://www.malsup.com/jquery/block/
This pure JavaScript seems to work pretty well ... tested on FireFox, Chrome, and Edge browsers.
I'm not sure about the performance of this if you had an overabundance of elements on your page and a slow computer ... try it and see.
Set cursor for all elements to wait:
Object.values(document.querySelectorAll('*')).forEach(element => element.style.cursor = "wait");
Set cursor for all elements back to default:
Object.values(document.querySelectorAll('*')).forEach(element => element.style.cursor = "default");
An alternative (and perhaps a bit more readable) version would be to create a setCursor function as follows:
function setCursor(cursor)
{
var x = document.querySelectorAll("*");
for (var i = 0; i < x.length; i++)
{
x[i].style.cursor = cursor;
}
}
and then call
setCursor("wait");
and
setCursor("default");
to set the wait cursor and default cursor respectively.
Lots of good answers already, but none of them mentions the <dialog> element.
Using this element we can create a solution similar to the masking <div>.
Here we use showModal() to "hide" elements, and we use ::backdrop to set the cursor style to wait on the entire page:
function showWaitDialog() {
document.getElementById('id_dialog').showModal();
}
#id_dialog, #id_dialog::backdrop {
cursor: wait;
}
<button onclick="showWaitDialog()">click me</button>
<dialog id="id_dialog">busy...</dialog>
The dialog is hidden by default, and can be shown using either the show() method, or the showModal() method, which prevents clicking outside the dialog.
The dialog can be forced to close using the close() method, if necessary.
However, if your button links to another page, for example, then the dialog will disappear automatically as soon as the new page is loaded.
Note that the dialog can also be closed at any time by hitting the Esc key.
CSS can be used to style the dialog however you like.
The example uses the html onclick attribute, just for simplicity. Obviously, addEventListener() could also be used.
Late to the party but simply give the Html tag an id by targeting
document.documentElement
and in the CSS place at the top
html#wait * {
cursor: wait !important;
}
and simply remove it when you want to stop this cursor.