Html - Space Key Press is Causing OnClick to be Triggered - html

[Note: this flaw only occurs in Internet Explorer 11. It is fine in IE9, Chrome and Firefox.]
I have the following Css:
/*** pop-up div to cover entire area ***/
.divModalDialog {
position:fixed;
top:0;
left:0;
width:100%;
height:100%;
/*! important !*/
display:none;
/* last attribute set darkness on scale: 0...1.0 */
background-color:rgba(0,0,0,0.8);
text-align:center;
z-index:101;
}
/*** ! target attribute does the job ! ***/
.divModalDialog:target { display:block; }
An Html:
<div id="divModalDialogUpdate" class="divModalDialog">
<div>
<input type="text" id="divModalText" />
<button onclick="doStuff();">Press</button>
</div>
</div>
<div id="divCanvas" style="display: none; width:100%; height: 100%;">
<canvas id="m_Canvas" width="200" height="200" oncontextmenu="return false;"></canvas>
</div>
As you can see, I am using the divModalDialog as a Modal Dialog Box which appears over the canvas div.
On the canvas div, a game is running. When I need to fire up the modal dialog I pause the game and then have the code:
window.location = "#divModalDialogUpdate";
The person enters some stuff in the text box, clicks the button which triggers the onclick event which runs the function doStuff(). Within doStuff() is the following line of code which returns to just the canvas div being visible:
window.location = "#";
This works all great.
Now the problem. The game state is paused, and my prefered key to toggle the pause state is the Space key. (Any other key and things would be fine, but the problem is I want to use the space key).
So I tap the space key and this is (unwantedly) triggering the onclick event of the button in the modal dialog div again (even though the modal div is no longer visible) which obviously calls the doStuff() function again.
How do I stop the space key triggering the Modal Div's button onclick event when the Modal Div is no longer visible?

You could use a global variable ignore before any logic in doStuff(), e.g.,
function doStuff() {
if(ignore == true) return;
/* logic here ... */
}
Then change your other code to something like:
ignore = false;
window.location = "#divModalDialogUpdate";
and
ignore = true;
window.location = "#";
There might be a way to do this using event.stopPropagation() but I could not find a way to make that work.

Related

Capture div focusout

I have a main div (parent) with a input (child) and 2 other child div (clickable).
I want to capture focus out event for the main div - not when input or other 2 clickable div are clicked or focused. I have set up an event handler using jQuery to capture focusin focusout events on all the elements.
What I see is when I click on the input:
first input is focused
then the main div.
If I click on any other clickable divs
event fires first focusout for input
then main div and then other div gets focus in and main div get focusin.
I don't want main div to loose focus when clicked on other clickable divs.
How can I achieve this? I want to validate the input on lose focus but not when clicked other divs.
So far this is what I have : Fiddle
HTML :
<div id="main">
<input id="i" type="text" />
<div id="Div2" class="icons" style="background-color:blue; right: 25px;" onclick="log('Clear Clicked');"></div>
<div id="Div1" class="icons" style="background-color:red;" onclick="log('DD Clicked');"></div>
</div>
CSS :
* {
-webkit-box-sizing: border-box;
/* Safari/Chrome, other WebKit */
-moz-box-sizing: border-box;
/* Firefox, other Gecko */
box-sizing: border-box;
/* Opera/IE 8+ */
}
#main {
top: 50px;
left: 200px;
position: absolute;
border: 1px solid #00bfff;
width: 250px;
height: 27px;
}
input {
border: none;
width: 248px;
height: 25px;
position: absolute;
z-index: 200;
}
.icons {
text-align:center;
border:1px solid blue;
height: 23px;
width: 23px;
position: absolute;
top: 2px;
right: 2px;
z-index: 99999999999999999999999;
background-position: center;
background-repeat: no-repeat;
}
jQuery :
$("#main").focusin(function () {
log("Main div got focused");
});
$("#i").focusin(function () {
log("input got focused");
});
$("#Div2").focusin(function () {
log("dropdown div got focused");
});
$("#Div1").focusin(function () {
log("clear div got focused");
});
$("#main").focusout(function () {
log("Main div lost focused");
});
$("#i").focusout(function () {
log("input lost focused");
});
$("#Div2").focusout(function () {
log("dropdown div lost focused");
});
$("#Div1").focusout(function () {
log("clear div lost focused");
});
function log(msg) {
//window.console.log(msg);
$("body").append("<p>" + msg + "</p>");
}
Any help or guidance appreciated
Here is a best way to solve, because I had the same problem too ^_^
There is a attr of event: "relatedTarget"
relatedTarget will provide the next element of this event
So, if next element is not your box OR anything inside your box, trigger focus out.
But FIRST you have to let your <div> element focusable, you have to add tabindex='-1' on div like this
<div id="main" tabindex='-1'>
the script is short:
$("#main, #main *").blur(function(e){
if(!$(e.relatedTarget).is("#main, #main *")){
//focus out.
}
});
The focus will lost and get inside #main, but you can do anything when the focus is lost from #main area.
This is a little different to your request, but I guess this may be what you want.
If this is, the code would be very clean.
Based on this accepted answer Is there a way to use event.preventDefault with focusOut? If not, why?
$(document).on('mousedown', function (event) {
target = event.target;
main = document.getElementById("main");
input = document.getElementById("i");
if (target == input) return true;
parent = event.target.parentNode;
if (parent == main) {
event.preventDefault(); //prevent default DOM action
event.stopPropagation(); //stop bubbling
return false; // return
}
});
OK, so it looks like you are constructing some sort of input widget. I see that the #main div is the outer container of the widget, the input is for entering text, and then you have two other divs serving as buttons or something. You want to validate the value of the input when the user tries to exit the widget, and you are trying to capture this event by listening for focusout on #main. This won't work because a div isn't an element that can receive focus. See the answer here for more.
I can prove to you that your div isn't focusable with a little experiment:
If you put e.stopPropagation() in both your focusin and focusout listeners for your input, you'll see that your main div is never actually focused or unfocused itself; it was just receiving the focusin and focusup events as they bubbled up the DOM tree from your input.
So, this means we have to tackle your problem from another angle.
Let's describe what it means for your widget to lose focus with a short user story:
User clicks on the input/#main/#Div1/#Div2 -- widget gains focus
User clicks on input (if he/she hasn't already) and types some text -- widget focus is not lost
User clicks somewhere on #main -- widget focus is not lost
User clicks #Div1 and then #Div2 -- widget focus is not lost
User clicks somewhere else on the page -- widget focus is lost -> validation runs
We now know exactly which events during which states should cause validation to run.
First, let's keep track of the 'focus' state of the widget with a boolean variable:
var isFocused = false;
The widget starts out in the unfocused state and becomes focused when there is a click anywhere in #main or its children OR when the input is somehow focused (could be via tabbed-into with the keyboard):
$("#main").on('click',function(){
isFocused = true;
});
$("#i").on('focus',function(){
isFocused = true;
});
The only time the widget becomes unfocused is when a) it's focused and b) the user clicks somewhere else on the page:
$(document).on('click',function(){
if(isFocused){
isFocused = false;
//kick-off the validation check!
}
});
But since all events bubble-up the DOM tree by default, multiple clicks within #main will bubble up to document.body and trigger a validation check. To prevent this, we call stopPropagation on the click event in the #main's click handler:
$("#main").on('click',function(e){
isFocused = true;
e.stopPropagation();
});
That's it!
I hope I was correct about what you're after.
Here's a working fiddle with above code.
Here is simple way to do it (As far as i understood)
$('#Div1').click(function(){
log('Clear Clicked');
//$('#main').focusin();
$('#i').focus();
});
$('#Div2').click(function(){
log('DD Clicked');
//$('#main').focusin();
$('#i').focus();
});
here is fiddle
The other way to workaround is to add a small setTimeout before running focusout handler.
You can easily whitelist a list of elements to exclude with and clearTimeout when they get focusin.

Prevent screen from moving when clicking on <a href=></a>

I'm using <a href> element along with :target css selector to show a <div> which by default is set to display:none. Problem is, that when I click on the link to show that <div>, it is automatically scrolling down my site towards that <div>.
Is there a way to stop the screen movement?
Unfortunately I am not yet proficient in anything besides CSS and HTML.
You can use event.preventDefault() to avoid this. Something like this:
$('a.yourclass').click(function(e)
{
//your code
e.preventDefault();
});
OR:
link
in the link enter:
Link here
You'll need JS anyway:
// (in jQuery)
$el.on('click', function(e) {
// find current scroll position
var pos = document.body.scrollTop || document.documentElement.scrollTop;
// let normal action propagate etc
// in the next available frame (async, hence setTimeout), reset scroll posiion
setTimeout(function() {
window.scrollTo(0, pos);
}, 1);
})
I don't know if this will flicker the screen. It might. It's a horrible hack either way.
In my Chrome, there's no flicker: http://jsfiddle.net/rudiedirkx/LEwNd/1/show/
There are two ways to tell the browser we don't want it to act:
The main way is to use the event object. There's a method
event.preventDefault().
If the handler is assigned using on (not by
addEventListener), then we can just return false from it.
Example:
Click here
or
here
This is a bit of a hack but you could use a basic css work around:
CSS only Example
#div1 {
height: 0;
overflow:hidden;
}
#div1:target {
height: auto;
margin-top: -110px;
padding-top: 110px;
}
#div2 {
background:red;
}
Click to show
<div id="div1">
<div id="div2">Content</div>
</div>
If you need it to be a little more flexible you can add some js...
More Flexible Example with JS
$('a').click(function () {
$('#div1').css({
'margin-top': 0 - $('#div1').position().top + $(window).scrollTop(),
'padding-top': $('#div1').position().top - $(window).scrollTop()
});
});
Basically you're pulling the top of div1 up with the negative margin and then pushing div2 back down with the padding, so that the top of div1 rests at the top of the window... Like I said its a hack but it does the trick.
Those links are anchor-links and by default made for those jumps :) You could use JS to prevent the default behaviour in some way. For example using jQuery:
$('a').click(function(e){e.preventDefault();});
or by default add return false; to the links
Avoid using :target all together and just use onclick event.
function myFunction()
{
document.getElementById('hiddenDiv').style.display = 'block';
return false;
}

fb like button creates a white background on page onload in all ie versions

I have added the facebook like button <fb:like href="http://mysite.com" class="myFacebook" layout="button_count" ></fb:like>.
When my page loads in any ie there is a noticeable white background before the like button appears, is there any way of removing this?
This is the iframe loading its content.
You could set visibility: hidden on the iframe, and then show it once it has loaded to avoid this.
Simply hide the container with CSS and then display it once the iframe has loaded, this can be done two ways:
<style>#fblike { visibility:hidden; }</style> /* Hide container */
<script>
FB.XFBML.parse(document, function(){
$('#fblike').css({'visibility':'visible'}); /* Show container once loaded */
});
</script>
If you are not using this FB.XFBML.parse() function then you can subscribe an event when everything has rendered instead:
window.fbAsyncInit = function () {
FB.init({
appId: 'APP_ID',
xfbml: true
});
FB.Event.subscribe('xfbml.render',
function () {
$('#fblike').css({'visibility':'visible'}); /* Show container once loaded */
}
);
};
Took me a while to find this all out! Here is a link to where I found my solution: http://developers.facebook.com/docs/reference/javascript/FB.Event.subscribe/
You should set allowtransparency="true" in iFrame.
I had to do like this to make it work
.fb_iframe_widget_fluid{
background:none !important;
//If you want no padding and no margin
padding:0 !important;
margin:0 !important;
}

fb like button creates a white background on page onload in all ie versions [duplicate]

I have added the facebook like button <fb:like href="http://mysite.com" class="myFacebook" layout="button_count" ></fb:like>.
When my page loads in any ie there is a noticeable white background before the like button appears, is there any way of removing this?
This is the iframe loading its content.
You could set visibility: hidden on the iframe, and then show it once it has loaded to avoid this.
Simply hide the container with CSS and then display it once the iframe has loaded, this can be done two ways:
<style>#fblike { visibility:hidden; }</style> /* Hide container */
<script>
FB.XFBML.parse(document, function(){
$('#fblike').css({'visibility':'visible'}); /* Show container once loaded */
});
</script>
If you are not using this FB.XFBML.parse() function then you can subscribe an event when everything has rendered instead:
window.fbAsyncInit = function () {
FB.init({
appId: 'APP_ID',
xfbml: true
});
FB.Event.subscribe('xfbml.render',
function () {
$('#fblike').css({'visibility':'visible'}); /* Show container once loaded */
}
);
};
Took me a while to find this all out! Here is a link to where I found my solution: http://developers.facebook.com/docs/reference/javascript/FB.Event.subscribe/
You should set allowtransparency="true" in iFrame.
I had to do like this to make it work
.fb_iframe_widget_fluid{
background:none !important;
//If you want no padding and no margin
padding:0 !important;
margin:0 !important;
}

zoomin/zoomout of an image in html5

i have simple application which should work on keyboard events like onfocus and onblur instead of onmouseover and onmouseout.
here is my code snippet to zoomin/zoomout:
<script>
var nW,nH,oH,oW;
function zoom(iWideSmall,iHighSmall,iWideLarge,iHighLarge,whichImage)
{
oW=whichImage.style.width;oH=whichImage.style.height;
if((oW==iWideLarge)||(oH==iHighLarge))
{
nW=iWideSmall;nH=iHighSmall;
}
else
{
nW=iWideLarge;nH=iHighLarge;
}
whichImage.style.width=nW;whichImage.style.height=nH;
}
</script>
calling this function in this way:
<td align=center valign=middle >
<figure>
<button style="background-color:black; height:160px;width:160px ; border:none"><img src="F:\rashmi\icons_tv\Help_Normal.png" onfocus="zoom('57px','120px','96px','136px',this);"
onblur="zoom('57px','120px','57px','120px',this);" > </button>
<figcaption><font size="5" color="white" style="font-weight:bold"><center>help</center></font></figcaption>
</figure>
</td>
but problem is when i select image using tab key i cant see any zoomin/zoomout effect. if i replace onfocus/onblur with onmouseover/onmouseout respectively it works well.
please some one help me where i am going wrong.
regards
rashmi
You will not get focus on an img element by tabbing but on the button element instead. Move your onblur/onfocus events to the button element. This will change your button's size each time you focus/lose focus on it, but it will not change your image size. What you have to do then is to modify your code so the change is mapped on the button's contained image dimensions as well. Something that I can think of right now is
<script type="text/javascript">
var nW,nH,oH,oW;
function zoom(iWideSmall,iHighSmall,iWideLarge,iHighLarge,whichElement)
{
theImage = whichElement.firstChild;
theImage.style.width=nW;theImage.style.height=nH;
oW=whichElement.style.width;oH=whichElement.style.height;
if((oW==iWideLarge)||(oH==iHighLarge))
{
nW=iWideSmall;nH=iHighSmall;
}
else
{
nW=iWideLarge;nH=iHighLarge;
}
whichElement.style.width=nW;whichElement.style.height=nH;
theImage.style.width=nW;theImage.style.height=hH;
}
</script>
Here, the first child of the button element, which happens to be the image, takes the same height and width with the button, whenever that changes.