I'm rather new to jQuery and I'm trying to make a cool little menu effect where when the user hovers over a element (#nav li) it will animate to a larger width, which will reveal the full background image. Each of the menu items has a ID to explicitly set a width (since they are all different in size), so #nav1 might be 80px whereas #nav2 is 90px. So I found this: How to get all of the IDs with jQuery? and that helped me to create a array but now I'm having problem figuring out how to insert it into the animation. I figured I would need to do a each or for loop. But like I said I'm rather new to jQuery and am having some problems.
So basically I'd like the variable chgWidth to return the width() of the currently hovered #nav and then I would plug that variable into the animate except I would add 30px for instance, or on the hover off I would subtract 30px.
Any idea? Here is my current code...
$(function(){
var chgWidth = $("#nav [id]").map(function(id) {
return this.id;
});
$.each(chgWidth,function(n,value){
$('#nav li').hover(function() {
$(this).stop(0,1).animate({"width" : chgWidth+"px" });
},
function(){
$(this).stop(0,1).animate({ "width" : chgWidth+"px" });
});
});
Sample HTML
<div id="menu">
<ul id="nav">
<li id="nav1"><a alt="" href="#">home</a></li>
<li id="nav2"><a alt="" href="#">about us</a></li>
<li id="nav3"><a alt="" href="#">weddings & events</a></li>
<li id="nav4"><a alt="" href="#">gallery</a></li>
<li id="nav5"><a alt="" href="#">accolades</a></li>
<li id="nav6"><a alt="" href="#">blog</a></li>
<li id="nav7"><a alt="" href="#">contact us</a></li>
</ul>
</div>
Sample CSS:
#menu { width: 100%; overflow: hidden; padding:0px 0px; background: #ffc4a0;}
#nav { position: relative; left: 50%; float: left;}
#nav li { position: relative; right: 50%; float: left; padding: 0 5px; margin: 0 5px; overflow:hidden; }
#nav1 { width:55px; }
#nav2 { width:80px; }
#nav3 { width:175px; }
#nav4 { width:60px; }
#nav5 { width:85px; }
#nav6 { width:40px; }
#nav7 { width:100px; }
#nav li a { color: #ffffff; text-decoration: none; font: bold 16px Verdana, Arial, Helvetica, sans-serif; }
Based on the answer I got this is what I ended up doing and it seems to work good (Thanks to Joel and krdluzni):
$(function(){
$("#nav [id]").each(function(){
$(this).hover(function() {
$(this).stop(0,1).animate({"width" : "+=30" });
},
function(){
$(this).stop(0,1).animate({ "width" : "-=30" });
});
});
});
jQuery as of a short while ago accepts a += like syntax for widths and other numeric values in animate. See the second last paragraph in the overview (and the examples as well) here: http://docs.jquery.com/Effects/animate#paramsdurationeasingcallback
You don't actually need to get the ids in an array so much as you need to assign an animation to each element in nav that has an id.
Instead of mapping the ids to your chgWidth variable, use each to iterate over the collection of elements and set each one individually.
$(function(){
$("#nav [id]").each(function(){
$(this).hover(function() {
$(this).stop(0,1).animate({"width" : this.id+"px" });
},
function(){
$(this).stop(0,1).animate({ "width" : this.id+"px" });
});
});
});
When you use each to iterate over a collection of elements, the this context is set to the current iterating element.
No each function is required! If a selector returns multiple elements, all of the elements recieve the function chained to them.
This is almost right:
$("li #nav").hover(
function()
{
$(this).stop(0,1).animate({"width" : this.width()+30 });
//save original width somehow
},
function()
{
$(this).stop(0,1).animate({ "width" : this.width()-30 });
//retrieve original width
});
);
You just need to save the widths somehow. Perhaps they can be read from the CSS.
Related
I have several div elements aligned in a grid. I want them to have their specific different background images when the user hovers over them which disappear when the mouse leaves the div. Basically it's a users information page where every square has the data of a user. When people hover over the squares, the users' images appear as background images. Here's the HTML:
<div class="contributor">
Some great stuff here
</div>
Here's the jQuery code I'm currently using. The problem: It assigns the same image to every div while I want different images for each div.
$(document).ready(function(){
$('.contributor').mouseenter(function(){
$(this).addClass('visible');
});
$('.contributor').mouseleave(function(){
$(this).removeClass('visible');
});
});
Here's the code for the 'visible' class:
.visible{
background-image: url('../res/dev-1.png');
}
Why do you use jQuery? use just CSS and pseudo-class :hover.
.contributor:hover{
background-image: url('../res/dev-1.png');
}
apply for diffrent div:
.contributor.diff-div:hover{
background-image: url('../res/dev-2.png');
}
If you can do something in the CSS, it is almost always it will be a better solution than using JavaScript
First, save the image url in an attribute named "imageurl" (which isn't parsed by the browser):
<div class="contributor" imgageurl="../res/dev-1.png"></div>
<div class="contributor" imgageurl="../res/dev-2.png"></div>
Then, use this jQuery code:
$('.contributor').mouseenter(function(){
var imgageUrl = $(this).attr("imageurl");
$(this).css("background-image" , imgageUrl);
});
$('.contributor').mouseleave(function(){
$(this).css("background-image" , "none");
});
Of course, you also have to build the HTML dynamically.
may be you can consider css function instead of addClass.
$(document).ready(function(){
$('.contributor').mouseenter(function(){
if(this.id == "one")
$(this).css("background-image" , "url('../res/dev-1.png')");
else if(this.id == "two")
$(this).css("background-image" , "url('../res/dev-2.png')");
});
$('.contributor').mouseleave(function(){
$(this).css("background-image" , "none");
});
});
Try this with jquery. suppose you have six images from dev-1.png to dev-6.png then it will set them as bacground for div number 1 to 6 respectively
$(document).ready(function(){
$('.contributor').mouseover(function(){
var index = $("div").index(this);
index++;
var bI= "background-image:url('../res/dev-"+index+".png');";
$("this").eq(index).attr('style',bI);
});
$('.contributor').mouseleave(function(){
var index = $("div").index(this);
index++;
var bI= "background-image:none";
$("this").eq(index).attr('style',bI);
});
});
For reference (Too troublesome and Won't apply if you have a ton of elements)
This can be achieved with pure CSS.
images might take a second to load (random image services)
Working example: (not responsive open in full page)
.optionlist li {
background: #111;
color: #999;
padding: .5em;
list-style-type: none;
border: 1px solid;
max-width: 70px
}
.optionlist li:hover {
background: red;
}
.optionlist li:hover:after {
content: '';
width: 800px;
height: 600px;
position: fixed;
top: 30%;
left: 50%;
transform: translate(-50%, -50%);
}
/* Start Background Control */
#red:after {
background: url(http://lorempixel.com/800/600/)
}
#blue:after {
background: url(http://lorempixel.com/800/601/)
}
#green:after {
background: url(http://lorempixel.com/801/600/)
}
#yellow:after {
background: url(http://lorempixel.com/801/601/)
}
#orange:after {
background: url(http://lorempixel.com/799/600/)
}
#white:after {
background: url(http://lorempixel.com/800/599/)
}
#black:after {
background: url(http://lorempixel.com/801/599/)
}
/* End Background Control */
<div class="optionlist">
<ul>
<li id="red">Red</li>
<li id="blue">Blue</li>
<li id="green">Green</li>
<li id="yellow">Yellow</li>
<li id="orange">Orange</li>
<li id="white">White</li>
<li id="black">Black</li>
</ul>
</div>
I keep getting the error cannot read property left of undefined when I drag the sortable jQuery UI elements around. Everything is working like I intend but I keep getting the error and would like to fix the problem causing it.
The intent is to have a sortable list with multi-select capability so that you are not forced to drag one element at a time. Like I said that is working and I followed the code on this fiddle
The strange thing is when I created a codepen to include with this question I am not getting the error message in the console anymore. I tried codepen and jsfiddle. I realize it may be difficult to troubleshoot if you can not see the error for yourself but am hoping someone might be able to spot a mistake or give me suggestions on what to check.
Here is my codepen and some code:
EDIT:
The problem has been solved thanks to a comment. I needed to change my jQuery version.
HTML:
<div id="wrapper">
<ul id="elePool" class="sortme">
<li class="draggable element" data-element="1">sku</li>
<li class="draggable element" data-element="2">type</li>
<li class="draggable element" data-element="3">attribute_set</li>
</ul>
<ul id="eleGroups">
<li class="sortme group attribute required" id="group-weight"></li>
<li class="sortme group attribute required" id="group-visibility"></li>
<li class="sortme group attribute" id="group-status"></li>
<li class="sortme group attribute" id="group-short_description"></li>
</ul>
<ul class='custom-menu' id="elementMenu">
<li class='visibleElement' data-action="duplicate">Duplicate</li>
<li class='visibleElement' data-action="delete">Delete</li>
<li class='visibleElement' data-action="copy">Copy</li>
<li class='visibleElement' data-action="cut">Cut</li>
</ul>
<ul class='custom-menu' id='attributeMenu'>
<li class='visibleAttribute' data-action="paste">Paste</li>
</ul>
</div>
CSS:
ul {
padding: 0;
}
#elePool,
#eleGroups {
float:left;
margin-right:30px;
width:300px;
border:1px solid #808080;
min-height:25px;
}
#eleGroups {
min-height:300px;
}
li.selected {
background-color: #DAA520 !important;
}
#eleGroups .group li,
#elePool li {
border:1px solid #808080;
background-color:#E0FFFF;
line-height:25px;
cursor: -webkit-grab;
cursor: move;
text-indent:15px;
list-style: none;
}
#eleGroups > li {
position:relative;
box-sizing: border-box;
min-height:100px;
border:1px dashed #D3D3D3;
padding-top: 20px;
list-style: none;
}
#eleGroups > li:after {
position:absolute;
top:1px;
left:2px;
font-size:16px;
text-transform: uppercase;
color: #808080;
}
li.group {
float: left;
width: 33.3%;
}
ul#eleGroups {
width:50%;
}
.required {
background-color:#FFEBE8;
}
.complete {
background-color:#EEFFAA !important;
}
/* The whole thing */
.custom-menu {
display: none;
z-index: 1000;
position: absolute;
overflow: hidden;
border: 1px solid #CCC;
white-space: nowrap;
font-family: sans-serif;
background: #FFF;
color: #333;
border-radius: 5px;
padding: 0;
}
/* Each of the items in the list */
.custom-menu li {
padding: 8px 12px;
cursor: pointer;
list-style-type: none;
}
.custom-menu li:hover {
background-color: #DEF;
}
#group-weight:after {content: 'weight'}
#group-visibility:after {content: 'visibility'}
#group-status:after {content: 'status'}
#group-short_description:after {content: 'short_description'}
JS:
function addElementMenu() {
$('.element').on("contextmenu", function (e) {
// Avoid the real one
e.preventDefault();
e.stopPropagation();
//set clicked item
clicked = $(this);
parent = $(this).parent().attr('id');
// Show contextmenu
$("#elementMenu").finish().show().css({
top: event.pageY + "px",
left: event.pageX + "px",
display: 'block'
});
});
}
function addAttributeMenu() {
$('.attribute').on("contextmenu", function (e) {
// Avoid the real one
e.preventDefault();
e.stopPropagation();
//set clicked item
clicked = $(this);
parent = $(this).parent().attr('id');
// Show contextmenu
$("#attributeMenu").finish().show().css({
top: event.pageY + "px",
left: event.pageX + "px",
display: 'block'
});
});
}
$('.sortme').on('click', 'li', function(e) {
if(e.ctrlKey || e.metaKey) {
$(this).toggleClass("selected");
} else {
$(this).addClass("selected").siblings().removeClass('selected');
}
}).sortable({
connectWith: ".sortme",
delay: 150,
revert: 0,
helper: function (e, item) {
var helper = $('<li/>');
if(!item.hasClass('selected')) {
item.addClass('selected').siblings().removeClass('selected');
}
var elements = item.parent().children('.selected').clone();
item.data('multidrag', elements).siblings('.selected').remove();
return helper.append(elements);
},
stop: function(e, info) {
info.item.after(info.item.data('multidrag')).remove();
},
update: function(event, ui) {
checkRequired(this);
}
});
function checkRequired(elementToCheck) {
if($(elementToCheck).hasClass('required')) {
if($(elementToCheck).is(':empty')) {
$(elementToCheck).removeClass('complete');
} else {
$(elementToCheck).addClass('complete');
}
}
}
//add the context menus
addElementMenu();
addAttributeMenu();
// If the document is clicked somewhere
$(document).bind("mousedown", function (e) {
// If the clicked element is not the menu
if (!$(e.target).parents(".custom-menu").length > 0) {
// Hide it
$(".custom-menu").hide(100);
}
});
// If the menu element is clicked
$(".custom-menu li").click(function(){
// This is the triggered action name
switch($(this).attr("data-action")) {
// A case for each action. Your actions here
case "duplicate": duplicateItem(clicked); break;
case "delete": deleteItem(clicked); break;
case "copy": copyItem(clicked); break;
case "cut": cutItem(clicked); break;
case "paste": pasteItem(); break;
}
// Hide it AFTER the action was triggered
$(".custom-menu").hide(100);
});
When you load js file?
If you load js files above the dom elements you handle,
your javascript code $( selector ) will not work properly.
Maybe Codepen and fiddle load your js files after dom elements, so the error will not occurs.
check your html file's javascript load point.
Many people likes following.
<html>
<head>
</head>
<body>
<!-- your dom elements -->
<script src="yourJavascript.js"></script>
</body>
</html>
If you load js files just before </body>, you can use your dom elements in yourJavascript.js
I had the same error, although in a somewhat different scenario (I was adding items manually to a sortable list). My problem was also highly sensitive to timing and environment options, sometimes it ran ok, sometimes not.
This stack overflow answer helped me onto the right track (I needed to clone the object before I added it to the list)
Please try to adding containment in sortable.
Default: false
Defines a bounding box that the sortable items are constrained to while dragging.
Note: The element specified for containment must have a calculated width and height (though it need not be explicit). For example, if you have float: left sortable children and specify containment: "parent" be sure to have float: left on the sortable/parent container as well or it will have height: 0, causing undefined behavior.
$( ".selector" ).sortable({
containment: "parent"
});
Have you tried wrapping the whole thing in jQuery, which would delay execution until DOMReady.
$(function () { /*...YOUR CODE HERE...*/ });
hi i have a javascript script for when i click on a img class other images go from invisible to visible and i can keep switching between them.i have added display:none on the css for the images i want to show up. but nothing seems to be working
Javascript
<script>
$('img.home').click(function() {
$('img.video && img.news && img.games && img.music').hide();
});
</script>
HTML
<nav align="middle">
<ul>
<li>
<img src="images/video-1.png" class="video" style="width:100px;height:50px;">
</li>
<li>
<img src="images/news-1.png" class="news" style="width:100px;height:50px;">
</li>
<li>
<img src="images/logo-4.png" class="home" style="width:80px;height:80px;" onclick="$('.video' || '.news' || '.games' || 'music').toggle();" onmouseover="this.src='images/logo-4-hover.png';" onmouseout="this.src='images/logo-4.png';">
</li>
<li>
<img src="images/games-1.png" class="games" style="width:100px;height:50px;">
</li>
<li>
<img src="images/music-1.png" class="music" style="width:100px;height:50px;">
</li>
</ul>
</nav>
CSS
li {
display: inline;
margin-right: .75em;
list-style: none;
margin: 0;
padding: 0;
}
html,body {
height: 100%;
/* new */;
}
ul {
position: fixed;
bottom: 0;
width: 100%;
list-style: none;
margin: 0;
padding: 0;
border: 2px solid #ccc;
border-width: 3px 0;
}
img.video {
display: none;
}
img.news {
display: none;
}
img.games {
display: none;
}
img.music {
display: none;
}
You need to update your code to
$('img.home').click(function() {
$('img.video, img.news, img.games, img.music').hide();
});
Additionally, if you want to toggle on the images then in place of hide(), use toggle()
And also, as #Mark suggested, enclose your script within document ready block.
Try this, use commas instead of the && and try loading script with document ready.
<script>
$(document).ready(function(){
$('img.home').click(function() {
$('img.video , img.news , img.games , img.music').hide();
});
});
</script>
Apart from the selector syntax problem which was already explained in another answers, all your images are placed inside anchor tags. You should also attach a click event handler to these anchors in order to stop event bubbling
This should work for you:
$("li a").click(function(e) {
e.preventDefault();
e.stopPropagation();
})
$('img.home').click(function(event) {
$('img.video , img.news , img.games , img.music').hide();
// OR:
// $(this).closest('li').siblings().find('img').hide();
});
You should also remove onClick attribute from the 'img.home' element as it's unnecesary (and improperly written)
I am curently working on one Javascript to show hover when mouseover.
Here is my Javascript code:
<script>
$(document).ready(function(){
$('.playlogo').mouseover(function () {
$('.company-image-overlay').show();
}).mouseout(function () {
$('.company-image-overlay').hide();
});
});
</script>
Here is my html:
<li class="playlogo"><img src="./uploads/player_thumbs/[blkfeatured_videos.video_id;block=div].jpg" title="<!--[blkfeatured_videos.title;htmlconv=no;ope=max:50;maxhtml;block=div;comm]-->"/><div class="company-image-overlay"></div></li>
I have many <li class="playlogo"> elements on this page.
Here is the CSS code:
.company-image-overlay {
width: 160px;
height: 160px;
background: transparent url(/images/play.png) no-repeat;
border-radius: 15px;
z-index: 1;
opacity: 0.5;
position: absolute;
top: 0.5em;
}
The problem now is that when i mouseover one <li class="playlogo"> it shows the hover efect on all other elements with <li class="playlogo">.
The question is - How i can make the Javascript show hover only on the one element on which i hover with my mouse at the moment?
Thanks in advance!
You need to refer to this and get its children :
$(this).find('.company-image-overlay').show();
Might be able to accomplish this with CSS
.company-image-overlay{
display:none;
}
.playlogo:hover .company-image-overlay{
display:inherit;
}
You need to reference the specific .playlogo that you're hovering, and then use .children() to traverse from within that context. * I'm using .children() because we're only traversing one level. Here's a working example:
http://jsfiddle.net/jr6Vn/
$('.playlogo').each(function() {
$(this).mouseover(function() {
$(this).children('.company-image-overlay').show();
});
$(this).mouseout(function() {
$(this).children('.company-image-overlay').hide();
});
});
I try to create a menu that streches its items to the window width. Could someone please tell me what I'm doing wrong? I know that this question has been asked before but I just don't know what's wrong with my code.
This is what I"m trying to achieve. The red is the window
http://jsfiddle.net/JdGeQ/5/
Javascript
$(function(){
$(window).resize(function (e) {
setTimeout(function () {
resizeButtons();
}, 200);
});
resizeButtons();
});
function resizeButtons() {
var count = $("#menu").length;
var itemwidth = $(window).width / count;
$(".item").css("background", "blue");
$(".item").css("width", itemwidth);
}
css
.elementtop {
position: fixed;
top: 0;
}
.elementfooter {
position: fixed;
bottom: 0;
}
.elementright {
right: 0;
}
ul {
min-width:100%;
padding:0;
margin:0;
float:left;
list-style-type:none;
background: #000000;
}
li {
display:inline;
}
a {
overflow: hidden;
text-decoration:none;
color:white;
background-color:purple;
padding:0.2em 0.6em;
border-right:1px solid white;
}
html
<div>
<ul id="menu">
<li> <a href="#" class="item">
<span>Text text</span>
</a>
</li>
<li> <a href="#" class="item">
<span>Text2</span>
</a>
</li>
<li> <a href="#" class="item">
<span>Text3</span>
</a>
</li>
</ul>
</div>
Thanks in advance.
You have a couple errors in your jQuery code. You need to use width() instead of width, as it is a function call. Also, you are not selecting menu items when you assign count, you are only selecting the #menu.
function resizeButtons() {
var count = $("#menu .item").length;
var itemwidth = $(window).width();
itemwidth = itemwidth / count;
$(".item").css(
"width", itemwidth
);
}
You also need to set display:inline-block or display:block on your anchors, so that you can affect the width.
a { display:inline-block; }
Updated Fiddle
Note: You will also need to account for the padding, etc. on your menu items to get the proper result.
This can be done with pure CSS:
http://cssdeck.com/labs/hgmvgwqc
ul {
min-width:100%;
padding:0;
margin:0;
display: table;
list-style-type:none;
background: #000000;
}
li {
display: table-cell;
width: 33%;
}
a {
overflow: hidden;
text-decoration:none;
color:white;
background-color:purple;
padding:0.2em 0.6em;
border-right:1px solid white;
display: block;
}
This method requires knowing how many list items there are.
With $("#menu").length you're getting the number of occurrences of the #menu element -- 1. You should use the following to get the number of menu items
var count = $("#menu li").length;