Just learning jQuery. What I want is to grab the src of the image and display it in a fixed division, kind of like a pop up, with the title of the image. But I'm stuck at getting the src of the image.
When I tried using the .attr(), its giving me undefined.
HTML:
<div id="album">
<div class="pic">
</div>
<div class="screen">
<h1 class="title">Photo 1</h1>
<img src="images/1 png.png" class="image" />
<p class="description">This is a description</p>
</div>
<div class="screen">
<h1 class="title">Photo 1</h1>
<img src="images/1 png.png" class="image" />
<p class="description">This is a description</p>
</div>
<span class="clear_left"></span>
</div>
css:
.screen {
border: 1px solid green;
margin: 10px auto;
float: left;
cursor:pointer
}
.image {
width: 300px;
}
.title {
font-size: 30px;
}
.description {
font-size: 25px;
}
.pic {
width: 600px;
position:fixed;
}
js:
$(document).ready(function () {
$(".pic").hide();
$(".screen").click(function () {
display();
});
});
function display() {
var source = $("img",this).attr("src");
alert("The souce of the image is " + source);
}
The problem is, the display() method does not have the context of the element being clicked. Hence it is showing undefined
So, try this:
$(document).ready(function () {
$(".pic").hide();
$(".screen").click(function () {
display($(this));
});
});
function display($this) {
var source = $("img", $this).attr("src");
alert("The souce of the image is " + source);
}
Working demo
Dont wrap your function call with another anonymous function:
Demo: http://jsfiddle.net/9KgSQ/
$(".screen").click(display);
This will now pass along this to your function.
this in the display function is referring to your anonymous function, not the element. You don't need to wrap it. $('.screen').click(display) will make sure that this references the .screen element.
I would also change display to do this instead:
function display() {
var source = $(this).find('img').attr('src');
alert("The source of the image is " + source);
}
This wraps jQuery around the .screen element that was clicked on and finds the img element inside of it. I think it's a little more clear, but this is just a preference thing.
It's because the value of this in display is not the same as the value of this in the click function for .screen. You can do a test for that by calling console.log(this); within the display function to see what the value of this is.
If you want to pass the value of this on to display you can use the call function like so:
$(document).ready(function () {
$(".pic").hide();
$(".screen").click(function () {
display.call(this);
});
});
function display() {
var source = $("img", this).attr("src");
alert("The souce of the image is " + source);
}
Or you could completely get rid of the anonymous function and pass in display directly:
$(".screen").click(display);
It's because your src IS undefined.
function display() {
var source = $("img",this).attr("src", "images/okay.jpg");
alert("The souce of the image is " + source);
}
Related
I have an array, store, containing three images. I'm trying to display each image from this array in ascending order on each button click.
ie: first there should not be any image, on first click of the button the first image of the array should load on class level.
How can I achieve this?
function store()
{
var level=['https://via.placeholder.com/75x75?text=1','https://via.placeholder.com/75x75?text=2','https://via.placeholder.com/75x75?text=3'];
}
<div class="level" style=" width=100px; height:100px; border:2px solid #000;">
<img src="" id="levelimage" style=" width=100px; height:100px;"/>
</div>
<button onclick="store()">Click me</button>
I'm a bit confused of what you're asking but I think this will do the trick:
var i = 0;
function store() {
var level = ['https://via.placeholder.com/75x75text=1','https://via.placeholder.com/75x75?text=2','https://via.placeholder.com/75x75?text=3']
document.querySelector("img").src=level[i++];
if (i>level.length-1)i=0;
}
<div class="level" style=" width=100px; height:100px; border:2px solid #000;">
<img src="" id="levelimage" style=" width=100px; height:100px;"/>
</div>
<button onclick="store()">Click me</button>
Introduce a global variable i that will stay consistent no matter which function call was it and increase it by one every click, also use DOM to select your img tag and change it's src
var i=0;
function store() {
var level=['https://via.placeholder.com/75x75?text=1','https://via.placeholder.com/75x75?text=2','https://via.placeholder.com/75x75?text=3'];
document.querySelector(".level").firstChild.src=level[i];
i+=1;
}
// A named function, which expects two arguments:
// e: the Event Object, passed automatically from
// EventTarget.addEventListener();
// haystack: the array of images.
function imageProgress(e, haystack) {
// finding the relevant image by navigating the DOM:
// e.target gives the element that initiated the event,
// previousElementSibling finds the previous sibling that is
// an element, Element.querySelector() finds the first (if any)
// element that matches the supplied CSS selector:
let target = e.target.previousElementSibling.querySelector('img'),
// finding the current image:
currentImage = target.src,
// finding the index of the current image within the
// array of images (this returns -1 if the image
// is not found):
currentIndex = haystack.indexOf(currentImage);
// updating the src property of the <img> element;
// we first increment the currentIndex variable, and
// divide that updated index by the length of the Array.
// if there is no current image shown (or the src can't be
// found in the Array) we start at the first array-index;
// otherwise we increment through the Array:
target.src = haystack[++currentIndex % haystack.length];
}
let images = ['https://via.placeholder.com/75x75?text=1', 'https://via.placeholder.com/75x75?text=2', 'https://via.placeholder.com/75x75?text=3'],
// finding the <button> element:
button = document.querySelector('button');
// using unobtrusive JavaScript to bind the event-handler,
// using an arrow function:
button.addEventListener('click', (e) => {
imageProgress(e, images)
});
*,
::before,
::after {
box-sizing: border-box;
margin: 0;
padding: 0;
}
.level {
width: 100px;
height: 100px;
border: 2px solid #000;
display: flex;
}
.level img {
margin: auto;
}
.level,
button {
margin: 1em;
}
<div class="level">
<img src="" id="levelimage" />
</div>
<button>Click me</button>
JS Fiddle demo.
References:
Arrow functions.
document.querySelector().
Element.querySelector().
EventTarget.addEventListener().
NonDocumentTypeChildNode.previousElementSibling.
I'm having a problem here to create a generic function on JQuery for my "boxes".
I have a visible box with contents, but I will have some other boxes(all DIVs) with another contents and forms. It can be just a DIV ou a full scructured content.
For exemple, a structure like this:
| DIV CONTAINER
|---- DIV CONTACT FORM
|---- ---- DIV RESET PASSWORD
|---- DIV RESET PASSWORD
|---- DIV SIGN UP FORM
|---- DIV RULES
|---- TERMS
Right now I'm doing the box exchanging manually like this code:
$( "#contact-form-link" ).on( "click", function()
{
$( "#contact-form-link" ).fadeOut( "normal", function()
{
$( "#reset-password-form" ).fadeIn( "normal" );
});
});
$( "#reset-password-form" ).on( "click", function()
{
$( "#reset-password-form" ).fadeOut( "normal", function()
{
$( "#contact-form-link" ).fadeIn( "normal" );
});
});
It's unecessary so much code!
I would like to create a function with parameters, so, I can call it from a LINK inside any part of the current box.
A function like:
function exchangeBoxes(box_fadeout,box_fadein)
{
$("box_fadeout").on("click", function()
{
$("box_fadeout").fadeOut( "normal", function()
{
$("box_fadein").fadeIn( "normal" );
});
});
};
So this way, I can call this function from a link passing which DIV will fadeOut and which will fadeIn.
I'm in #contact-form and want to change to #reset-password-form?
Click Here
I need to be able to call the function from any link, anywhere on the page, WITHOUT setting a ID or CLASS for the link, only for the DIVS.
I'm using one function inside another so the IN page only loads when the OUT page is done.
ONLY ONE div can be displayed at time. When one fades out, the other one called will fadeIN. Always callig by the ID, never by CLASS.
Any help to create this generic function is welcome!
Thanks!
You can attach the event to parent div, check id of element at click event, pass the element as either first or second parameter to exchangeBoxes depending on the id of the element.
function exchangeBoxes(a, b) {
$(a).fadeOut( "normal", function() {
$(b).fadeIn( "normal" );
});
}
var elems = ["contact-form-link", "reset-password-form"];
$("#container").on("click", "[id]", function(e) {
if (this.id === elems[0]) {
exchangeBoxes("#" + elems[0], "#" + elems[1])
}
if (this.id === elems[1]) {
exchangeBoxes("#" + elems[1], "#" + elems[0])
}
});
or use multiple selectors when assigning click event
var elems = ["contact-form-link", "reset-password-form"];
$("#contact-form-link, #reset-password-form")
.on("click", function(e) {
exchangeBoxes(this, "#"
+ elems.filter(function(id) {return id !== e.target.id})[0])
});
You could attach a class e.g. exchange to your link and use a data attributes to store the ID of the elements you want to fade in and out.
<a class="exchange" href="#" data-out="#contact-form" data-in="#reset-password-form">Click Here</a>
<a class="exchange" href="#" data-out="#reset-password-form" data-in="#contact-form">Click Here</a>
Then attach an event handler
$(".exchange").on("click", function () {
var data = this.dataset;
$(data.out).fadeOut("normal", function () {
$(data.in).fadeIn("normal");
});
});
If you strictly only focusing on those two DIVs, you could also use fadeToggle() without having to use data attributes
$(".exchange").on("click", function () {
$('#contact-form').fadeToggle("normal", function () {
if ($(this).is(':visible')) {
$("#reset-password-form").fadeOut("normal");
} else {
$("#reset-password-form").fadeIn("normal");
}
});
});
In addition to the answer above, you can also acheive this without using inline onclick. I prefer to keep the javascript separate.
Give each link a data-link with the box they link to. e.g.
Go to box 2
Then in js you can pick this up and do the required fade in/out as per the example:
p.s. sorry for the css I'm really bored with nothing better to do.
$(".box a").click(function() {
linkTo = $(this).data("link");
$(this).parent().fadeOut("normal", function() {
$(linkTo).fadeIn();
});
});
body {
background: #333;
color: #ccc;
font-family:sans-serif;
}
.box {
margin: 0 auto;
width: 300px;
border: 1px solid #ccc;
text-align: center;
display:none;
}
.box a {
text-decoration: none;
color: #ccc;
border:1px solid #ccc;
padding: 10px;
margin: 0 0 10px 0;
display: inline-block;
}
.box a:hover {
background: #333;
color: #ccc;
}
#box1 {
background: #CD5C5C;
display:block;
}
#box2 {
background: #6B8E23;
}
#box3 {
background: #6A5ACD;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.1.1/jquery.min.js"></script>
<div class="container">
<div class="box" id="box1">
<h3 class="title"> I am Box 1 </h3>
Go to box 2
<br>
Go to box 3
</div>
<div class="box" id="box2">
<h3 class="title"> I am Box 2 </h3>
Go to box 1
<br>
Go to box 3
</div>
<div class="box" id="box3">
<h3 class="title"> I am Box 3 </h3>
Go to box 1
<br>
Go to box 2
</div>
</div>
Well, thank you all!
I put all responses together and came up with this:
<div id="contact">
<h3>CONTACT</h3>
<p>My form</p>
Reset Password
About
</div>
<div id="reset" style="display:none">
<h3>RESET</h3>
<p>Reset password form</p>
Back to contact
</div>
<div id="about" style="display:none">
<h3>ABOUT</h3>
<p>Some info.</p>
Back to contact</li>
</div>
And the JQuery very clean:
function exchangeBoxes(a, b)
{
var a = "#" + a;
var b = "#" + b;
$(a).fadeOut( "normal", function()
{
$(b).fadeIn( "normal" );
});
}
Thank you very much, guys!
Lately I've been trying my hand at animation using CSS and jQuery, it went well, however, now I want to do a bit more.
That is, once the user clicks information should show up on top of the image.
At the moment, I just have a few tags on which I perform the animations and class toggles.
My question is, I've thought about doing the following:
<div class= "singleImage">
<img src.... class="actualImage">
<p>text to put over the image</p>
</div>
This would be done per image which means that I'll have about 5 of them with different images.
However, I don't know how to go about selecting the previous element of class "actualImage".
Has anyone got any suggestions?
Thank you
Use the jQuery prev function. Example: Assume you want to select the image previous to the second image:
var foo = $(".singleImage").eq(1);
var bar = $(foo).prev().find('.actualImage');
Fiddle
Try this:
$('singleImage').children('.actualImage').prev();
I'm not sure why you are trying to select the previous element, but you could do something akin to this:
Bind a function to the click event for the element containing your image and caption.
Inside this function, toggle the caption.
Also, bind a click event handler to the body to detect clicks "off" the containing element.
HTML:
<a href="#" class="has-caption">
<img src="http://placehold.it/300x300" />
<span class="caption">This is a caption</span>
</a>
CSS:
a.has-caption { position: relative; }
a.has-caption .caption {
background: rgba(0, 0, 0, .25);
bottom: 0;
color: #fff;
display: none;
height: 20px;
left: 0;
line-height: 20px;
position: absolute;
width: 100%;
}
a.has-caption img { vertical-align: bottom }
JavaScript
$('a.has-caption').on('click', function(e) {
e.preventDefault(); e.stopPropagation();
var self = $(this)
, tmpId = 'toggle-' + Date.now();
self.addClass(tmpId);
$('span.caption', self).toggle();
$('body').one('click', function(e) {
if (!$(event.target).closest('.' + tmpId).length) {
$('span.caption', '.' + tmpId).hide();
self.removeClass(tmpId);
};
});
});
http://jsfiddle.net/83s7W/
I have a page with 2 buttons that swap an image in a div from one to the other. I would like a image to be in the div when the page loads, this is my attempt:
Script:
<script type="text/javascript">
function startPic(){
document.getElementById('imageRoll').style.backgroundImage="url(balanceSheet.jpg)";
}
function changeStyle1(){
document.getElementById("imageRoll").style.backgroundImage="url(balanceSheet.jpg)";
}
function changeStyle2(){
document.getElementById("imageRoll").style.backgroundImage="url(incomeStatement.jpg)";
}
document.body.onload = startPic();
</script>
HTML:
<div style="width:auto; float: left;">
<div style="width:200px; height:30px; padding: 5px;"><img style="border: 0px; vertical-align:middle; padding: 5px;" onmouseover="this.src='standardButton_over.png'" onmouseout="this.src='standardButton.png'" src="standardButton.png" />See balance sheet</div>
<div style="width:200px; height:30px; padding: 5px;"><img style="border: 0px; vertical-align:middle; padding: 5px;" onmouseover="this.src='standardButton_over.png'" onmouseout="this.src='standardButton.png'" src="standardButton.png" />See income statement</div>
</div>
<div id="imageRoll" style="background-repeat:no-repeat; width:335px; height:465px; float: left;"></div>
Using the above code the swap performs exactly as expected, and if an alert is set in the startPic function it works if it is before the image embed line, but the alert does not work if it is below the image embed line. For some reason the image embed line in the startPic function does not work.
Remove the parenthesis when you attach the event, else you are calling the function and not attaching it:
// good - attaches the function to the onload of the body
document.body.onload = startPic;
// bad - won't work as you would expect
document.body.onload = startPic();
You could always do things with event listeners; something like:
var load = function(fn){
var d = document;
if(d.addEventListener) {
d.addEventListener("DOMContentLoaded", fn, false);
} else {
d.attachEvent("onreadystatechange", function(){
if(d.readyState === "complete") {
fn();
}
});
}
};
load(startPic);
Which will works cross browser quite nicely.
So I'm making a image-toggling function that can toggle between two images. More specifically, it toggles the background images of a div.
I'm using the jquery .data() function as a counter where one = first image and two = toggled image.
Here's the algorithm I'm using:
click button to start function.
When I click on the div, if the data is equal to "one", replace image and set data to "two".
When I click the image again, set the image back to the original image and set data equal to "one" so that the function can repeat itself.
It seems to replace the image on the first try, as in the first "if", but it doesn't replace the image again on the second try (the else part). It seems to never reach the else part, even though the first if should return false and then go to the else.
Any help will be appreciated. Also, I know there is a .toggle() function and other image-toggling methods, but I must use this one because this is only a small, edited chunk of a larger program.
Here's the code:
<!DOCTYPE html>
<html>
<head>
<script src="jquery.js"></script>
<link rel="stylesheet" type="text/css" href="mouseovertestlayout.css" />
<script>
function startEdit()
{
$("div").click(function ()
{
if (($(this).data('kangaroo')) == "one")
{
$(this).css('background-image', "url(image2.png)");
$(this).data('kangaroo',"two");
}
else
{
(this).css('background-image', "url(image1.png)");
$(this).data('kangaroo',"one");
}
});
}
</script>
</head>
<body>
<div class="container" data-kangaroo="one" ></div>
<button onclick="startEdit()"> </button>
</body>
</html>
Here's my .css
.container
{
width: 20px;
height: 20px;
line-height: 0;
border-style:solid;
border-width:1px;
border-color:red;
padding: 20px;
background-repeat:no-repeat;
background-image:url('image1.png');
}
You have a typo in your "else" first line is the $ missing at (this)
You are missing a $ in else clause.
Fixed:
function startEdit() {
$("div").click(function ()
{
if (($(this).data('kangaroo')) == "one")
{
$(this).css('background-image', "url(image2.png)");
$(this).data('kangaroo',"two");
}
else
{
$(this).css('background-image', "url(image1.png)");
$(this).data('kangaroo',"one");
}
});
}
Try like this
if (($(this).attr("data-kangaroo")) == "one") //Here is the edit
{
$(this).css('background-image', "url(image2.png)");
$(this).data('kangaroo',"two");
}
else
{
$(this).css('background-image', "url(image1.png)"); //Here put "$" before (this)
$(this).data('kangaroo',"one");
}
What you want to do can be done much shorter if you use a class and toggleClass.
Demo: http://jsbin.com/anazoq/1/edit
HTML:
<div class="container"></div>
<button>Toggle</button>
CSS:
div {
...
background: url(image1.png) no-repeat;
}
.switch {
background-image: url(image2.png);
}
JavaScript:
$('button').click(function() {
$('div').toggleClass('switch');
});