Jquery next() function not returning class - javascript

I am still trying to get the hang of the next() function in jQuery. I have created a hover function, when you hover the image, a transparent overlay appears per image
Click here for an example
For some reason my next() is not working, I am assuming my jQuery set up is incorrect. Below is an a snippet of my code:
$(document).ready(function () {
var $this = $(this);
$('.dummy').removeClass('overlay2');
$this.parent().next('.dummy').addClass('overlay2');
});
});
Can someone correct where I have gone wrong?

This can be easily accomplished without using any javascript:
.dummy {
height: 100%;
width: 100%;
position: absolute;
top:0;
background: #000;
opacity: 0.50;
display: none;
}
.figure-item:hover .dummy{
display: block;
}
I just changed .overlay2 to .dummy in your stylesheet and added display: none;, then made it so hovering over .figure-item sets .dummy to display: block;.
Here it is working: http://jsfiddle.net/zaX5U/6/
Old JS Solution:
This should work for you:
$(document).ready(function () {
$('.figure-img').on('mouseenter mouseleave', function(e){
var $this = $(this),
toggle = e.type === 'mouseenter';
$('.dummy').removeClass('overlay2');
$this.find('.dummy').toggleClass('overlay2', toggle);
});
});
The reason your previous code wasn't working was because it looked like you'd forgotten to include the line with the event handler in (there was an unmatched }): in the fiddle). This meant that $(this) was actually document and so the code didn't work.
.hover() interally maps to .on( "mouseenter mouseleave" and in this case it makes the code smaller to use the full version. This also use the .toggleClass() function with the optional switch argument to either remove or add the class depending on the type of event.
Fiddle: http://jsfiddle.net/zaX5U/4/

Related

mxgraph: I would like to add a button to disable/enable the graph and toolbar

I tried to disable the graph by not allowing the cells on graph with follow code.
graph.setCellsSelectable(false);
but it is not working, still can select cell, (only disabled resizing)
And for the toolbar to be disabled, I tried to remove or replace ondrag event, is that correct? In theory I think mxgraph has their own event handler for dragging of toolbar item.
mx_toolbar.appendChild(
mxUtils.button("Disable/Enable", function() {
document.querySelectorAll('.toolbar > button').addEventListener(function (e) {
e.preventDefault()
return false;
});
}
)
Hope your help. I dont mind as long as it is working solution.
Thanks
Instead of removing or modifying the event handler, you can simply overlay the area you want to disable along with css.
var toolbarContainer = document.querySelector(".toolbar");
var overlay = document.querySelector(".toolbar-overlay")
if (!overlay) {
overlay = document.createElement('div')
overlay.className = 'toolbar-overlay'
toolbarContainer.appendChild(overlay)
} else {
overlay.parentNode.removeChild(overlay)
}
Here is css for the overlay div
.toolbar-overlay {
position: absolute;
top: 0;
height: 100%;
width: 100%;
opacity: 0.4;
background: #e1e1e1;
}
Note: You should make sure the parent div of the overlay div must positioned as relative to make this css working!

Page jumps abit up when an element above fades in

I have 2 elements, the first one (at the top) has the following CSS properties:
header {
position: relative;
height: 100%;
width: 100%;
background-color: black;
}
This makes it in the size of the browser's viewport, what I did on purpose because I wanted that result. I also had to give the html, body element the CSS property's for this to work (filling the screen with the first element):
html, body {
height: 100%;
width: 100%;
}
The second element I have looks like this:
#content {
display: none;
position: relative;
height: 1500px;
width: 100%;
background-color: yellow;
}
This element is underneath the first one.
As you can see, this element is hidden. That's because when I click on the button on the first element (which you can see in the jsFiddle) it shows the #content element, scrolls to that, and hides the element where we came from (header) when it's done scrolling.
Which works perfectly, I've got the function here:
var showScrollHide = function(showTime, element, eleTime, hide, hideTime, func) {
var _ele = $(element),
_hide = $(hide);
_ele.fadeIn(showTime, function() {
$('html, body').animate({
scrollTop: _ele.offset().top
}, eleTime, function() {
_hide.fadeOut(hideTime, func ? func : null);
});
});
};
I'm calling that function by this piece of code:
$('.exploreBtn').on('click', function() {
showScrollHide(500, content, 1000, header, 250, function() {
$(window).scrollTop(0);
$('.scrollBackBtn').fadeIn();
});
});
In the snippet above I had to call $(window).scrollTop(0); otherwise it would scroll down the page a bit when it was done scrolling. Also I displayed the scroll back button now, but that is the problem.
When I'm on the second element, and the element above it is hidden by the function above. And I try to use the same function to scroll it back up which means:
Show the element above
Scroll to it
Fade out the element we came from
It only gives me a fade to the element I'm trying to scroll to.
When I removed all the code from the function, and only used this:
$('header').fadeIn();
It just did the same and automatically faded the screen to that element we have just faded in. Which means it scrolls up, but not with any animation or what so ever.
Here is a jsFiddle to show what I'm doing
Btw, I already fixed this issue with the help of #Loktar with this piece of code, but I'm still not sure if its the right way to do it:
$('.scrollBackBtn').on('click', function() {
$(window).scrollTop(0);
$(header).slideDown();
});
If I am understanding it correctly the following should work.
_scrollBackBtn.on('click', function() {
_window.scrollTop(0);
$(header).slideDown();
});
Live Demo

Replace image on hover

I'm trying to replace an image with another image.
Since the webpage, that i'm building, has to be viewable in IE8, then CSS based solutions played out quircky.
I tried the
display: none; and display: block; trick
opacity: 0; and opacity: 1; trick
But they both don't function as I want to (centered inside a div, because IE8 plays some stuff differently, then I thought that may-be a simple src="" swaping will do the trick.
I started with jquery, but since I'm pretty bad with understanding the $(this) and DOM, then it isnt working at all, but i think I got my logic right.
So, HTML is here:
<div class="wrapper">
<a href="#">
<img class="original" src="http://placekitten.com/200/200">
<img class="overlay" src="http://placekitten.com/g/200/200">
</a>
…
…
So I have numerous a tags inside a wrapper, each containing two images. As they are responsive and having the same ratio, then no sizes are needed.
And my started jquery:
$('.wrapper a').hover(
function () {
var original = $(this).attr('src');
var overlay = $(this).next().attr('src');
$(this).children('.original').attr('src', overlay);
},
function () {
$(this).children('.original').attr('src', original);
}
);
And here's the JSFiddle .
So, I'm really after this, that each a tag I have inside a wrapper would change the image according to the images inside of that tag.
You don't need javascript here at all. Really. Use CSS:
.wrapper a:hover .original {
display: none;
}
.wrapper a:hover .overlay {
display: inline-block;
}
Demo: http://jsfiddle.net/hHyh6/10/
You should simply show overlay image on hover and hide original image
$('.wrapper a').hover(function () {
$(this).find('.original').toggle();
$(this).find('.overlay').toggle();
}, function () {
$(this).find('.original').toggle();
$(this).find('.overlay').toggle();
});
DEMO
Instead you can try this:
$('.overlay').hide(); //<----------first hide the overlay image
$('.wrapper a').hover(function () {
$(this).find('.overlay').show().add(this).find('.original').hide();
// here find the overlay and show it and hide the original
}, function () {
$(this).find('.overlay').hide().add(this).find('.original').show();
// here find the overlay and hide it and show the original
});
Demo # Fiddle using .end()
Demo # Fiddle using .add(this)
try this js i also tried in your fiddle too it works
var current_cash;
$('.wrapper a').hover(
function () {
current_cash = $(this).find('.original').attr('src');
var overlay = $(this).find('.overlay').attr('src');
$(this).children('.original').attr('src', overlay);
},
function () {
$(this).children('.original').attr('src', current_cash);
}
);

Temporarily disable all onclick events and bind them back

How to disable all onclick events on a page, bind my custom function, and after the execution enable all the previous events?
I'm building a bookmarklet, which should work on any already loaded page and I'm using jQuery to handle my custom logic (the page is jquerified after it is loaded). Note, that I don't have any control which events and when are being bound.
Currently the best stable solution i found is to unbind the events, bind by custom function preventing the default action and then, reload the page. This works, however I want to avoid the reload. A partial workaround would be to reload the page and scroll to the previous position (how to achieve this effect?). Some possible solution would use iframes, but I'd prefer to avoid this.
it's easier to lay a div-element over all... something like
CSS
.noclick {
position: absolute;
top: 0;
right: 0;
bottom: 0;
left: 0;
z-index: 9999; /* or maybe higher */
background-color: transparent;
}
jQuery
jQuery(document).ready(function() {
jQuery('body').append('<div class="noclick" />');
});
A nice way I've seen it done, and done it myself is to use a modal 'mask' overlay.
The grayed out transparent mask that covers the entire page, except for the element you're interacting with, eg. modal popup window.
One more way is to use the jQuery BlockUI plugin.
You can reassign the onclick to another property and than override it.
Example with one element
var btn = document.getElementById("button");
btn._onclick = btn.onclick;
btn.onclick = function(){ return false; };
and when you want to transfer it back to the original event
var btn = document.getElementById("button");
if (btn._onclick) {
btn.onclick = btn._onclick;
btn._onclick = null;
}
It depends on whether your onclick event is dependent on the element being clicked (i.e. whether it needs to know which element was clicked):
If it's independent, then you can just add an event handler to the body element or other parent (because the parent event gets called first, then the child, which is what you want):
$('body').click(function() { /* your code here */});
It it is dependent on the the element, then you can access the previous onclick event code that has been registered in the 'click' property of element which is being clicked, so something like this (probably being a little more specific with the selectors):
$('body *').each(function() {
var previousClick = this.click;
this.click = null; // remove previous
$(this).click(function() { /* your code here */});
$(this).click(function() { previousClick();}); // run the code that was already there.
})
Some modification algorhythm's answer.
The idea is to "cover" the link by a transparent element. You can use a pseudo element (e.g. :after).
To prevent "tab key" set tabindex:
<a href="..." tabindex="-1">
Mark link with a class "disabled" on click:
$('a').on('click', function(){ $(this).addClass('disabled') })
Add css:
a.disabled:after {
position: absolute;
content: "";
display: block;
background: white;
opacity: 0.5; // optional
z-index: 999;
left: 0;
top: 0;
bottom: 0;
right: 0;
}
$('a').on('click', function(){ $(this).addClass('disabled') });
a.disabled:after {
position: absolute;
content: "";
display: block;
background: white;
opacity: 0.5; // optional
z-index: 999;
left: 0;
top: 0;
bottom: 0;
right: 0;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<a hreh="#" tabindex="-1">The Link</a>

Wait cursor over entire html page

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.

Categories

Resources