ISSUE: IE version 7 and 8 is not showing updated IMG SRC change done in JavaScript
You can see what I mean if you go to the URL below, and on the left under (3) I want a different liner, you choose one of the swatches; lets say you choose "Asahi Chartreuse". Notice nothing happens to the preview on the left. BUT then if you go ahead and choose another swatch, you will see the preview on the left shift to show Asahi Chartreuse. So it is one behind. This is why I believe it is a "refresh" issue. It works in Chrome just fine.
In IE: Notice if you click on some other control, the refresh happens.
You can see the code here: https://www.casemodo.com/test.asp
WHAT I'VE TRIED SO FAR:
I've tried adding headers to say "no-cache".
I've tried adding "?" and random number after the png file name.
I've tried setting focus() to the image after changing the src.
I've tried, after changing src, telling the style.display to be hidden and then visible.
I've tried creating a hidden (and not hidden) text input box on the page and then setting focus() to it after changing img src.
I've tried setting window.focus().
I've tried (as you see now) setting an alert after changing the src.
GUESS: What it looks like now is the JavaScript engine just pauses after I set that src UNTIL you manually click (focus) somewhere else on the screen. So it never even gets to all of those scripts I've tried above.
Set the src attribute to null, then set it to your new url:
in jquery:
var myImg = $('#myImg');
myImg.attr('src', null);
myImg.attr('src', newUrl);
in straight js:
var myImg = document.getElementById('myImg');
myImg.src = null;
myImg.src = newUrl
This worked for me - it was driving me mad!
Try to use onclick instead of onchange. The latter doesnt work well with some form elements in some browsers.
I've seen similar IE issues solved with a seemingly bizarre reassignment of innerHTML. Suppose "container" is a variable referencing the parentNode of the img. Try "container.innerHTML = container.innerHTML". This triggers a re-rendering and may bring the errant img to life.
Comments on the question:
Please include a code snippet in the question.
Was the javascript in an onchange event, or where?
If the client browser is Google Chrome, does it work?
(Sounds like yet-another-IE-image-src-bug.)
The demonstration page you linked to has been changed since this question was posted;
as I write this, clicking on a swatch causes submit which causes load of a different page.
A suggestion:
Use setTimeout, so that the actual change occurs when the timeout event fires, instead of in the original GUI event thread.
For example, if the original javascript was
SomeFunction();
change this to
setTimeout(SomeFunction, 10);
(where image.src = newURL; is done inside SomeFunction)
This question is probably no longer relevant but we ran into the same issue today when we checked backward compatibility for one of our libraries.
The only thing that worked for us was to replace the image element by itself before changing the value for the src attribute:
var myImg = document.getElementById('myImg');
myImg.parentNode.replaceChild(myImg, myImg);
myImg.src = newUrl;
I was working with a Lazy Loading implementation, and got to a similar problem. For some reason, after changing the data-srcset attributes to srcset in code, even with the other approaches described on this page, the elements still didn't seem to get the new attributes values. After some research, I got to this page on github, about a bug fix on a lazy loading plugin. It gave me the idea to, instead of using the replace option described here, or the your_element.src=null approach, to use something like this:
your_element.setAttribute("src", your_element.getAttribute("data-srcset"));
And it ended up working for me.
Related
I've looked around and tried a few things I've seen on here to try to fix this issue but I can't seem to find out why. I have five images in the toppic class. I want to be able to hover over an image in the toppic class and change the big image (id = Biggin) in my screen with the image that is being hovered over, and then change back to the default when the mouse leaves the image. Is there anything blatantly wrong? I copied and pasted from a previous working function and I'm not sure as to what I did wrong this time.
$(".toppic").hover(function() {
var imgsrc = this.src;
$("#Biggin").attr("src", imgsrc);
})
$(".toppic").mouseout(function() {
$("#Biggin").attr("src", ".//Images/IMG_3604.JPG");
})
I had similar issues when starting out using jQuery, and there could be a few reasons why your code isn't working as intended. The most common reason mine wasn't working is that the jQuery script element was getting activated before the DOM existed.
Make sure that the jQuery script element in your html file loads after your DOM loads. You can place the jQuery script element at the end of the HTML file so your jQuery would be loaded after the HTML loads.
I hope that helps.
I am trying to get all images particularly from this website: http://web.archive.org/web/20160110012916/http://habibemaia.com/ . I can get almost all by gathering all "src" tags and downloading from there, but there are problems with the main picture which is changed by javascript either with timing or on a click event. I set up my webclient like this:
webClient.getOptions().setCssEnabled(true);
webClient.getOptions().setJavaScriptEnabled(true);
webClient.waitForBackgroundJavaScript(15000);
webClient.waitForBackgroundJavaScriptStartingBefore(5000);
webClient.setAjaxController(new NicelyResynchronizingAjaxController());
webClient.getOptions().setUseInsecureSSL(true);
After I got the div I try to use click like this:
HtmlPage newPage = div.click();
DomNodeList<DomElement> newImages = newPage.getElementsByTagName("img");
for (DomElement img : newImages) {
if (img.hasAttribute("src")) {
newImagesStrings.add(img.getAttribute("src"));
System.out.println("Image added: "+img.getAttribute("src"));
}
}
If I click on this div int the browser, a new image appears. Unfortunately this code does not trigger the javascript that changes the image. I have tried using
webClient.waitForBackgroundJavaScript(3000);
after click(), as suggested elsewhere, but no luck. The page does not change. Now I am out of ideas completely. Thanks for help.
webClient.waitForBackgroundJavaScript(15000);
webClient.waitForBackgroundJavaScriptStartingBefore(5000);
are both no option settings. The make only sense if you call them after some action - remove this from the setup part of your code.
Regarding the images: I did a quick analysis of the page with firebug. For me it looks like all the images are part of the code and the javascript only toggles the visibility (with some fancy effects).
Maybe something like:
find the div with class 'cameraCont'
iterate over all children with the style 'cameraSlide'
every of this div has an img child that points to a different image
Can't seem to get this one to work...
I have a page that hides certain links. When the DOM is loaded, I'm using jQuery to toggle some of those elements. This is driven by using a data attribute like so:
<div class="d_btn" data-usr='48'>
<div class="hidden_button">
Then, I have the code:
$.each($(".d_btn"), function() {
var btn = $(this).data('usr');
if ( btn == '48' ){
$(this).children('.hidden_button').toggle();
}
The above all works as planned. The problem is that I am trying to remove the data-usr from the class .d_btn once the if statement is evaluated. I've tried the following and nothing works (i.e., after the page is loaded, the source still shows the data-usr attribute:
$(this).removeAttr("data-usr");
$(this).removeData("usr");
I've been working on this for a couple of hours now and...nothing! Help is greatly appreciated!
UPDATE
I've tried the great suggestions of setting the data attribute to an empty string but I'm still not getting the desired result.
To explain a little further, The reason I'm trying to remove the attribute is so when an ajax response adds another item to the page, the previously added items would already have the button either shown or hidden. Upon AJAX response, I'm calling the same function once the DOM is loaded.
Currently, when something is added via AJAX, it toggles all the buttons (showing the ones that were hidden and vice versa.) Ugh...
I'm also fully willing to try alternatives to my approach. Thanks!
UPDATE
Well, the light bulb just flashed and I am able to do what I want to do by just using .show() instead of .toggle()
Anyway, I'd still like to find an answer to this question because the page will be potentially checking hundreds of items whenever something is added - this seems horribly inefficient (even for a computer, hahaha.)
Why don't you set the value to a random value or empty variable instead if removeAttr does not work..
$(this).attr("data-usr" , '');
$(this).prop("data-usr" , '');
Changing the DOM doesn't affect the source. It affects the DOM, which you can view with the Inspector/Developer Tools. Right click => View Source will give you the original source of the page, not the actual current source as modified by JavaScript.
Set it to a blank string:
$(this).attr("data-usr", "");
I second what Kolink said: check the DOM, not the source. (Chrome: Ctrl + Shift + i).
As others have stated. Checking the source will only show the original unedited source for the webpage. What you need to do is check the DOM using developer tools.
I've just checked everything in Chrome's inspector on jsfiddle here and the attribute is definitely being removed as well as the data.
My markup is a simple div element with id 'load'. Using jQuery I then load a list of image elements into this div:
$('#load').load('images.html', { }, function() {
$(this).onImagesLoad({
selectorCallback: function() {
....do something....
}
});
});
where images.html is a list like this:
<img src='1.jpg' caption='img 1'>
<img src='2.jpg' caption='img 2'>
...
To ensure that all images are loaded completely, I use the onImagesLoad plugin. This, so far, works just fine on all browsers.
However, on IE8 (and I assume other versions of IE also) when I then iterate over the img elements, I am unable to determine the width/height of the images loaded. The image.context.naturalWidth and naturalHeight attributes don't seem to work.
How do I get a hold of the images' dimension?
Thanks heaps :)
Update
#Simon: That didn't work on IE, and broke the other browsers as well.
#Jenechka: If "imageDomElement" is just another name for the "image" variable in my example above, then it doesn't work. Or what do you mean by that DomElement?
If you haven't resized the image, you could use:
image.width()
and
image.height()
It's been a while but I finally found some time to tinker with this again. The above problems are still there, but here is what I think is going on.
When I load the initial images then yes, the file is loaded and image objects are generated. But it seems that the attributes are not correct yet, and they won't be until the image is actually added to the DOM of the site and rendered. A div/image on hide() on IE has no dimension information whatsoever, on Safari there is some information available. For example, without adding the following div anywhere
var test = $("<div><img src='test.jpg'></div>")
the image contained there has the following information:
width() = 0,
attr("width") = 600,
css("width") = "", and
img[0].clientWidth = 0.
That's on Safari; on IE it's the same except attr("width") = 0 and css("width") = "auto". Now I can't use this, and that's what broke my script and why I posted my initial question. However, the moment I append this div and have it rendered, all the correct values show up in the image object.
I'm writing a little gallery thinghie, which shows whatever images I have in that second .html file that I load; that gallery, however, computes and places the thumbnails, and prepares the images it shows in full resolution. To make this look ok, I basically wanted to create the entire thing hidden, and then fade it in. Alas, it seems that this whole idea won't pan out. A friend suggested to load everything into a tiny iframe off to the left where it's not visible, and work with that. Perhaps that's the way to go.
Another thing I noticed, and that seems to be very closely related to the aforementioned load issue is clone(). It seems that if an image is rendered, a
var newimg = img.clone()
generates the same "empty" image object that I have to deal above. Even when the original image is visible and contains all the right attributes, its clone does not.
Right now I don't see any other way than to rethink and rewrite parts of my gallery.
This is quite similar to the other answers, but I have tested it in IE7, so it might be closer to what you want:
$(document).onImagesLoad({
selectorCallback: function() {
$('img').each(function(){
alert($(this).width()+', '+$(this).height());
});
}
});
See here, this may not be exactly how you were using it, but I'm not familiar with this onImagesLoad thing.
imageDomElement.width
imageDomElement.height
or try
imageDomElement.clientWidth
imageDomElement.clientHeight
If you play with jquery, then image.attr(width) should do the trick
But why not using the document.ready instead, could give you less headeache. .
Use the following code instead
$(document).onImagesLoad({
selectorCallback: function() {
$('img').each(function(){
alert($(this)[0].clientWidth +', '+$(this)[0].clientHeight);
});
}
});
What about?
$("#load img").each(function() {
var img = new Image();
img.src = this.src;
alert(img.height + " x " + img.width);
});
So, I have this pretty complex ajax thing going.
It loads new html (including div tags and all) to show up on the page.
I included a 'more' link to load additional data.
This more link links to my javascript function. The 'more' link is located in a div, which I gave a unique id. The next time the load function is called, I use document.getElementById(the id).style.display="none"; to "remove" this div from the look of the page.
I set error traps for this, the div with that id is found without problems, but javascript fails to change my style property.
I tested alert(document.getElementById(the id).innerHTML); and that worked without problems - hence the title of the question.
So, does anyone have any ideas/do I need to offer more information? The main problem is that it doesn't throw any errors anywhere, yet it fails to complete the task I asked...
Here's a bit of code to go with it -
try
{
var myidthing = "morelink" + ContentStart.toString(); //the id is correct
var div = document.getElementById(myidthing);
if (!div)
{
}
else
{
div.style.display="none"; //this doesn't work, but doesn't raise an error
alert(div.innerHTML); //this works without problem
}
}
catch(theerr)
{
alert(theerr);
}
------------------------->EDIT<-------------------------
I'm incredibly sorry if I upset any people.
I'm also angry at myself, for it was a stupid thing in my code. Basically, I had a variable that stored the contents of a parent div. Then I (succesfully) removed the div using the removeChild() method. Then my code pasted the contents of that vaiable (including the div I wanted gone) back into the parent div.
I switched around the order and it works fine now.
Again, excuse me for this.
Throwing out a few ideas of things to look for:
You said the div is generated by javascript. Is it possible the div you are targeting is not the one you think you are? It could be you are targeting another div, which is already hidden, or obstructed... or maybe the innerHTML you are displaying goes with a different element than the one you intend to target. Put an alert or script breakpoint in the if(!div) case, also, and see if it's going down that path.
If the above code is only a stripped-down version of your actual code, check your actual code for typos (for example: style.display = "none;";)
Using the FireBug plugin for FireFox, inspect the target element after the operation completes, and make sure that the display: none appears in the style information. If not, use FireBug's debugger to walk through your javascript, and see if you can figure out why.
Use FireBug to break on all script errors, in case there is another error causing this behavior.
Try empty quotes instead of 'none' and see if that works?:
document.getElementById('element_id').style.display="";
Failing that, don't change the style, just add a class which hides the element.