I am using jquery .toggle() to show a div on a page that has display:none on page load. However, under the default settings jquery inserts display:block, where I would want display:table-cell. How can I achieve this? My attempt so far:
<div class="mydiv" style"display:none">test</div>
.mydiv {
display:table-cell;
}
$("a#showdiv").click(function() {
$(".mydiv").toggle();
Use .toggleClass() instead and use css for the styling..
html
<div class="mydiv table-hidden">test</div>
css
.mydiv {
display:table-cell;
}
.mydiv.table-hidden{
display:none;
}
jquery
$("a#showdiv").click(function() {
$(".mydiv").toggleClass('table-hidden');
}
Use CSS for the styling #Gaby aka G. Petrioli or use the .css() method in jQuery.
HTML
<div class="mydiv">test</div>
jQuery
$("a#showdiv").click(function() {
if($(".mydiv").css("display") == "none"){
$(".mydiv").css("display", "table-cell");
} else {
$(".mydiv").css("display", "none");
}
});
What you have should work already.
In jQuery, unless the style attribute of the element has display initially set to something else other than none, when the show is called, all it does is remove the style attribute for display. It doesn't set it block.
You can see for yourself in this fiddle that when the button is clicked, the display that is set in the CSS is what the element is set to.
Here's the relevant code in the jQuery source:
function showHide( elements, show ) {
var display, elem, hidden,
values = [],
index = 0,
length = elements.length;
for ( ; index < length; index++ ) {
elem = elements[ index ];
if ( !elem.style ) {
continue;
}
values[ index ] = data_priv.get( elem, "olddisplay" );
display = elem.style.display;
if ( show ) {
// Reset the inline display of this element to learn if it is
// being hidden by cascaded rules or not
if ( !values[ index ] && display === "none" ) {
elem.style.display = "";
}
// Set elements which have been overridden with display: none
// in a stylesheet to whatever the default browser style is
// for such an element
if ( elem.style.display === "" && isHidden( elem ) ) {
values[ index ] = data_priv.access( elem, "olddisplay", css_defaultDisplay(elem.nodeName) );
}
} else {
if ( !values[ index ] ) {
hidden = isHidden( elem );
if ( display && display !== "none" || !hidden ) {
data_priv.set( elem, "olddisplay", hidden ? display : jQuery.css(elem, "display") );
}
}
}
}
// Set the display of most of the elements in a second loop
// to avoid the constant reflow
for ( index = 0; index < length; index++ ) {
elem = elements[ index ];
if ( !elem.style ) {
continue;
}
if ( !show || elem.style.display === "none" || elem.style.display === "" ) {
elem.style.display = show ? values[ index ] || "" : "none";
}
}
return elements;
}
I should note that toggling classes will usually be faster in general because there is less information to check.
.display-none {
display: none;
}
div.display-table-cell {
display: table-cell;
}
<button id="showdiv">Show/Hide</button>
<div class="mydiv display-none">test</div>
<div class="mydiv display-none">test</div>
<div class="mydiv display-none">test</div>
<div class="mydiv display-none">test</div>
$("#showdiv").click(function() {
$(".mydiv").toggleClass('display-table-cell');
});
http://jsfiddle.net/7q27y/
If you understand CSS precedence as well, you don't technically "need" the div. on the latter:
div.display-table-cell {
display: table-cell;
}
http://jsfiddle.net/7q27y/
Of course, this is due to it's precedence and the fact it falls after the other statement, which both would calculate as the same precedence otherwise. See:
http://jsfiddle.net/7q27y/2/
Related
I have not been able to figure out why jQuery applies the desired new class to body making the first condion always true regarless of different conditions.
The HTML contains these different tags:
<h1 class="entry-title">Intro Audios</h1>
<h1 class="entry-title">Level 1 Audios</h1>
<h1 class="entry-title">Level 2 Audios</h1>
<h1 class="entry-title">Level 3 Audios</h1>
16 pages to be exact contain the h1 tag first aboeve, another 16 contain the h1 tag above and so on.
But no matter what page I visit the added class to the body tag is always "Level-1"
<script>
jQuery(document).ready(function($){
var level1 = $("h1.entry-title:contains(Level 1)");
var level2 = $("h1.entry-title:contains(Level 2)");
var level3 = $("h1.entry-title:contains(level 3)");
if ( level1)
{
$(document.body).addClass('level-1');
} else if (level2 )
{
$(document.body).addClass('level-2');
} else if (level3 )
{
$(document.body).addClass('level-3');
} else
{
$(document.body).addClass('intro');
}
});
</script>
What am I doing wrong?
Try this fiddle, https://jsfiddle.net/djkk8yrg/
Check the console where level1 and level2 vars are logged and there is no corresponding html code for level1
They return:
[prevObject: jQuery.fn.init[1]]
[h1.entry-title, prevObject: jQuery.fn.init[1]]
Even though level1 element is not there in the html, it just returns a prevObject. Add additional logic to confirm that it's not only prevObject which is returned.
What I was trying to do was to be able to add a class to the body tag depending on the condition that a particular wordpress category exists or not. If it exist add the class to body tag so I can stylize each of those pages differently according to new body class.
After trying and testing different answers and codes for a while I found a solution that woks and it is this:
<script>
jQuery(document).ready(function($){
var intro = $( "article" ).hasClass( "category-level-intro" );
var level_1 = $( "article" ).hasClass( "category-level-1" );
var level_2 = $( "article" ).hasClass( "category-level-2" );
var level_3 = $( "article" ).hasClass( "category-level-3" );
// check to see if the condition is true
if(intro === true)
{
$(document.body).addClass('intro');
} else if (level_1 === true)
{
$(document.body).addClass('level-1');
} else if (level_2 === true)
{
$(document.body).addClass('level-2');
} else if (level_3 === true )
{
$(document.body).addClass('level-3');
} else {
$(document.body).addClass('');
}
});
</script>
Thanks!
I have a div that I show if the mouse is hovering over a different div, then when the mouse leaves the div is hidden.
In my mousemove callback function I say
$('#divToShow').show(), however I'm wondering if this is inefficient as mousemove events are fired very frequently, and if that div is already shown then it's calling show() for no reason.
Would it be more efficient to check if the div is hidden, and only show it then? Like this:
if ($('#divToShow').is(":hidden")){
$('#divToShow').show();
}
Or another solution would be to have a boolean variable that is set to true the first time the div is shown, then set to false on mouseleave.
Does anyone have any information on an efficient way to show a div in a mousemove function?
Since you're using Jquery, a more efficient way to do what you want is using a .hover(handlerIn, handlerOut) callback, so you don't need to worry about creating a flag or something like that.
The handlerIn will be triggered only one time, when the mouse enter on the target div (as you can see on the console.log('show') call). The handlerOut will also be executed only one time, when the mouse leaves the target div.
On the example below, when the mouse hover #div-b the #div-a content will be visible and when it leaves, the content will be hidden:
$(function() {
$('#div-b').hover(
function() {
console.log('show');
$('#div-a').show();
},
function() {
console.log('hide');
$('#div-a').hide();
}
);
});
#div-a {
display: none;
padding: 20px;
}
.wrapper {
margin: auto;
background-color: darkcyan;
color: white;
height: 100px;
margin-bottom: 10px;
}
#div-b {
padding: 20px;
height: 50px;
background-color: black;
color: white;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="wrapper">
<div id="div-a">
I'm visible!
</div>
</div>
<div id="div-b">
Hover me
</div>
First of All , i let you inspect source code of $.fn.show, then , see , at the end , my answer :
show: function() {
return showHide( this, true );
}
And showHide source code is :
function showHide( elements, show ) {
var display, elem, hidden,
values = [],
index = 0,
length = elements.length;
for ( ; index < length; index++ ) {
elem = elements[ index ];
if ( !elem.style ) {
continue;
}
values[ index ] = dataPriv.get( elem, "olddisplay" );
display = elem.style.display;
if ( show ) {
// Reset the inline display of this element to learn if it is
// being hidden by cascaded rules or not
if ( !values[ index ] && display === "none" ) {
elem.style.display = "";
}
// Set elements which have been overridden with display: none
// in a stylesheet to whatever the default browser style is
// for such an element
if ( elem.style.display === "" && isHidden( elem ) ) {
values[ index ] = dataPriv.access(
elem,
"olddisplay",
defaultDisplay( elem.nodeName )
);
}
} else {
hidden = isHidden( elem );
if ( display !== "none" || !hidden ) {
dataPriv.set(
elem,
"olddisplay",
hidden ? display : jQuery.css( elem, "display" )
);
}
}
}
// Set the display of most of the elements in a second loop
// to avoid the constant reflow
for ( index = 0; index < length; index++ ) {
elem = elements[ index ];
if ( !elem.style ) {
continue;
}
if ( !show || elem.style.display === "none" || elem.style.display === "" ) {
elem.style.display = show ? values[ index ] || "" : "none";
}
}
return elements;
}
So :
You don't need to check if it is hidden or not $().is(':hidden') because it is already checked in show function (See : if ( elem.style.display === "" && isHidden( elem ) ) { ....)
Use mouseEnter to set a flag (or just show) and on mouseLeave set the flag to the opposite value (or just hide). mouseMove may not be best event since it may be fired more than desired. You may not even keep track of a flag if you just want to show and hide an element.
Can't you use .hover() and .toggle() functions? is mousemove must?
https://jsfiddle.net/tvwpdxum/1/
A better solution would be to use a mouseEnter and mouseLeave like this snippet below:
This is in javaScript but will give you a better idea. If you want it in JQuery and having problems with it I can write it on Pluncker for you. Hope this will help
function show_hide(id) {
var e = document.getElementById(id);
if (e == null){
} else {
if (!e.classList.contains('showClass'))
e.className += " showClass";
else
e.className = "myclass";
}
}
.myclass {
opacity: 0;
margin-top: 25px;
font-size: 21px;
text-align: center;
-webkit-transition: opacity 1s ease-in;
-moz-transition: opacity 1s ease-in;
-o-transition: opacity 1s ease-in;
-ms-transition: opacity 1s ease-in;
transition: opacity 1s ease-in;
}
.showClass{ opacity: 1 }
<div onmouseover="show_hide('deletebutton')" onmouseout="show_hide('deletebutton')">
// image
<div class="myclass" id="deletebutton">DELETE</div>
</div>
Updated
function show() {
$("#deletebutton").show();
}
function hide() {
$("#deletebutton").hide();
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.12.4/jquery.min.js"></script>
<div onmouseover="show()" onmouseout="hide()">
// image
<div class="myclass" id="deletebutton" style="display:none;">DELETE</div>
</div>
In the code below, the CSS display element is not being read by the Javascript and I don't understand why. After putting in a debugger statement I saw display was empty even though I set it in the CSS. I've been staring at it for a while, so I'm probably missing something obvious.
<html>
<head>
<style type="text/css">
div#image{ display: none; }
div#url { display: none; }
</style>
<script type="text/javascript">
function toggleVisibility(id) {
debugger;
var imageStyle = document.getElementById('image').style;
var urlStyle = document.getElementById('url').style;
alert(document.getElementById("image").style.display); // debug for stack
if ( id == "image" ) {
if ( imageStyle.display == "none" ) {
imageStyle.display = "block";
urlStyle.display = "none";
}
}
if ( id == "url" ) {
if ( urlStyle.display == "none" ) {
urlStyle.display = "block";
imageStyle.display = "none";
}
}
}
</script>
</head>
<body>
<form method="post" action="create.php">
<input type="hidden" name="formType" value="create">
<input type="radio" name="type" value="image" onClick="toggleVisibility('image');"> Image <input type="radio" name="type" value="url" onClick="toggleVisibility('url');"> URL
<div id="image">
Image div
</div>
<div id="url">
URL div
</div>
</form>
</body>
</html>
Demo
You can't read css styles of attributes like that but an alternative is to check for an empty value and treat it like display:none
if ( id == "image" ) {
if ( imageStyle.display == "none" || !imageStyle.display) {
imageStyle.display = "block";
urlStyle.display = "none";
}
}
if ( id == "url" ) {
if ( urlStyle.display == "none" || !urlStyle.display) {
urlStyle.display = "block";
imageStyle.display = "none";
}
}
That's because you need to get the computed style of the element.
You can do that using this function:
function getStyle( elem, name ) {
var value;
if (elem.currentStyle) {
value = elem.currentStyle[name];
} else if (window.getComputedStyle) {
value = document.defaultView.getComputedStyle(elem,null).getPropertyValue(name);
}
return value;
}
I've also simplified part of your JS, so you probably wouldn't need to check the style of the element anyway:
if ( id == "image" ) {
imageStyle.display = "block";
urlStyle.display = "none";
}
if ( id == "url" ) {
urlStyle.display = "block";
imageStyle.display = "none";
}
Demo here
JavaScript doesn't natively read styles from elements as set in a style sheet. I think JQuery and other libraries do. In order to get this to work you could et the style attribute on the actual tag itself:
<div id="image" style="display:none">
Image div
</div>
<div id="url" style="display:none">
URL div
</div>
Or, check for an empty value and use that as "none"
The style property on HTMLElement instances only reflects the information for the inline styles for that element (e.g., the style attribute on the tag). To get the computed style of an element, which includes any applied by CSS rules, you have to use getComputedStyle (on browsers that support it) or currentStyle (on browsers that support it).
Slightly off-topic: Reliably getting the computed style for an element is one of the (many) areas where a good JavaScript library can save you a lot of time and trouble, whether it's jQuery, Prototype, YUI, Closure, or any of several others. It's not just the getComputedStyle / currentStyle dichotomy, but various browser quirks as well. Using a good library, you can leverage the huge amount of work and research others have done, so you can concentrate on your specific work. Usually. :-)
For instance, using jQuery you could find out whether the element with the id "image" was visible (which can be affected by display: none, visibility: hidden, etc.) like this:
if ($("#image").visible()) {
// Yes it is
}
Or if you want to check a specific computed style:
if ($("#image").css("display") === "none") {
// It has display: none, either directly or by rule
}
Other libraries will have similar functionality.
Lets say I have a webpage, and all I'm interested is the div with id "content", i.e:
<div id="content"></div>
How do I remove all the other div elements, and just display the div I want?
var all_div_nodes = document.querySelectorAll('div'),
len = all_div_nodes.length,
current = null;
while( len-- ) {
current = all_div_nodes[len];
if( current.parentNode ) {
if( current .id !== 'content' )
current .parentNode.removeChild( current );
}
}
If you can afford using a library like jQuery, this would be even more trivial:
$('div').not('#content').remove();
If you want to remove the sibling DIVs, using jQuery, you can write:
$("#content").siblings("div").remove();
Im trying to figure out a simple way to enable me to select 2 DIV elements using JQuery - here is my attempt : http://jsfiddle.net/MarKP/5/
I need to limit the selections to just 2 and will use the class I add to get the selected objects.
Can anyone point me in a better direction
<div id="1">one</div>
<div id="2">two</div>
<div id="3">three</div>
<div id="4">four</div>
var selected = 0;
var prevSelect;
$('div').click(function() {
if (selected == 2) {
selected = 1;
console.log(prevSelect);
$('#' + prevSelect).removeClass('fill');
}
$(this).addClass('fill');
prevSelect = $(this).attr('id');
selected = selected +1;
});
div {
border: 1px solid blue;
height: 25px;
margin-bottom: 5px;
}
.fill {
background-color: red;
}
I updated your functionality to disallow any selection change if 2 divs are already selected unless you click a selected div to unselect it:
http://jsfiddle.net/MarKP/32/
$('div').click(function(e){
var $et = $(e.target);
if ($et.hasClass('fill')) {
$et.removeClass('fill');
} else {
if ($('.fill').length < 2) {
$et.addClass('fill');
}
}
});
Old solution: http://jsfiddle.net/MarKP/11/
What you want is something like this:
$('.divclass').click(function(){
var cnt=$('.divclass .selected').length;
if(cnt>2) return;
$(this).addClass('selected');
});
This will add the class selected to at most 2 divclass objects. To get the selected objects, you just call $('.divclass .selected').
If you always want to remove the oldest one clicked (unless it is already selected), I'd maintain my own array like this:
Example: http://jsfiddle.net/MarKP/17/
var selected = [];
$('div').click(function() {
if( $.inArray( this, selected ) > -1 ) return;
if( selected.length === 2 ) {
$(selected.shift()).removeClass('fill');
}
selected.push($(this).addClass('fill')[0]);
});
Only add a selected class if there are fewer than two divs returned from a selector for div.selected. Otherwise, remove the selected class. For instance:
$('div').click(function() {
if (!$(this).hasClass("selected") && $("div.selected").length < 2) {
$(this).addClass("selected");
} else {
$(this).removeClass("selected");
}
});