Setting focus fails - javascript

Not an expert, so I am trying to understand why this condition fails. I want it to set focus on .alert-focus if the css classes are present in the page, otherwise if they are not it should set focus on #maincontent. However it never ends up setting focus on #maincontent.
here is my code:
$(function() {
if ($('body .alert, body .success, body .warning').length) {
$('.alert-focus').focus();
} else {
$('#maincontent').focus();
}
});
<a id="maincontent" tabindex="-1" name="maincontent"></a>

Your code does work as long as there is some content inside the <a> element to show.
The example below shows this by adding a CSS rule that only applies to maincontent when it has the focus.
$(function() {
if ($('body .alert, body .success, body .warning').length) {
$('.alert-focus').focus();
} else {
$('#maincontent').focus();
}
});
/* If you see a yellow background, the element has the focus! */
#maincontent:focus { background-color:yellow; }
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<!-- If an element doesn't have any content, then there's nothing to see.
You have to give the element something to be marked up. -->
<a id="maincontent" tabindex="-1" name="maincontent">test</a>

Related

stop auto scrolling when clicking on a link

I have a simple HTML Code in combination with css and JavaScript.
When you are clicking on a link, your URL will be updated like "#link1". Then the visibility of an overlay turn on visible, which is only shown at "#link1"
Now the problem:
When I click on the link my screen automatically scrolls to this overlay, but I didn't want that.
I tried "return false" or "event.preventDefault()". This works, but my URL didn't get updated, so my overlay will not appear.
Dose anyone has an idea how I can do this?
Also tried:
return null
event.preventDefault()
onClick
----html----
<!--The Link-->
<area href="#link1" shape="rect" coords="0,0,100,100" />
<!--The Overlay-->
<div id="link1" class="overlay">
<div class="popup">
...some text...
</div>
</div>
----css----
.overlay {
visibility: hidden;
... some other stuff ...
}
.overlay:target {
visibility: visible;
}
Can you do it this way instead of using href="#link1", do href="javascript:void(0)", and make overlay property appear using jquery property link
$('body').on('click','a', function(){
//Something here
}
Start by setting the display property of the overlay class to none
You need to create a function that will get triggered when the page is loaded or when a link that starts with # is clicked.
That function will get the hash of the url, get the corresponding element and set its display property to something other than none
This way the element won't be visible when the page loads or the hash is changed.
if (document.readyState === "complate") onLoad();
else addEventListener("load", onLoad);
function onLoad() {
var target = document.getElementById(new URL(document.URL).hash.substring(1));
if (target && target.classList.contains("overlay")) {
target.classList.add("active");
}
}
document.querySelectorAll("[href^='#']").forEach(function(link) {
link.addEventListener("click", function() {
setTimeout(onLoad, 0);
});
});
.overlay {
display: none;
}
.overlay.active {
display: block;
}
Show overlay
<!--The Overlay-->
<div id="link1" class="overlay">
<div class="popup">
...some text...
</div>
</div>
The other simpler solution is to use position: fixed to make the elements position static and always have it on the view-port (elimination the need for scrolling).

How to use jQuery .hover() in combination with Overflow

Well, i am stucked and can't find the answer myself. Hopefully someone can give me a hint.
I try to fullfill the following requirements:
There should be a Newsblock within a HTML Page with a fixed width and
height.
In this Newsblock only the title of the news are visible.
Those news are "collapsed" by default and should "expand" if the Mouse is over it.
Due the fact that the 'Newsblock' is limited by its height, there should be a Scrollbar visible. But only if the currently expanded news makes it necessary, so the user can Scroll down.
Newstitle and Newstext should never leave the Newsblock.
so far so good, i was able to fullfill all those demands except the one with the Scrollbar. If i try to reach the Scrollbar out of the currently expanded news it collapses again and the Scrollbar disappears. I understand that my .hover is configured that it always SlideUp if i leave the newsentry and the Scrollbar isn't a part of the newsentry div. But i have no idea what to change to still have an overall Scrollbar for the Newsblock, but won't disappear if i try to 'reach' it.
P.s.: A Scrollbar only per Newsentry looks weird. Thats why i want 'bind' the scrollbar to the parent container :S
HTML
<div id="newsblock">
<div> // some auto generated div's i have to life with, so the news entries are not 'direct' children of the newsblock.
<div class="newsentry">
<div class="newstitle">...</div>
<div class="newstext">...</div>
</div>
... another 9 'newsentry' divs.
</div>
</div>
JS
$(".newsentry").hover(
function() {
$(this).children(".newstext").stop(true,true).slideDown();
},
function() {
$(this).children(".newstext").stop(true,true).slideUp();
}
);
CSS
.newsblock {
height: 200px;
overflow-y: auto;
}
Instead of closing a .newsentry when the cursor goes out of it, a solution can be to close it only when it enters another .newsentry or when it leaves #newsblock.
The scrollbar being part of #newsblock, the entry isn't closed anymore when you go on it.
EDIT: Following our discussion about the scroll issue, I added a step callback to the closing animation to make sure that the top of the .newsentry getting opened remains visible when the other entries are getting closed.
Here is a working example:
var $newsblock = $("#newsblock");
function closeAllNews(slideUpArgs){
return $(".newstext").stop(true).slideUp(slideUpArgs);
}
function openNews(news, slideDownArgs){
$(news).find(".newstext").stop(true).slideDown(slideDownArgs);
}
function ensureNewsTopVisible(news){
// Check if the top of the newsentry is visible...
var top = $(news).position().top;
if(top < 0){
// ...and if not, scroll newsblock accordingly.
$newsblock.scrollTop($newsblock.scrollTop() + top);
}
}
$(".newsentry").each(function(){
var $this = $(this);
// When the mouse enter a news entry...
$this.on("mouseenter", function(){
// ...close all opened entries (normally there is at most one)...
closeAllNews({
// (while making sure that the top of this entry remains visible
// at each step)
step: ensureNewsTopVisible.bind(null, $this)
});
// ...open this newsentry.
openNews($this);
});
});
// When the mouse get out of the newsblock, close all news.
$newsblock.on("mouseleave", closeAllNews);
.newstitle {
font-size: 2em;
}
.newstext {
display: none;
}
#newsblock {
max-height: 150px;
overflow: scroll;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="newsblock">
<div>
<div class="newsentry">
<div class="newstitle">News 1</div>
<div class="newstext"></div>
</div>
<div class="newsentry">
<div class="newstitle">News 2</div>
<div class="newstext"></div>
</div>
<div class="newsentry">
<div class="newstitle">News 3</div>
<div class="newstext"></div>
</div>
<!-- Etc. -->
</div>
</div>
<!-- Ignore the script below. It is just filling in the news' text. -->
<script>
$(".newstext").each(function(i, newstext){
$.get("http://baconipsum.com/api/?type=meat-and-filler&format=html&paras=5&num=" + i)
.then(function(ipsumHtml){
$(newstext).html(ipsumHtml);
});
});
</script>
Try this:
$(".newsentry, .newsblock").hover( // <-- changed
function() {
$(this).children(".newstext").stop(true,true).slideDown();
},
function() {
$(this).children(".newstext").stop(true,true).slideUp();
}
);
This makes sure the block stays open when you hover either over the header or the block itself.
Is that what you mean?
There would be a joke , if i am wrong .. what i thing just change your css as
/* not .newsblock **/
#newsblock {
height: 200px;
overflow-y: scroll;/* not auto*/
}
It will be a lot better if you use click operation instead of hover to slide down news text block because the user can accidentally hover over any of the news entry in order to reach for the scroll bar. I think you need a accordion like functionality. You can use the below code if you are fine with click instead of hover.
$(".newsentry").click(
function() {
$(".newstext").stop(true,true).slideUp();
$(this).children(".newstext").stop(true,true).slideDown();
}
);
Or use the below one to go with hover.
$(".newsentry").hover(
function() {
$(".newstext").stop(true,true).slideUp();
$(this).children(".newstext").stop(true,true).slideDown();
},
function(){}
);
This will not close the news text block until you accidentally hover over another news entry.

jQuery show div only if has class

I have some problems with show/hide element. I have 2 popups on one page and I need hide one popup if another popup has class.
For example:
<body class="home">
<div class="popup main"></div>
<div class="popup"></div>
</body>
So, if body.home has .main I need to show only .main popup and hide or remove another .popup.
I'va tried
if ($('.home').find('.main')) {
$('.home').find('.main').show();
$('.home').find('.popup').remove();
}
But it does not working as I need, because in some reason I'll have code only with one popup block
<body class="home">
<div class="popup"></div>
</body>
Just try this,
if($(".popup").hasClass('main')){
$(".popup").hide();
$(".main").show();
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<body class="home">
<div class="popup main">main</div>
<div class="popup">another</div>
</body>
$( '.home .popup' ).not( ".main" ).remove();
You may want something like this:
$('.popup.main').length &&
$('.popup').show().not('.main').remove() ||
$('.popup').show();
JSFiddle
The above code is basically a "shortcut" of this:
// if there's a popup with class .main:
if($('.popup.main').length){
// show it:
$('.popup.main').show();
// and remove the one without class .main:
$('.popup').not('.main').remove();
// else, if there's no popup with class .main:
}else{
// show the .popup:
$('.popup').show();
}
If you want to show/hide element, use jQuery.hide() or jQuery.show(). If you use jQuery.remove() then u don't have chance to do it again because it was removed from DOM tree.
check with hasClass()
if ($('.home .popup').hasClass('main')) {
$('.home .popup').hide();
$('.home .main').show();
}
This will hide all popups, then show only that has .main class
Working pen
Edit
ok this in not working when .home has only one child.
Try solving this with css
.home .popup:not(.main) {
display: none;
}
.home .popup:only-child {
display: block !important;
}
with this code you only have to add/remove .main class to manage visibility
Working pen with css

jQuery binding events to elements with dynamic class

I have a trigger element and a responding element.
<div class="more"></div>
<div class="info"></div>
I would like to bind an open/close type event.
$('.more').delegate($('.more'), 'click', function(){
$(this).removeClass('more');
$(this).addClass('less');
$(this).text("less...");
$('.info').addClass("open");
});
$('.less').delegate($('.less'), 'click', function(){
$(this).addClass('more');
$(this).removeClass('less');
$(this).text("more...");
$('.info').removeClass("open");
});
It doesn't work as intended, if the second function is nested in the first then you can open and close only once.
If the script is formatted sensibly as above it will open but not close.
Could anyone help me out?
Bonus if the script could support the .info could be either a sibling or the element immediately following $(.more/.less)'s parent.
I've been toying with .on/.live/.bind but less successfully than above.
Use event delegation ,and binded to document or immediate parent,not same element
$(document).on( 'click',".more", function(){
$(this).removeClass('more');
$(this).addClass('less');
$(this).text("less...");
$('.info').addClass("open");
});
$(document).on('click',".less", function(){
$(this).addClass('more');
$(this).removeClass('less');
$(this).text("more...");
$('.info').removeClass("open");
});
DEMO
NOTE: delegate was outdated with latest version of jquery ,so use on instead,
ISSUE: you are delegated with same element $('.less'),$('.more') use immediate parent or document
Just use JavaScript to toggle a class, and let CSS magic do the rest. Here is a demo: http://jsfiddle.net/pomeh/69sX5/1/
And here is the code:
HTML
<div>
Some visible content
</div>
<div class="content-fold">
<div class="more">More...</div>
<div class="less">Less...</div>
</div>
<div class="info">Some hidden additional content</div>
CSS
/* Additional content and Less button hidden by default */
.content-fold + .info, .content-fold .less {
display: none;
}
/* Additional content and Less button shown when class shown is active */
.content-fold.shown + .info, .content-fold.shown .less {
display: block;
}
/* More button hidden when additional content is shown */
.content-fold.shown .more {
display: none;
}
/*
You can also move the "div.info" into the "div.content-fold",
and use ".content-fold.shown > .info" instead of ".content-fold.shown + .info"
Browser support is quite good for adjacent selector (see http://www.quirksmode.org/css/selectors/#t11 and https://developer.mozilla.org/en-US/docs/Web/CSS/Adjacent_sibling_selectors#Browser_compatibility)
*/
JavaScript
$('.content-fold').on('click', function(){
$(this).toggleClass('shown');
});
Use id to do your task. it's easy.
Html
<div class="more" id="toggle"></div>
<div class="info"></div>
Jquery
$('#toggle').click(function(){
var $this = $(this) //store object
if($this.hasClass('more')) {
$this.removeClass('more').addClass('less').text('Less...')
$this.next('.info').addClass('open');
} else {
$this.removeClass('less').addClass('more').text('More...')
$this.next('.info').removeClass('open');
}
});
js Fiddle: http://jsfiddle.net/5N6TL/53/

How to show the child div on mouse hover of parent div

I have a number of parent divs (.parent_div), which each contain a child div (.hotqcontent) where I output data from my database using a loop.
The following is my current markup:
<div class="content">
<div class="parent_div">
<div class="hotqcontent">
content of first div goes here...
</div>
<hr>
</div>
<div class="parent_div">
<div class="hotqcontent">
content of second div goes here...
</div>
<hr>
</div>
<div class="parent_div">
<div class="hotqcontent">
content of third div goes here...
</div>
<hr>
</div>
<div class="parent_div">
<div class="hotqcontent">
content of fourth div goes here...
</div>
<hr>
</div>
</div>
What I would like to achieve is when a user hovers / mouseovers a parent div, the contents of the child div contained within should be revealed.
To achieve this I wrote the following jQuery script but it doesn't appear to be working. It's not even showing the alert!
<script>
$(document).ready(function() {
$(function() {
$('.parent_div').hover(function() {
alert("hello");
$('.hotqcontent').toggle();
});
});
});
</script>
How can I modify or replace my existing code to achieve the desired output?
If you want pure CSS than you can do it like this....
In the CSS below, on initialization/page load, I am hiding child element using display: none; and then on hover of the parent element, say having a class parent_div, I use display: block; to unhide the element.
.hotqcontent {
display: none;
/* I assume you'll need display: none; on initialization */
}
.parent_div:hover .hotqcontent {
/* This selector will apply styles to hotqcontent when parent_div will be hovered */
display: block;
/* Other styles goes here */
}
Demo
Try this
$(document).ready(function() {
$('.parent_div').hover(function() {
alert("hello");
$(this).find('.hotqcontent').toggle();
});
});
Or
$(function() {
$('.parent_div').hover(function() {
alert("hello");
$(this).find('.hotqcontent').toggle();
});
});
You can use css for this,
.parent_div:hover .hotqcontent {display:block;}
This can be done with pure css (I've added a couple of bits in just to make it a bit neater for the JSFIDDLE):
.parent_div {
height: 50px;
background-color:#ff0000;
margin-top: 10px;
}
.parent_div .hotqcontent {
display: none;
}
.parent_div:hover .hotqcontent {
display:block;
}
This will ensure that your site still functions in the same way if users have Javascript disabled.
Demonstration:
http://jsfiddle.net/jezzipin/LDchj/
With .hotqcontent you are selecting every element with this class. But you want to select only the .hotqcontent element underneath the parent.
$('.hotqcontent', this).toggle();
$(document).ready(function(){
$('.parent_div').on('mouseover',function(){
$(this).children('.hotqcontent').show();
}).on('mouseout',function(){
$(this).children('.hotqcontent').hide();
});;
});
JSFIDDLE
you don't need document.ready function inside document.ready..
try this
$(function() { //<--this is shorthand for document.ready
$('.parent_div').hover(function() {
alert("hello");
$(this).find('.hotqcontent').toggle();
//or
$(this).children().toggle();
});
});
and yes your code will toggle all div with class hotqcontent..(which i think you don't need this) anyways if you want to toggle that particular div then use this reference to toggle that particular div
updated
you can use on delegated event for dynamically generated elements
$(function() { //<--this is shorthand for document.ready
$('.content').on('mouseenter','.parent_div',function() {
alert("hello");
$(this).find('.hotqcontent').toggle();
//or
$(this).children().toggle();
});
});
you can try this:
jQuery(document).ready(function() {
jQuery("div.hotqcontent").css('display','none');
jQuery("div.parent_div").each(function(){
jQuery(this).hover(function(){
jQuery(this).children("div.hotqcontent").show(200);
}, function(){
jQuery(this).children("div.hotqcontent").hide(200);
});
});
});

Categories

Resources