Unable to change image src with JavaScript - javascript

I know this has been asked; and I've read most of the asked questions to no avail. I still am having trouble. I want to click an image and have the image source change (thus having the image change).
This is my HTML:
<img id="picture1" onclick="showHide('builder1'); change('picture1');" width="25" height="25" src="pictures/down.png">
Ignore the "showHide('builder1');". It's working. I need help on the change('picture1').
And this is my Javascript:
function change(id)
{
var isDown = true;
var picture = document.getElementById(id);
if(isDown === true)
{
picture.src = "pictures/pullup.png";
isDown = false; //No longer a down arrow...
}
else
{
picture.src = "pictures/down.png";
isDown = true;
}
}
I am able to change the picture once (to 'pictures/pullup.png') but can't change it back.
I also added alerts at certain points in the if/else statement to see where it was at; and it never even reached the 'else' part of the statement.

Move var isDown = true; outside the function scope - define it before the function.
This way, every time you run the function, you set the variable to true first.
Based on Mike's comment: you could also use something like this:
picture.src = "pictures/"
+ (picture.src=="pictures/pullup.png" ?
"pulldown.png"
: "pullup.png");
Or with an IF if you dislike ternary.

You are defining isDown in the same statement, everytime, to be true. So it will never reach the else block of your conditional statement.

Related

turning CSS on / off globally

My goal is to have a button (controlled by a javascript function) that would toggle the entire CSS on the website on and off. I thought this was a common practice and was surprised when I couldn't find a complete solution here or on the web.
Here is what I got.
$("#button").click(function() {
var css = (document.styleSheets[0].enabled = true);
if (css == true)
{
document.styleSheets[0].disabled = true;
css = (document.styleSheets[0].enabled = false);
}
else if (css == false)
{
document.styleSheets[0].disabled = false;
}
});
A simple Jquery function that targets the button by ID and performs an if test. I could've ommited the variable, but this way I am able to check the value easily in console.log. I am able to turn the CSS off, but not back on. The program doesn't even get to the else condition.
I am aware that the else if is not really appropriate, but with just else (and even just with another if condition) the function doesn't run at all.
Second option that I thought of, and which might be much easier is just dynamically changing the contents of the link href attribute, where the path to the css file is given.
But I am struggling to target the href element with Javascript.
This is a simple Boolean toggle so write it as a simple toggle
$("#button").click(function() {
var sheet = document.styleSheets[0];
sheet.disabled = !sheet.disabled;
});
As for why your code isn't working as is,
var css = (document.styleSheets[0].enabled = true);
// same as
var css;
document.styleSheets[0].enabled = true;
css = true;
which means
if (css == true)
// same as
if (true == true)
which always holds so you'll always follow this code path
Well, for one you need to loop through all of the stylesheets.
Also, you can save some lines of code by using a counter, then on each button click increment the counter and use the % modulo operator to turn that into a 1 or a 0, which you can then coerce a boolean from using !!.
var count = 0;
var sheets = document.styleSheets;
$("#button").click(function() {
for(var i in Object.keys(sheets)) sheets[i].disabled = !!(++count % 2);
});
.demo {
background: #888;
color: blue;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="demo">Some Text</div>
<button id="button">Click It</button>
Your problem is that you are doing an assignment when you should be doing an equality check.
You have
var css = (document.styleSheets[0].enabled = true);
But you are really trying to do an equality check, i.e.,
var css = (document.styleSheets[0].enabled == true);
Notice the extra =. The single = does an assignment, so your current code is equivalent to this:
document.styleSheets[0].enabled = true
var css = document.styleSheets[0].enabled; // i.e., true
Because you set enabled to true, your if (css == true) condition is always satisfied, so your code always turns the CSS off and never turns it back on.
The fix, as Paul S. wrote in his answer, is just to toggle the value of document.styleSheets[0].disabled, as in:
$("#button").click(function() {
document.styleSheets[0].disabled = !document.styleSheets[0].disabled;
});
There's no need to set and track a new property enabled.
The issue seems to be that you are doing assignment, and not comparison, on this line:
var css = (document.styleSheets[0].enabled = true);
It should be
var css = (document.styleSheets[0].enabled == true);
Probably simpler, since you have a jquery tag on the question, to just do:
$stylesheets = $('link[rel="stylesheet"]');
$("#button").click(function() {
$stylesheets.attr('disabled', !$stylesheets.attr('disabled'));
});
If you want to modify every href in your DOM,
just use
$('a[href*=]').each(function () {
var $this = $(this);
$this.attr('href', $this.attr('href').replace();
});

Inner HTML if statement not recognizing a div tag

I tested the following code in IE, Chrome, and Firefox and it does not work in any of them. I have read several questions about similar problems but they have not offered solutions that fix my example.
I am trying to create a pause/play button that interfaces with JWplayer (I also want it to interface with flowplayer, once I get the button working) and the image will change depending on which image is currently there. I also have a stop button that stops the player completely and changes the image of the pause/play button to pause.
Here is my current code:
<script type="text/javascript">
function changeimg()
{
var obj = document.getElementById('image1');
var imgtag1 = '<img src=\'PLAY.png\'>';
var imgtag2 = '<img src=\'PAUSE.png\'>';
if(obj.innerHTML == imgtag2)
{obj.innerHTML = imgtag1;}
else
{obj.innerHTML = imgtag2;}
return;
}
function playimg()
{
document.getElementById('image1').innerHTML = '<img src=\'PLAY.png\'>';
return;
}
</script>
<div id="image1" href="#" onclick="changeimg(); jwplayer('mediaspace1').play(); jwplayer('mediaspace2').play(); jwplayer('mediaspace3').play(); jwplayer('mediaspace4').play();"><img src='PLAY.png'></div>
<div href="#" onclick="playimg(); jwplayer('mediaspace1').stop(); jwplayer('mediaspace2').stop(); jwplayer('mediaspace3').stop(); jwplayer('mediaspace4').stop();"><img src='STOP.png'></div>
The play/pause function works, and the first div WILL change into the pause img (so the javascript is going through) and it WILL change back into play if I click on the second div (stop function - triggers playimg() ) but it will not change back into the play image if I click on the pause button again.
For security reasons I can't link the website, but any help would be appreciated
It looks like all you really want to change is the SRC of the IMG tag, not necessarily the entire innerHTML. As machineghost mentions in his comment, there may be whitespace added or other changes to the full HTML that may make your comparison come out as false.
However, you could check if obj.src == "PLAY.png" and set the SRC attribute directly. Something like this:
function changeimg()
{
var obj = document.getElementById('image1');
var img1 = 'PLAY.png';
var img2 = 'PAUSE.png';
if(obj.src == img2)
{obj.src = img1;}
else
{obj.src = img2;}
return;
}
I think the innerhtml you are replacing in changeimg() is affecting the whole obj element, which is a div. So, if(obj.innerHTML == imgtag2) will return false since the div innerhtml is not imgtag2, but the next time you are going to call changeimg(), "obj" will be undefined because you replaced its innerhtml with an HTML code that doesn't have an id: {obj.innerHTML = imgtag2;}
Check the console to see if there's any javascript error, which it should, at if(obj.innerHTML == imgtag2)
rgds.
Just check whether PLAY is present or not and then change innerHTML according to it
function changeimg()
{
var obj = document.getElementById('image1');
var imgtag1 = '<img src=\'PLAY.png\'>';
var imgtag2 = '<img src=\'PAUSE.png\'>';
if(obj.innerHTML.indexOf('PLAY') != -1)
{obj.innerHTML = imgtag2;}
else
{obj.innerHTML = imgtag1;}
return;
}

Javascript if/else statement using image src as condition

I have a voting script with an arrow system (upvotes and downvotes).If user clicks upvote, the arrow changes to the green arrow, meaning vote registered. If they click again, I want the arrow to revert back to the original image. However, using my code, it changes the image on the first like, but doesn't revert back on a second click.
if (like.src = 'vote_triangle.png') {
like.src = 'vote_triangle_like.png';
} else {
like.src = 'vote_triangle.png';
}
Use a more lenient if statement like:
if (like.src.indexOf('vote_triangle.png')!=-1) {
like.src = 'vote_triangle_like.png';
} else {
like.src = 'vote_triangle.png';
}
I know it's a very old thread, but I would like to add my findings here for future reference.
I found the following code wasn't working:
function swapImage() {
var element = document.getElementById("myImage");
if (element.src == "image1.png") {
element.src = "image2.png";
} else {
element.src = "image1.png"
}
}
Showing alerts containing the element.src taught me it contained the full path to the image in my local machine. Thus, the if statement had been always evaluated to false.
To fix that in a logical manner, what I did was get the attribute of the element, as the following code shows.
function swapImage() {
var element = document.getElementById("myImage");
if (element.getAttribute("src") == "image1.png") {
element.src = "image2.png";
} else {
element.src = "image1.png";
}
}
By using the function getAttribute("attributeName"), I was able to retrieve the path contained in the src relatively to the project directory.
I would suggest, instead of using img soruce as conditional statement, use a global variable, change its state once the upvote is clicked by say +1 and for downvotes -1.
//when 0, show upvote image, make it a global by declaring before any function
var UpVote = 0;
//when upvote clicked, when greater than 0, show down vote img
UpVote = UpVote +1 ;
//conditional logic for img source
if(UpVote > 0){
like.src = 'vote_triangle.png';
}
else{
like.src = 'vote_triangle_like.png';
}

Return address of image or error if it doesn't exist

I know my problem is the fact that I can't check if the image is good until it has time to load. I'm trying to check width and return after it or the src changes (using onerror to set an src.) I'm always getting stuck with a race condition though, and it errors out long before the height and width or src change. When I reload, the image is cached and it works fine. I don't know how to avoid this. Here is my current code (also not working, it loops until Firefox complains.) I'm setting the return of this function to a variable. There are some writes in there I'm using to see how far it gets, and it stops in the while loop. I tried using getTimeout('tstit = chkload("thisisatest",tinypth);',250);, but that didn't work either. I wish I could force this to load in order...
function buildimg(tehname,myc,pth1,pth2,tinypth)
{
var myimg = pth1+tehname+"/"+tehname+"-"+myc+".jpg";
buildtest("thisisatest",myimg,tinypth);
var testimg = document.getElementById("thisisatest");
var tstit = chkload("thisisatest",tinypth);
while(tstit == false) {
document.write(tstit);
tstit = chkload("thisisatest",tinypth);
}
alert(testimg.src+'-'+testimg.width+'-'+testimg.height);
if((testimage.width > 20) && (testimage.height > 20)) {
return myimg;
}
else if(typeof pth2 == "undefined") {
myimg = "error";
return myimg;
}
else {
myimg = buildimg(tehname,myc,pth2);
return myimg;
}
document.write('No return error in buildimg.');
return "error";
}
/*Builds a hidden img tag for testing images*/
function buildtest(itsid,itssrc,tinypath) {
if(document.getElementById(itsid)) {
var imgobj = document.getElementById(itsid);
imgobj.remove();
}
document.write('<img id="'+itsid+'" style="display: none;" src="'+itssrc+'" onerror="swaponerr(\''+itsid+'\',\''+tinypath+'\')" />');
}
/*Swaps the image to a small picture, so we can detect if it worked*/
function swaponerr(tagid, tinypath) {
var theimg = document.getElementById(tagid);
theimg.onerror = '';
theimg.src = tinypath;
}
/*Recurses to return when the image is loaded*/
function chkload(loadid,tinychk) {
var tehobj = document.getElementById(loadid);
document.write(tehobj.width+'x'+tehobj.height+'x'+tehobj.src);
if((tehobj.naturalWidth > 20) && (tehobj.naturalHeight > 20)) {
return true;
}
if(tehobj.src == tinychk) {
return true;
}
return false;
}
I need to test for an image, and return error if it is non-existent. The code below works fine on my server:
/*Checks if the image at /tehname/tehname-c.jpg exists in either of the paths
outputs it's address if it does, and "error" if not.*/
function buildimg(tehname,index,pth1,pth2)
{
var myimg = pth1+tehname+"/"+tehname+"-"+index+".jpg";
$.ajax({
url:myimg,
type:'HEAD',
error: function()
{
myimg=pth2+tehname+"/"+tehname+"-"+index+".jpg";
$.ajax({
url:myimg,
type:'HEAD',
error: function()
{
myimg="error";
return;
},
});
return;
},
});
return myimg;
}
Unfortunately, I'm trying to do this on a messed up system my work uses. We do have jquery, but the system stores user files on a separate server from code, so ajax won't work. This will eventually be in a .js file, I hope.
Now I've got code starting with:
function buildimg(tehname,myc,pth1,pth2)
{
var myimg = pth1+tehname+"/"+tehname+"-"+myc+".jpg";
var tehimage = new Image();
tehimg.src = myimg;
I tried to have the function load the image, and check its width, but I always get 0, since I can't pre-load the images without knowing how many they are (and I don't want to have some outrageously high number of requests with most being errors.) For some reason (at least on Firefox 4, as that's what my goal is to get working first) tehimage.complete always returns false. I've tried using onerror and onload by a global variable, and a few other methods. I must admit though, I'm not very versed in Javascript, so my callbacks may not have worked.
Please help, I'm getting desperate!
Do you hold the 'power to execute php code' on that user files server? If so, check them in php and output to images.js in that server, than in your html, first load images.js, then your usual javascript.
By the way, jQuery had memory leaks in ajax for ears, don't know about 1.6, but 1.5 definately had those. if you wan't to use ajax to get data from server to javascript - use plain javascript: http://www.w3schools.com/ajax/ajax_xmlhttprequest_send.asp
Edit: Definately worth checking out: http://fettig.net/weblog/2005/11/28/how-to-make-xmlhttprequest-connections-to-another-server-in-your-domain/
Since I'm getting no answers, I'm closing the question. What I ended up doing was a modification to make the image change class in the onload, have the image onerror delete it, and have the rest of the code run in the window onload. Unfortunately, this means the 404s aren't caught before it tries to load more images, so I'm forced to limit the max number of images that can be used (changeable in the function call,) and the images that aren't there just waste a little time.
See the final result here.

I need to set display: block on div then find an anchor within that div

I'm nearly finished with this project but I have been beating my head against this problem for a day or so.
Big picture:
Im trying to create a link that will jump between tabs and find an anchor.
Details:
I need to create a link which triggers the function that hides the current div (using display: none)/shows another div (display: block;) and then goto an anchor on the page.
My first intuition was to do:
code:
<a onClick="return toggleTab(6,6);" href="#{anchor_tab_link_name}">{anchor_tab_link_name}</a>
Since the onClick should return true and then execute the anchor. However it loads but never goes to the anchor.
Here is the toggleTab function to give some context:
function toggleTab(num,numelems, anchor, opennum,animate) {
if ($('tabContent'+num).style.display == 'none'){
for (var i=1;i<=numelems;i++){
if ((opennum == null) || (opennum != i)){
var temph = 'tabHeader'+i;
var h = $(temph);
if (!h){
var h = $('tabHeaderActive');
h.id = temph;
}
var tempc = 'tabContent'+i;
var c = $(tempc);
if(c.style.display != 'none'){
if (animate || typeof animate == 'undefined')
Effect.toggle(tempc,'appear',{duration:0.4, queue:{scope:'menus', limit: 3}});
else
toggleDisp(tempc);
}
}
}
var h = $('tabHeader'+num);
if (h)
h.id = 'tabHeaderActive';
h.blur();
var c = $('tabContent'+num);
c.style.marginTop = '2px';
if (animate || typeof animate == 'undefined'){
Effect.toggle('tabContent'+num,'appear',{duration:0.4, queue:{scope:'menus', position:'end', limit: 3}});
}else{
toggleDisp('tabContent'+num);
}
}
}
So I posted this on a coding forum and a person told me that my tab code was done in prototype.
And that I should "Long story short: don't use onclick. Attach the data to the A tag and handle the click event yourself (using preventDefault() or similar) to do your tab-setting stuff, then when it's done, manually set your location to the hash tag."
I do understand what he is suggesting but I don't know how to implement it because I don't know much about javascript syntax.
If you can provide any hints or suggestions it would be amazing.
Update:
I tried to implement the solution below like this:
The link:
<a id="trap">trap</a>
Then adding the following js to the top of the page:
<script type="javascript">
document.getElementById("trap").click(function() { // bind click event to link
tabToggle(6,6);
var anchor = $(this).attr('href');
//setTimeout(infoSupport.gotoAnchor,600, anchor);
jumpToAnchor();
return false;
});
//Simple jump to anchor point
function jumpToAnchor(){
location.href = location.href+"#trap";
}
//Nice little jQuery scroll to id of any element
function scollToId(id){
window.scrollTo(0,$("#"+id).offset().top);
}
</script>
But unfortunately it simply doesn't seem to work for me. When I click the text simply nothing happens.
Anyone notice any apparent mistakes? I'm not used of working with javascript.
I found a lot simpler solution:
$(function(){
jumpToTarget('spot_to_go'); //This is what you put inside your function when the link is clicked.
function jumpToTarget(target){
var target_offset = $("#"+target).offset();
var target_top = target_offset.top;
$('html, body').animate({scrollTop:target_top}, 500);
}
});
Working demo:
http://jsbin.com/ivure/3/edit
So on the click event you do something like this:
//Untested
$('#trap').click(function(){
tabToggle(6,6);
var anchor = $(this).attr('href');
jumpToTarget(anchor);
return false;
});
​
Apparently a small delay was all I needed.
I used this for the link. This is preferred for my situation since I'm batch generating many of these links.
trap
Then I used this vanilla javascript
//Simple jump to anchor point
function jumpToAnchor(target){
setTimeout("window.location.hash=target",450);
}
This loads the link and instantly goes to the location. No jerkiness or anything.

Categories

Resources