I'm trying to create a function which will add an overlay to a thumbnail image when you hover over it and remove the overlay when you leave it. Here is my HTML...
<div class="thumb"><img src="i/testThumb.gif" /></div>
And here is my jQuery...
$('.thumb').live('mouseover', function(event){
if($(this).find('.overlay').length == 0){
$(this).prepend('<div class="overlay"></div>');
}
return false;
});
$('#galleryPanel .thumb').live('mouseout', function(event){
$(this).find('.overlay').remove();
return false;
});
The trouble is that when the overlay is created the mouse is already over it and that triggers the "mouseout" of the container, which removes the overlay, and it cycles continuously flashing on and off.
Is there an easy solution to this?
I you put one more div into the mix, I think you may find what you are looking for.
<style>
.hover { display:none;}
</style>
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.2.6/jquery.min.js"></script>
<script>
$(document).ready(function(){
$(".image").hover(
function(over) {
$(this).find(".hover").animate({opacity: "show", top: "55"}, "slow");
},
function(out) {
$(this).find(".hover").animate({opacity: "hide", top: "55"}, "slow");
});
});
</script>
<div class='image'>
<div class='imageClass'>
<img src='img1.jpg' />
<div class='hover'>
<img src='img1.jpg' />
</div>
</div>
</div>
Instead of binding mouseout to ".thumb" trying binding it to ".overlay".
$('#galleryPanel .overlay').live('mouseout', function(event){
$(this).remove();
return false;
});
This might sound a little hacky, but you can use a variable (in the case of a dom element, I'd use a css class) to know if this is the first time the event is firing on this element.
Basically, your function looks for the presence of this css class on the dom element, but it's not there by default when you create it. If it's not there, add the class and exit the function. If it is there, the hit is valid and you should execute your overlay functionality. Since you can have multiple classes on a dom element, this shouldn't cause any conflict with any other classes used for styling. I'd say go with a class instead of a custom attribute because custom attributes make your html "invalid" to search crawlers.
Related
I'm building a page that currently contains a few videos and more will be added over time through our CMS (Craft). The container div for each video will have a unique ID, as below:
<div id="video-1"></div>
<div id="video-2"></div>
<div id="video-3"></div>
Every time one of the divs is clicked, I want to run some Jquery. It is the same base Jquery but I want it to only run for the unique video that is clicked, so it should be tied to the ID.
The challenge is - I don't want to have to go to our javascript file and manually add a new selector to run the function(s) each time we add a video. I would like the Jquery to work for each new video that is added through the CMS, without any extra steps. Assume that each video's ID will increase by as a new one is added.
Here is an example of the Jquery I'm working with:
$('#video-1').on('click', function() {
$('#video-1').css('background', 'none');
$('#video-1').css('display', 'block');
$('#video-1').css('position', 'static');
$('iframe').css('display', 'block').attr('src', function() {
return edTalksAutoPlay();
});
});
How / is there a way to achieve what I'm looking to do? Thanks!
The easiest way to achieve this is to group the elements together. You can do that either by adding a class to them, or selecting them by a parent element, eg. #parent > div.
From there you can use the this keyword to refer to the element that raised the event within the handler. I would also strongly suggest you use pre-defined CSS classes to style the elements and use addClass()/toggleClass() to amend them. Something like this:
$('.video').on('click', function() {
$(this).toggleClass('active').prop('src', function() {
return edTalksAutoPlay();
});
});
.active {
background: none;
display: block;
position: static;
}
<div id="video-1" class="video"></div>
<div id="video-2" class="video"></div>
<div id="video-3" class="video"></div>
Finally, note that div elements do not have a src attribute - although I assume this was just an oversight when simplifying the HTML in your question.
When jQuery invokes an event handler, it arranges for this to be bound to the DOM element involved. Thus, $(this) in the event handler will always give you a jQuery object for the element involved with the event.
$('[id^=video]').on('click', function() {
$(this).css('background', 'none');
$(this).css('display', 'block');
$(this).css('position', 'static');
$(this).css('display', 'block').prop('src', function() {
return edTalksAutoPlay();
});
});
I have one problem about add and remove class in my javascript code.
I have created this DEMO from codepen.io
So you can see in demo there is a Click here link. When you click the link then jquery doing
$(document).ready(function() {
$('.buton').click(function (event) {
event.preventDefault();
$('.vduzalani').animate({'opacity':'.50'}, 300, 'linear');
$('.vduzalani').css('display', 'block');
$(this).next('.yazi-paylas').toggleClass('in');
})
});
Then problem is i want to add a .in from .yazi-paylas div tag. What is the problem in my javascript code
That is because .buton is the only child node of its parent and .next() will return nothing, as seen in your markup:
<div class="container">
<div class="buton">Click Here</div>
<!-- .buton is the ony sibling! -->
</div>
<div class="yazi-paylas">ssss</div>
<div class="vduzalani"></div>
You can use .parent('.container') (or just .parent()) or .closest('.container') to go one level up, and select the immediate sibling of .container:
$(document).ready(function() {
$('.buton').click(function (event) {
event.preventDefault();
// You can use chaining, so you don't have to fetch $('.vduzalani') twice
$('.vduzalani')
.animate({'opacity':'.50'}, 300, 'linear')
.css('display', 'block');
// Tranverse DOM
$(this).parent().next('.yazi-paylas').toggleClass('in');
// or
// $(this).closest('.container').next('.yazi-paylas').toggleClass('in');
});
});
See demo fiddle here: http://jsfiddle.net/teddyrised/0g9385k1/
Please try:
$('.yazi-paylas').toggleClass('in');
instead of
$(this).next('.yazi-paylas').toggleClass('in');
Evaluate the parent to get the .yazi-paylas element. Change your code to:
$(this).parent().next('.yazi-paylas').toggleClass('in');
Or, if it doesnt matter the parent, just do:
$('.yazi-paylas').toggleClass('in');
Try to replace your line with this:
$(this).parent().next('.yazi-paylas').toggleClass('in');
$(this) in this case is actually one level deeper than the element you are trying to select.
I am using jquery to expand/hide a piece of content. I then changed it such that the link used to expand/hide the content is a button and that broke it. Here is the code working before I changed to a button:
<body>
<div class="content">
<a class="toggle" href="">Expand box 1</a>
<div class="contentHidden" style="display:none;">Hidden 1</div>
</div>
<div class="content">
<a class="toggle" href="">Expand box 2</a>
<div class="contentHidden" style="display:none;">Hidden 2</div>
</div>
</body>
<script type='text/javascript'>
$(function() {
$(".toggle").click(function(event) {
$(event.target).parent(".content").find(".contentHidden").toggle('slow');
event.preventDefault()
});
});
</script>
However if I change the function to the following it no longer works:
$(function() {
$(".toggle").button({ icons: { primary: 'ui-icon ui-icon-arrowthick-1-e'} });
$(".toggle").click(function(event) {
$(event.target).parent(".content").find(".contentHidden").toggle('slow');
event.preventDefault()
});
});
Its as if the call to button() changes the hierarchy and my search no longer returns the '.contentHidden' div
Regards
Des
Yes, JQuery UI button() creates a new hierarchy below the original link (adds a couple of spans). One of these spans is the new clickable item, so it goes wrong for this reason alone (the clicked element is one level deeper than before), so use closest instead of parent:
$(".toggle").button({
icons: {
primary: 'ui-icon ui-icon-arrowthick-1-e'
}
});
$(document).on('click', '.toggle', function (event) {
$(event.target).closest(".content").find(".contentHidden").toggle('slow');
event.preventDefault()
});
Working JSFiddle here: http://jsfiddle.net/HxKLy/
The other issue, of using click instead of say a deferred on is actually a red herring in this instance, but I will retain below for reference.
Binding to specific DOM elements with click, means that as soon as you change the DOM that click event has been detached. Generally you will want to use the deferred calling syntax of on instead of a click, but in this case it makes no odds.
e.g.
$(document).on('click', '.toggle', function(event)...
instead of
$(".toggle").click(function(event)
Just to prove it was not the actual issue, here is a variation of the fiddle with the click back:
http://jsfiddle.net/HxKLy/1/
I'm trying to implement an accordian style box on some content. However there are 4-6 of these boxes on 1 template, all with different classes for obvious reasons. However I want to try and make the code as easy to read as possible and I don't want to duplicate the code for each class name. I'm assumung jQuerys (this) method would work but i'm not 100% sure how to use it.
Here is my JS code:
<script type="text/javascript">
$(document).ready(function(){
$(".block-50_hoverHeader").click(function (){
//alert("clicked");
$(".scrollText").slideToggle(1000);
});
});
</script>
So the .scrollText class is the div that holds all the content which needs to be displayed after the onClick function. But currently when I click the header all the .scollText divs appear on the page. So i want it to only appear on the parent header div that is being clicked.
Here the HTML:
<div class="block-50 left textHoverWrapOne">
<img src="" alt="" /> (Image working as BG Image)
<div class="block-50_hoverHeader"><p>This is a header!</p></div>
<div class="block-50_textHoverOne trans_click scrollText">
This is the content that needs to be displayed after the
</div>
</div>
Find the scrollText relative to the clicked block-50_hoverHeader element. In this case it is the next sibling, so you can use .next()
Inside the event handler this points to the element in which the handler is registered, in this case it is the block-50_hoverHeader element, so we can find the next scrollText using $(this).next()
jQuery(function ($) {
$(".block-50_hoverHeader").click(function () {
$(this).next().slideToggle(1000);
});
});
Demo: Fiddle
There are a number of ways to accomplish this. I prefer to grab the shared parent and then use find as I find this is a bit less likely to break due to minor modifications to the html structure.
$(".block-50_hoverHeader").click(function (){
$(this).closest(".textHoverWrapOne").find(".scrollText").slideToggle(1000);
});
Why not targeting the whole div??
jQuery(function ($) {
$(".block-50").click(function () {
$(this).find('.scrollText').slideToggle(1000);
});
});
I want to style my div using jquery, i want to make it when i click the background become blue, when i unclick(i clicked on other part other than div in my page) the background become red. Sorry for my bad english
With a click handler on document you can capture all the click events, and if the click is not on your div, you can revert to red
$('#yourdiv').click(function() {
$(this).css('background-color', 'blue');
});
$(document).click(function(e) {
if(!$(e.target).is('#yourdiv'))
$('#yourdiv').css('background-color', 'red');
});
See example: http://jsbin.com/oyunin/1/edit
Im not sure about performace, but you can do something like:
$("*").not("your element selector").on("click",function(){
//other elements click
});
a good practice will be doing this:
$("*","some container").not......
if you want to change the div when you click on another div, you can add a click event on the other div, or perhaps you want to add the click event to the entire body of the document so that if a click event is not captured and stopped by another listener, it will go through to the body's event listener.
Try this,
Jquery Code:
$(document).mouseup(function (e){
var wrapDiv = $(".wrapper");
if(wrapDiv.has(e.target).length === 0){
wrapDiv.css('background-color','red');
}
$('.wrapper').click(function(event){
$('.wrapper').css('background-color','blue')
});
});
CSS code:
<style type="text/css">
.wrapper{
background-color:#0FF;
width:200px;
height:200px;
}
</style>
Html code:
<div class="wrapper">
</div>
The way I solved it in my site was adding a click event to the div in question, and another click event to the document in general. The method stopImmediatePropagation() makes it work as expected:
Here's a jsFiddle with a working example.
HTML:
<div class="colored"></div>
JQUERY:
$(document).click(function(e){
$(".active").removeClass("active");
});
$(".colored").live("click",function(e){
$(this).addClass("active");
e.stopImmediatePropagation();
});
CSS:
.colored{background:red}
.colored.active{background:blue}