Opacity with onclick, onmousedown & onmouseup - html

I am a newbie to javascript programming, but am making progress! I am developing a web app in house for children with autism, for touch screen browsers (55" touch screen PCs and Nexus 7 tablets). We will only use Firefox as it appears most compatible. The children will click on image "buttons" to make choices and to communicate their needs. The buttons need to give visual feedback when touched. I have solved this by using the active state in CSS:
img { opacity:1.0 };
img:active { opacity:0.4 };
This works fine. Hover is no good for use on touch screens. I also have a need for some images to be made invisible but to remain where they are, and to toggle on and off on a long press. For this I have found a toggle function and a timer function and combined them.
JAVASCRIPT (in <head> of page):
var t
function tog_vis(id) {
var e = document.getElementById(id);
if(e.style.opacity == 1 )
e.style.opacity = 0 ;
else
e.style.opacity = 1 ;
HTML:
<img id="myimg" onclick="DoSomething();" onmousedown="t=setTimeout(function(){ tog_vis('myimg'); }, 1500);" onmouseup="clearTimeout(t);" src="images/img1.png">
Problem is the active state gets taken over by the onmousedown and onmouseup events (I have read that this is because they are both part of the click event - makes sense!), and I am guessing that the onclick event may also mess things up further.
Expected/Desired behaviour:
1.On a normal click, the image changes opacity to 0.4, and when released returns to 1, then completes the onclick request.
2.On a long click, the image opacity goes to 0, and on a second long click the opacity returns to 1, with NO onclick event.
The app will eventually have # 100 similar images that must perform the first behaviour, whilst the second behaviour will only be needed on # 10 buttons so I could happily code functions individually if necessary. I have also found that the 55" touchscreens (Windows 7) are not responding to the img:active CSS, so guessing these are relying on the touchdown and touchup events, whilst the tablets are very well behaved.
Any help here much appreciated.
Tim

You could you css3 transitions and a little javascript for this use case. Have a look at this fiddle: http://jsfiddle.net/Ce8J5/
Also you could realise the hover with javascript/jquery, just remove the hover css statement and define some addionatial css classes and add them via javascript.
E.g.
$("#element").mouseenter(function(){
$(this).addClass(".hover");
});
$("#element").mouseleave(function(){
$(this).removeClass(".hover");
});

Related

stop css target being affected by backbutton

I use the target selector to put and remove a class that shows and hides the navigation menu. The problem is that when a user uses the backbutton on the browser the menu states get messed up.
This is my css code
<style>
#buttons-container a.close-menu-primary{display: none;}
#wrap:target #mainmenu{display: block;}
#wrap:target #buttons-container a.open-menu-primary{display: none;}
#wrap:target #buttons-container a.close-menu-primary{display: block;}
</style>
buttons-container is a div with two buttons, open-menu-primary & close-menu-primary, that toggle each other on and off and show or hide the mainmenu.
The problem occurs when someone uses the back button. In that case it only toggles the button states between open and close-menu-primary, which are a burger and a close image.
You can check the live version here if you make the browser small enough or use a mobile device, screen size has to be smaller than (min-width: 768px) and (min-height: 558px) website with toggle by target selector
Hope someone can clear this up if it is possible to use target this way or if there better ways to get this affect without scripting please.
Thanks in advance!
The question is... when user presses the back button, do you want to go back one state of menu visibility (ie. hide it or unhide it), or do you want to go back one page?
I check your linked page http://www.rieon.nl. I think this is the problem:
I presume you want the user to go back one page, not just to hide the menu. Then, you need to change this piece of code
jQuery( document ).ready(function( $ ) {
$("#buttons-container a").click(function(){
$("nav").toggleClass("main");
});
});
and add either return false or e.preventDefault():
jQuery( document ).ready(function( $ ) {
$("#buttons-container a").click(function(e){
$("nav").toggleClass("main");
e.preventDefault(); // use either one
return false; // of these lines
});
});
The problem is that by clicking on the link on navigation button, browser executes the javascript handler that shows the menu AND navigates to link's href address (which is #wrap) and that creates a new step in its history, so that when user hits back button, browser just goes back to previous state (which is usually the same page but without #wrap). By adding return false (that's jQuery speciality) or calling preventDefault() on event object (that's standard JS), you cancel the navigation and leave only your own handler to be executed.

how to show/hide a div with many children(> 7000) without style recalculation

This is an Android app that uses WebView to display a long list. The long list's visibility can be toggled by the following JS function:
function _showOverlay() {
$("#container").css("visibility", "visible");
}
function _hideOverlay() {
$("#container").css("visibility", "hidden");
}
a style recalculation is triggered by both function. On desktop the performance is fine but on slower phone device (Galaxy Nexus class), the performance is not acceptable. Anyway to speed this operation up? or, any other trick I can use to show/hide a div?
Tried the following:
"opacity:0" - can't use this because the list can still respond to user touches while invisible (bad)
"display:none" - triggers same style recalculation.

disable scroll for a div with SVG

I have a SVG chart using d3js. We can add some points to this chart and move it. When I have a big page and so when we need to scroll it, it works with the mouse. But I have an input screen with multi-touch and in more I develop my app for mobile.
The input with the chart and the scroll aren't working together with an input touch. For example if I want to move my point it's the page which scroll and not my point wich move. It's not exactly the same bugs on firefox, IE and my Windows RT app.
You can see a little example here to test if you have an input touch, I guess tablet and smartphone will have the same behaviour than my PC with a touch screen.
I have the following css to simulate a bigger app:
body {
overflow:visible;
width: 2000px;
height: 2000px;
}
There is a way to do this?
I hope you understood my problem :)
I tested this on my phone and tried to research how to force a browser to stop scrolling with little success. The good news is your app allows a mobile user to place a new point really nicely.
To get the project done quick, you might need to create a set of controls that grabs an id of each existing point and allow the mobile user to move the desired point using buttons. The UI for such a set of controls could be minimal and intuitive if done well. You could set the UI to display:none and only show when the screen width/height is iPad size or less.
I finnaly found a solution with the pointer-events property in css
var C1 = document.getElementById("C1"),
evtIn = window.navigator.msPointerEnabled ? "MSPointerDown" : "touchstart",
evtOut = window.navigator.msPointerEnabled ? "MSPointerUp" : "touchend";
C1.addEventListener(evtIn, function () {
d3.select("#C1").style("pointer-events", "all");
d3.select("body").style("overflow", "hidden");
}, false);
C1.addEventListener(evtOut, function () {
d3.select("#C1").style("pointer-events", "none");
d3.select("body").style("overflow", "auto");
}, false);
On touch start I just allow pointer events in my chart et disable overflow and in the other way for the touch end.

Disable events triggered on HTML <SELECT> control

Is there a way to capture the events triggered on HTML controls before they are forwarded for default (generic) handling by the control itself. In my case, I want to prevent a element dropdown to open when a user clicks on the control. e.g. On this user click, OnClick() event gets fired and is handled by the default control which open the dropdown. I want to stop this from happening.
Can I attach a custom function to this event and redirect the event handling to this one instead of the default code that opens the dropdown?
Thanks
onclick,onmousedown and onmouseup will not help you to prevent the selectbox from opening. I'm not asking why you want to do that, but if you really can't use any other solution, like for example (changing selectbox to the readonly inputbox), then, you can try the next solution.
One way to prevent the box from opening, is to create an overlay container, which will block the the focusable area of the select. This can be achived by placing the div after the selectbox and givving it the sizes and the position of the selectbox.
<div style="position:relative;">
<select style="width:100px;height:30px">
<option>hello</option>
</select>
<div style="position:absolute;
left:0;
top:0;
width:100px;
height:30px;
z-index:2;
background-color:black;
opacity:0;filter:Alpha(Opacity='0');"
></div>
</div>
Event then, it will work only for IE >= 7. Not for IE6, cause selectboxes in IE6 are strange( maybe you can try to fix IE6 with some iframe hack);
Fairly old question with some good suggestions, but none seem to directly answer the original question. In case anybody out there is wondering, I believe the OP was wanting to keep the visual appearance of the system/browser select element, but use his own custom drop-down menu instead of the system/browser drop-down menu.
In this case, the onclick event will occur too late for you to stop the actual drop-down menu from displaying. What you want to do is bind to the mousedown event, and prevent the event from propagating to the default behavior:
document.getElementById('my_select_id').onmousedown = function(event) {
// ... do something here...perhaps display your own custom menu, an advanced selection chooser, focus another element, display a message, or some other custom handling.
event.preventDefault(); // This prevents the drop-down menu from displaying
}
Notes:
Replacing the drop-down with a custom-designed element (as suggested by others) isn't always an option. In some cases, you'll end up either having to completely omit default/system drop-downs from your site (in favor of a custom-designed element), or you have to live with a mismatch in visual appearance due to browser/system/theme differences (unless you feel like designing the custom element to match every conceivable visual aesthetic/theme.)
Disabling the drop-down will not work, as it will prevent the event handlers from firing.
Using optgroups will still allow the drop-down menu to be displayed.
Replacing the drop-down with an empty version will still display an empty drop-down menu.
This is the answer I gave on another, similar question.
This works great for me in IE and Chrome, there's no flicker or anything:
html
<select id="MySelect"><option>Hello</option></select>
js
MySelect.onmousedown = function ()
{
window.setTimeout(function ()
{
//- An immediate blur, then refocus stops the options from being displayed
this.blur();
this.focus();
//- so now we run our custom function
runOtherFunctionInstead();
},0);
}
Make sure the js runs after the select element has been parse by placing it in an onload or ondocumentready or a script block after the select element. Haven't tried it in Firefox or Opera. Assumedly it would work in Safari, though.
EDIT
As suggested in the comments, the popup will still appear for a double click in IE (all versions). This is due to a bug where the mousedown event doesn't fire for the second click (whoops). You can quickly hide the options again by using the blur, focus method in the ondblclick event and if this method works in Firefox and Safari, I still think it's the best solution considering most people don't double click select boxes.
you need to set selectbox to be onload disabled: disabled="disabled"

Removing resize handlers on contentEditable div

I created a contentEditable div to use as a rich textarea. It has resize handlers around it that I'd like to get rid of. Any idea how I'd do this?
Edit: This appears to be happening because I am absolutely positioning the div, so Firefox adds an infuriating _moz_resize attribute to the element which I cannot turn off.
Just as a side note, you can disable Firefox's automatic resize handle feature by sending the (somewhat poorly-documented) enableObjectResizing command to the document:
document.execCommand("enableObjectResizing", false, false);
AFAIK, this can only safely be done once the document has loaded, and there's no way I know of to disable the grabber, which is a separate feature.
It looks like I'll be able to work around this by adding a wrapper div and absolutely positioning the wrapper and then making the inner div contentEditable.
In Chrome 39, these handles don't seem to exist, even if you wanted them to.
In Firefox, one can simply use execCommand, like ZoogieZork answered.
But in Internet Explorer this can't be turned off. It must be worked around.
In WYMeditor development, here's what I've found.
The following results in:
In IE, the resize UI shows up for a split second and then disappears. There seems to be no way for the user to use it.
Images are text selected on mouseup
Ability to drag images. In some browsers, they may have to be selected before dragging. As written in the previous item, a simple mouseup will result in an image being selected.
Images are selected using text selection and not "control selection" (that which provides the resize UI).
This is the best I could come up with after hours of very deep breaths. I think it is good enough if you really want to get rid of those handles.
In IE, Setting oncontrolselect to return false on the image, really does prevent those handles from appearing, and you can do it cleverly, by attaching the following handler to the mousedown event:
function (evt) {
var img;
function returnFalse() {
return false;
}
if (evt.tagName.toLowerCase() === "img") {
img = evt.target;
img.oncontrolselect = returnFalse;
}
}
It actually doesn't work completely well. The reason that it didn't work very well is that in order to begin a drag and drop operation on the image, one had to press and hold the mouse, without moving it, for a split second, and only then begin moving it for the drag. If one pressed the mouse and immediately began dragging, the image would remain in its place and not be dragged.
So I didn't do that.
What I did is the following. In all browsers, I used mouseup to text select the target image exclusively. In non-IE and IE11, synchronously:
function (evt) {
if (evt.target.tagName.toLowerCase() === "img") {
selectSingleNode(img); // In my case, I used Rangy
}
}
In IE 7 through 10, asynchronously:
function (evt) {
if (evt.target.tagName.toLowerCase() !== "img") {
return;
}
window.setTimeout(function () {
selectSingleNode(img); // In my case, I used Rangy
}, 0);
}
This made sure that after those handles show up, they disappear ASAP, because the image loses its "control selection" because that selection is replaced with a regular text selection.
In Internet Explorer 7 through 11, I attached a handler to dragend that removes all selection:
function (evt) {
if (evt.target.tagName.toLowerCase() === "img") {
deselect(); // I use Rangy for this, as well
}
}
This makes the handles that show up after drag and drop, disappear.
I hope this helps and I hope you can make it even better.
I just face that problem.
I tried document.execCommand("enableObjectResizing", false, false); but, the move icon was still appearing. What just fix my problem was just e.preventDefault() when onmousedown event occurs.
element.onmousedown = function(e){
e.preventDefault();
}
for IE11 (I havn't tested the older versions of IE, but I feel like it would work) you can add contenteditable="false" attribute to the img tag. This will prevent any re-sizing from being done while keeping drag and drop in place.
... just the best fix ever
<div contenteditable="true">
<label contenteditable="false"><input/></label>
</div>
or any html element that wraps your input/img
Works on IE11 like a charm
Have you tried adding the style
border: none;
to the div?