Is there a way to set the focus on an on page load? I have found documentation stating to use the autofocus attribute but the documentation says that attribute only applies to input, button, textarea, and select.
Thanks.
You can try scrollIntoView method on window onload
window.onload=function(){
document.getElementById("ID_OF_IMAGE").scrollIntoView();
}
I think you looking for something like that:
window.addEventListener('load', function() {
document.querySelector(".classFromImage").focus();
})
What you could do is search for the img element with the autofocus attribute and set the focus after the DOM is read. You also need to set the tabindex to get that working.
I would only search for img[autofocus] so that you don't mess too much around with the default behavior.
window.addEventListener('DOMContentLoaded', function() {
let elm = document.querySelector("img[autofocus]")
if (elm) {
elm.focus()
}
})
img {
width: 100px;
height: 100px;
display: inline-block;
}
:focus {
border: 4px solid red;
}
<img autofocus tabindex="0">
You can focus a nonfocusable element by adding tabindex="0" attribute to the tag and use focus() method with js.
<img class="focusable" tabindex="0" src="#"/>
window.addEventListener('load', function() {
document.querySelector(".focusable").focus();
})
Related
When navigating through inputs on the page using tab, they become outlined once in focus. But when I try to do something similar using, for example, arrow keys, focusing on checkboxes doesn't show outline styles.
jq(elems).keydown(function(e){
if(!e) return;
if(e.keyCode == '38') {
var el = ... // searching for the next element
el.focus();
}
Even if I manually add outline styles after focus, or add css like
input[type="checkbox"]:focus
{
outline-style:auto;
outline-color:
-webkit-focus-ring-color;
}
it wouldn't work. The focus is on the checkbox, the styles are there, but they are not displayed. Some other styles applied correctly, for example if I add styles like:
input[type="checkbox"]:focus {
box-shadow:1px 1px lightgrey;
}
I can see shadow box when focus is on the checkbox, but outline is not there.
I've only done this in raw js, but hopefully it helps:
Make sure to set the event listener on the document - otherwise you're only firing the event if the key is pressed whilst already 'inside' the element.
JS:
var el = document.getElementById('my-check');
document.addEventListener('keydown', function(e) {
e.preventDefault();
el.focus();
});
CSS:
input[type="checkbox"]:focus, input[type="checkbox"]:active {
width: 100px;
height: 100px;
outline-color: -webkit-focus-ring-color;
outline-style: solid !important;
}
DOM:
<form>
<input type="checkbox" id="my-check" />
</form>
Fiddle: https://jsfiddle.net/radmpxgs/1/
Sorry for the edits.
When you enter my website (goerann.com) the dropdown register-box is down by default.
If I click in Register, the register-box toogles it visibility as I want, but it doesn't start hidden by default.
$(document).ready(function() {
$('#signup').click(function() {
$('.signupmenu').slideToggle("fast");
});
});
I want it to only show when you click on it. How can I make this happen?
Here's my jsfiddle (http://jsfiddle.net/bdv2doxr/)
Since you're already using the $(document).ready event, you can hide the menu there:
$(document).ready(function() {
$('.signupmenu').hide();
$('#signup').click(function() {
$('.signupmenu').slideToggle("fast");
});
});
And here is your fiddle updated.
You need to make two changes, both involving the removal of display: block. When you toggle this div, it will make the display block. Therefore, you can initialize it as display: none.
Change this:
<div class="signupmenu" style="display: block;">
to this:
<div class="signupmenu">
And also change this:
.signupmenu {
background-color: #FFF;
display: block;
...
to this:
.signupmenu {
background-color: #FFF;
display: none;
...
Updated fiddle here
I've a web application with dialogs. A dialog is a simple div-container appended to the body. There is also an overlay for the whole page to prevent clicks to other controls. But: Currently the user can focus controls that are under the overlay (for example an input). Is there any way to limit the tabbable controls to those which are in the dialog?
I am using jQuery (but not using jQueryUI). In jQueryUi dialogs it's working (but I don't want to use jQueryUI). I failed to figure out, how this is accomplished there.
Here is the jQueryUI example: http://jqueryui.com/resources/demos/dialog/modal-confirmation.html - The link on the webpage is not focusable. The focus is kept inside the dialog (the user cannot focus the urlbar of the browser using tab).
HTML:
I should not receive any focus
<input type="text" value="No focus please" />
<div class="overlay">
<div class="dialog">
Here is my dialog<br />
TAB out with Shift+Tab after focusing "focus #1"<br />
<input type="text" value="focus #1" /><br />
<input type="text" value="focus #1" /><br />
</div>
</div>
CSS:
.overlay {
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
background-color: rgba(0, 0, 0, 0.3);
text-align: center;
}
.dialog {
display: inline-block;
margin-top: 30%;
padding: 10px;
outline: 1px solid black;
background-color: #cccccc;
text-align: left;
}
Here is my fiddle: http://jsfiddle.net/SuperNova3000/weY4L/
Does anybody have an idea? I repeat: I don't want to use jQueryUI for this. I'd like to understand the underlying technique.
I've found an easy solution for this issue after hours of trying. I think the best way is adding 2 pseudo elements. One before and one after the dialog (inside the overlay). I'm using <a>-Tags which are 0x0 pixels. When reaching the first <a>, I'm focusing the last control in the dialog. When focusing the last <a>, I'm focusing the first control in the dialog.
I've adapted the answer of this post: Is there a jQuery selector to get all elements that can get focus? - to find the first and last focusable control.
HTML:
<div class="overlay">
<a href="#" class="focusKeeper">
<div class="dialog">
Here is my dialog<br />
TAB out with Shift+Tab after focusing "focus #1"<br />
<input type="text" value="focus #1" /><br />
<input type="text" value="focus #1" /><br />
</div>
<a href="#" class="focusKeeper">
</div>
Extra CSS:
.focusKeeper {
width: 0;
height: 0;
overflow: hidden;
}
My Javascript:
$.fn.getFocusableChilds = function() {
return $(this)
.find('a[href], area[href], input:not([disabled]), select:not([disabled]), textarea:not([disabled]), button:not([disabled]), iframe, object:not([disabled]), embed, *[tabindex], *[contenteditable]')
.filter(':visible');
};
[...]
$('.focusKeeper:first').on('focus', function(event) {
event.preventDefault();
$('.dialog').getFocusableChilds().filter(':last').focus();
});
$('.focusKeeper:last').on('focus', function(event) {
event.preventDefault();
$('.dialog').getFocusableChilds().filter(':first').focus();
});
May be I'll add a fiddle later, no more time for now. :(
EDIT: As KingKing noted below the focus is lost, when clicking outside the control. This may be covered by adding an mousedown handler for the .overlay:
$('.overlay').on('mousedown', function(event) {
event.preventDefault();
event.stopImmediatePropagation();
});
EDIT #2: There's another thing missing: Going outside the document with the focus (for example the titlebar) and than tabbing back. So we need another handler for document which puts back the focus on the first focusable element:
$(document).on('focus', function(event) {
event.preventDefault();
$('.dialog').getFocusableChilds().filter(':first').focus();
});
You can try handling the focusout event for the .dialog element, check the e.target. Note about the e.relatedTarget here, it refers to the element which receives focus while e.target refers to the element lossing focus:
var tabbingForward = true;
//The body should have at least 2 input fields outside of the dialog to trap focusing,
//otherwise focusing may be outside of the document
//and we will loss control in such a case.
//So we create 2 dummy text fields with width = 0 (or opacity = 0)
var dummy = "<input style='width:0; opacity:0'/>";
var clickedOutside = false;
$('body').append(dummy).prepend(dummy);
$('.dialog').focusout(function(e){
if(clickedOutside) {
e.target.focus();
clickedOutside = false;
}
else if(!e.relatedTarget||!$('.dialog').has(e.relatedTarget).length) {
var inputs = $('.dialog :input');
var input = tabbingForward ? inputs.first() : inputs.last();
input.focus();
}
});
$('.dialog').keydown(function(e){
if(e.which == 9) {
tabbingForward = !e.shiftKey;
}
});
$('body').mousedown(function(e){
if(!$('.dialog').has(e.target).length) {
clickedOutside = true;
}
});
Demo.
So i'm learning some jQuery at the moment and got somewhat stuck with this .click function. I'm trying to "turn a light on and off", so to speak.
I am able to do so, but only once. Why is that, that my code only runs for one click event per item, and how should i improve it?
Link to my JSfiddle.
HTML
<div class="lightOn"></div>
<div class="lightOff"></div>
jQuery
$('.lightOn').click(function() {
$(this).removeClass('lightOn');
$(this).addClass('lightOff');
});
$('.lightOff').click(function() {
$(this).removeClass('lightOff');
$(this).addClass('lightOn');
});
CSS
.lightOn {
height: 90px;
width:90px;
background-color:yellow;
border-radius: 100%;
float:left;
margin:10px;
}
.lightOff {
height: 90px;
width:90px;
background-color:grey;
border-radius: 100%;
float:left;
margin:10px;
}
The issue is because you are removing the class you are selecting by, so for successive clicks the element no longer exists. Instead have a common class which remains, but add one to it to light up the object. Try this:
<div class="light"></div>
<div class="light"></div>
.light.on {
background-color:yellow;
}
.light {
height: 90px;
width:90px;
background-color:grey;
border-radius: 100%;
float:left;
margin:10px;
}
$('.light').click(function() {
$(this).toggleClass('on');
});
Example fiddle
This method has the benefit of being able to handle x number of .light elements wihtout having to amend the jQuery selector you use.
The problem is that you bind the functions to elements, not to selectors. That is to say, you bind a function that removes the class lightOn to the element that had that class originally. That function only ever removes the lightOn class and adds the lightOff class, even if that has already been done once.
There are two ways to fix this. One is with on and event delegation, which allows you to do something akin to binding to a selector. It attaches the handler to a parent element, and makes use of the fact that all ancestor elements are notified of events that originated on their descendents. So the function might be bound to document.body, but only elements that originated on an element matching the .lightOn selector will trigger the handler:
$(document.body).on('click', '.lightOn', function() {
$(this).removeClass('lightOn').addClass('lightOff');
}).on('click', '.lightOff', function() {
$(this).removeClass('lightOff').addClass('lightOn');
});
http://jsfiddle.net/lonesomeday/C6f7u/5/
Better, however, is to make use of jQuery's toggleClass function, which removes classes if the element currently has them and adds them if it doesn't.
$('.lightOn,.lightOff').click(function() {
$(this).toggleClass('lightOn lightOff');
});
http://jsfiddle.net/lonesomeday/C6f7u/2/
What about
$('.lightOn, .lightOff').click(function() {
$(this).toggleClass('lightOn lightOff');
});
Demo: Fiddle
You can try using toogleClass of jquery
http://api.jquery.com/toggleClass/
It's a good practice to attach your events to the parent element. In your case this is even mandatory, because you are changing the classes, which are used during the event binding. So, your HTML:
<div class="ligths">
<div class="lightOn"></div>
<div class="lightOff"></div>
</div>
JS:
$(".ligths").on("click", "div", function(e) {
var el = $(this);
if(el.hasClass("lightOn")) {
el.removeClass("lightOn").addClass("lightOff");
} else {
el.removeClass("lightOff").addClass("lightOn");
}
});
JSFiddle: http://jsfiddle.net/C6f7u/7/
I'm making a collapsible treeView.
I made it all, I just need my + and - icons to toggle whenever they are clicked.
I did the part when I change an icon from + to -, on click, with jQuery with the following code:
$(this).attr('src','../images/expand.gif');
Problem is, I don't know how to make it go other way around, when i click on the node again :)
This should work:
<style>
.expand{
content:url("http://site.com/expand.gif");
}
.collapse{
content:url("http://site.com/collapse.gif");
}
</style>
<img class="expand">
<script>
//onclick code
$('img.expand').toggleClass('collapse');
</script>
Look for jquery function toggleClass :)
http://jsfiddle.net/Ceptu/
Html:
<div id="box">
Hello :D
</div>
Jquery:
$("#box").click(function () {
$(this).toggleClass("red");
});
Css:
#box {
width: 200px;
height: 200px;
background-color: blue;
}
.red {
background-color: red !important;
}
Remember that !important is realy important!!!
Lots of ways to do this :D
I wanted to do this without making classes. Inside your click event function, you could do something like this:
if($(this).attr('src') == '../images/collapse.gif')
$(this).attr('src', '../images/expand.gif');
else
$(this).attr('src', '../images/collapse.gif');
add plus as a default img src then define a minus-class to change the image source to minus image
$("selector_for_your_link").click(function () {
$(this).toggleClass("minus-class");
});