Prevent label active state using javascript - javascript

I have a quite simple scenario where I am trying to prevent the orange background on mouse down:
document.querySelector('label').addEventListener('mousedown', (event) => {
console.log('mouse down')
event.preventDefault();
})
label:active {
background: orange;
}
<label>Press mouse down</label>
Unfortunately the event.preventDefault() has no effect and the label becomes orange. (Tested in Chrome and Safari and IE11)
Can anyone explain me the reason behind that or maybe tell me how to prevent the active state programatically without hacks?
Codepen: https://codepen.io/anon/pen/pPZVrO

It seems like an old issue. If you want, you can fix it, by using pointer-events property. Also, support for the same is pretty much decent (including IE11)
label:active {
background: orange;
}
label {
pointer-events: none;
}
<label>Press mouse down</label>
Make sure you have some class or an id declared on the label element so that you don't target all of them.
JavaScript Solution - Just giving a shot
The idea is to add a class on mousedown and override it with CSS class having an :active pseudo class, and later, remove the class on mouseup .. something like
var overrideActive = function() {
var labelElm = document.querySelector('label');
var bodyElm = document.querySelector('body');
function init() {
//on mousedown, add a class and override it with css
labelElm.addEventListener('mousedown', (event) => {
event.target.className = 'disable-active';
});
//onmouseout get rid of the class
bodyElm.addEventListener('mouseup', (event) => {
labelElm.classList.remove('disable-active');
});
}
return {
init: init
}
}();
overrideActive.init();
label:active {
background: orange;
}
.disable-active:active {
background-color: transparent;
}
<label>Press mouse down</label>

You can disable mouse events via css. Adding this CSS will will prevent the background from turning orange.
label {
pointer-events: none;
}
If you don't want to do it in every case, use a class and apply the noclick class only when needed (ie, as part react's render() method, or when the page is generated, depending on the framework you're using.
.noclick {
pointer-events: none;
}

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!

When the mouse is not activating a class, add it? Javascript

I have two borders, one on the bottom of an H1, and the other on the right hand side of a div. I have them change color if the mouse is over either element. My idea is to change both borders to be the new color when the mouse is in neither. I figure my best bet would be some sort of JavaScript logic. Something like: if the mouse is not on a, and not on b, add id1 and id2, though I don't know how this will affect my id1 and id2 when the mouse goes back to them.
Is this the right answer, or is there another way I can do this? In case you're wondering the border is 2px wide. I am very new to JavaScript. So to recap, what I want is, the borders of my h1 and div to change when the mouse hovers over them, when the mouse is on neither, I wan't both borders to change at the same time. I'm after the simplest least messy way of solving this.
You could do it by applying css only when their container is hovered. Check out the snippet!
.container {
display:block;
width:100px;
}
.container:hover h1 {
border-right:solid 2px red;
}
.container:hover div {
border-top:solid 2px blue;
}
<div class="container">
<h1>Hi there</h1>
<div>my friend</div>
</div>
You can use the onmouseleave event to handle what happens when the mouse is not on the elements.
You can have a boolean value for each element that you set to true when the user hovers over them and false when the user leaves them. Then you can have an if statement in your onmouseleave event handler that checks whether the mouse is not on either of the elements.
//Get your h1 element
//Get your div element
var onH1 = false;
var onDiv = false;
function changeBoth() {
//Change both borders
}
h1.onmouseover = function() {
onH1 = true;
//Change h1 border
}
div.onmouseover = function() {
onDiv = true;
//Change div border
}
h1.onmouseleave = function() {
onH1 = false;
if((!onH1) && (!onDiv)) {
changeBoth();
}
}
div.onmouseleave = function() {
onDiv = false;
if((!onH1) && (!onDiv)) {
changeBoth();
}
}

No outline on mouse focus but still have outline on keyboard focus?

When elements of a page have focus (such as a link or button), they show an outline. I would like this outline to only display when that element was given focus by the keyboard, not by the mouse.
Is it possible to determine how that element got its focus with JavaScript? If so, how do I then control the browser's own outlining feature?
Browsers use the CSS outline property to show which element has the focus, as you might already know. So, in jQuery, you might use:
$(document).ready(function() {
$("body").on("mousedown", "*", function(e) {
if (($(this).is(":focus") || $(this).is(e.target)) && $(this).css("outline-style") == "none") {
$(this).css("outline", "none").on("blur", function() {
$(this).off("blur").css("outline", "");
});
}
});
});
Explanation: This function looks for the mousedown event on any element. This event is delegated, meaning it will apply to elements currently on the page as well as any created dynamically in the future. When the mouse is clicked over the element, its CSS outline property is set to none; the outline is removed.
The targeted element gets a new handler for blur. When focus is taken from the element, the outline property is set to a blank string (this removes it from the element's style attribute), allowing the browser to control the outline again. Then, the element removes its own blur handler to free up memory. This way, an element is only outlined when focused from the keyboard.
Edit
Based on Rakesh's comments below, I made a slight change. The function can now detect if there's already an outline set, and will avoid overriding it. Demo here.
http://jsfiddle.net/np3FE/2/
$(function(){
var lastKey = new Date(),
lastClick = new Date();
$(document).on( "focusin", function(e){
$(".non-keyboard-outline").removeClass("non-keyboard-outline");
var wasByKeyboard = lastClick < lastKey
if( wasByKeyboard ) {
$( e.target ).addClass( "non-keyboard-outline");
}
});
$(document).on( "click", function(){
lastClick = new Date();
});
$(document).on( "keydown", function() {
lastKey = new Date();
});
});
CSS
*:active, *:focus {
outline: none;
}
*:active.non-keyboard-outline, *:focus.non-keyboard-outline {
outline: red auto 5px;
}
Removing outline is terrible for accessibility! Ideally, the focus ring shows up only when the user intends to use the keyboard.
2018 Answer: Use :focus-visible. It's currently a W3C proposal for styling keyboard-only focus using CSS. Until major browsers support it, you can use this robust polyfill. It doesn't require adding extra elements or altering the tabindex.
/* Remove outline for non-keyboard :focus */
*:focus:not(.focus-visible) {
outline: none;
}
/* Optional: Customize .focus-visible */
.focus-visible {
outline-color: lightgreen;
}
I also wrote a more detailed post with some demo just in case you need more info.
One easy way I can see is to use the mouse event to prevent the focus from firing.
$('#element').click(function(){
$(this).blur();
});
This brings a potencial problem that you won't be able to use the mouse to select the element at all. So you can also just add a class and adjust the focus style.
$('#element').click(function(){
$(this).addClass('fromMouse');
});
$('#element').blur(function(){
if($(this).hasClass('fromMouse'){
$(this).removeClass('fromMouse');
}
});
CSS
.fromMouse{
outline: none;
}
http://api.jquery.com/blur/
CSS
:focus{
outline: none;
}
.outline{
outline: 2px solid rgba(200,120,120, 0.8);
}
jQuery code
$(function(){
$('*').on('keydown.tab', function(e){
/*
TAB or Shift Tab, Aw.
Add some more key code if you really want
*/
if ( 9== e.which && this == e.target ){
window.setTimeout( function(){
$('.outline').removeClass('outline');
$(document.activeElement).addClass('outline');
}, 100 );
}
});
});
This works fine. You will get outline only when the element is focused using Keyboard ( I am aware of Tab and Shift Tab only, you can add more though )
See it working:
http://jsbin.com/okarez/1
Based on #theftprevention answer, a more customisable solution can be :
$(function(){
$('body')
.on('focus', '*', function() {
var e = $(this);
if (!e.is('.focus-mouse')) {
e.addClass('focus-keyboard');
}
})
.on('mousedown', '*', function() {
$(this).removeClass('focus-keyboard').addClass('focus-mouse');
})
.on('blur', '*', function() {
$(this).removeClass('focus-keyboard').removeClass('focus-mouse');
});
});
Now, you just have to cutomize using .focus-keyboard and .focus-mouse classes in CSS.
.focus-keyboard{
background:#eeeeee;
}
.focus-mouse{
outline: 0;
}
you can add class to body to know css if user is currently using mouse or keyboard
document.body.addEventListener('mousedown', function() {
document.body.classList.add('using-mouse');
});
document.body.addEventListener('keydown', function() {
document.body.classList.remove('using-mouse');
});
and in css
:focus {
outline: #08f auto 2px;
}
body.using-mouse :focus {
outline: none;
}

Is there an easier way to show/hide an element on a mouse action?

I have this segment of code here, which I seem to use something similar all the time:
$(".fieldv").live('mouseenter', function() {
$(this).children('.edit-icon').show();
}).live('mouseleave', function() {
$(this).children('.edit-icon').hide();
});
Is there an easier, simpler, or cleaner way to show / hide an element on a mouse action whether it be hovering or clicking an element? Or something of the like...
Why use JavaScript?
You will need to hide the icon by default:
.fieldv .edit-icon { display: none; }
Then this CSS applies on hover (and ONLY on hover)
.fieldv:hover .edit-icon { display: block; /* or inline, etc. */ }
You could try this:
$(".fieldv").hover(function(){
//mouseover
,function(){
//mouseout
});
$(".fieldv").hover(function() {
$(this).children('.edit-icon').show();
}, function() {
$(this).children('.edit-icon').hide();
});
use $(".class").hover(function(){}, function(){});

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