changing img while clicking button - javascript

I have a jsp page that has buttons, and when i click the button a modal will open, and whatever happens inside that modal is linked with a js file (no more jsp). So here is my table inside modal (js file) :
html = '<table style="width:400px;height:250px;">'
+ '<tr><td title="grp"><img id="groupBtn" src="group.png"></td>'
+'<td title="1st"><img id="1stBtn" src="1st.png""></td>'
as you can see, it's html code in js file and not normal code from jsp. (I don't know the exact term.)
Therefor I can't write the <style></style> tag for that table made in js file.
What I want to do:
change the image while I'm clicking the button; not mouse enter, not image change, but a:active.
My problem:
it's in img tag and not a tag
so i tried
+ '<tr><td title="그룹"><a id="test1><img id="groupBtn" src="group.png"></a></td>'
this but the problem is i don't know where to put
#test1:active{
background-image : url('clicked.png');
}
while googling i found out this won't work because this is not how you change the src in img tag.
html = '<table style="width:400px;height:250px;">'
+ '<tr><td title="grp"><img id="groupBtn" src="group.png"></td>'
+'<td title="1st"><img id="1stBtn" src="1st.png""></td>'
^ How should I reform this <img id=> to something that could work with a:active tag? Or, should i never even use a tag and just change the whole tag into something else? plus, if i want to give style to elements that were created in js file by html, where should i add the style tag?
To save your precious time helping me, i want to summarize a bit,
I want the image on my button to change only when my mouse is clicked (pressed more precisely) and then my mouse is no more pressed, i want my button image to return to original image. Thats why I said i want something that works like a:active tag cause it only changes your css when the mouse is pressed and changes back when mouse isnt pressed anymore !

If you just want to change on click,you could add a onClick handler in a script tag instead of changing it via css.
<a id="test1" onclick="changeImgSrc()"><img id="groupBtn" src="group.png"></a>
Somewhere in your js file,have this function.
function changeImgSrc(){
var groupImg = document.getElementById('groupBtn');
groupImg.src = "clicked.png"; // path of the img
return false // required to prevent default browser behaviour.
}

This might help you.
function imgToNew(){
var image= document.getElementById('groupBtn');
image.src = "newImage.png";
}
function imgToOrig(){
var image= document.getElementById('groupBtn');
image.src = "group.png";
}
<a id="test1" onmousedown="imgToNew()" onmouseup="imgToOrig()"><img id="groupBtn" src="group.png"></a>

Another option using css classes.
.image{
height:400px;
width:600px;
background: url('https://picsum.photos/200/300') no-repeat;
}
.image:hover{
background: url('https://picsum.photos/250/450?grayscale') no-repeat;
}
<div class="image"></div>

Related

Print function only works after second click

I have this function to print a DIV.
Whenever the page is loaded and I click in a "Print" link I have, the DIV is shown to be printed without CSS.
If I close Chrome's print visualization page and click in the "Print" link again, the DIV has CSS applied.
Any ideas why?
Javascript
function printDiv(divId) {
var printDivCSSpre =
'<link href="/static/assets/vendor/sb-admin-2-1.0.7/bower_components/bootstrap/dist/css/bootstrap.min.css" rel="stylesheet">' +
'<link href="/static/assets/vendor/sb-admin-2-1.0.7/dist/css/sb-admin-2.css" rel="stylesheet">' +
'<div style="width:1000px; padding-right:20px;">';
var printDivCSSpost = '</div>';
$('body').append('<iframe id="print_frame" name="print_frame" width="0" height="0" frameborder="0" src="about:blank"></iframe>');
$("link").clone().appendTo($("#print_frame").contents().find("head"));
window.frames["print_frame"].document.body.innerHTML =
printDivCSSpre + document.getElementById(divId).innerHTML + printDivCSSpost;
window.frames["print_frame"].window.focus();
var windowInstance = window.frames["print_frame"].window;
windowInstance.print();
}
HTML
<a id="print" href="#">
<i class="fa fa-print"></i> Print
</a>
<script>
$('#print').click(function () {
printDiv('report')
})
</script>
<div id="report" class="report">
<p># Generated Table#</p>
</div>
First click:
http://imgur.com/a/Go81Y
Closing the print preview page and clicking again in print
http://imgur.com/a/SCxJF
This happens because when you call your printDiv() function, css is also written using inner HTML and in this scenario CSS is not applied during first click because you wrote CSS to the elements even when they do not exist inside DIV.
The function to work as desired has to write DIV contents first and then CSS should be applied. I would say write css after contents of DIV or load on top of your HTML page and just write DIV contents.
Hope that helps.
Every thing is right just change the sequence. In browser debugger on first click it didn't show 'print_frame' in sources section while in second click it does (I am using chrome devtool).
So load in memory frame with css attributes during onload:
var windowInstance;
$(function(){
$('body').append('<iframe id="print_frame" name="print_frame" width="0" height="0" frameborder="0" src="about:blank"></iframe>');
$("link").clone().appendTo($("#print_frame").contents().find("head"));
windowInstance = window.frames["print_frame"].window;
});
and onClick just append html
$('#print').click(function () {
var divId = 'report';
var printDivCSSpre ='<div id="printReportDiv" style="width:1000px; padding-right:20px;">';
var printDivCSSpost = '</div>';
window.frames["print_frame"].document.body.innerHTML = printDivCSSpre + document.getElementById(divId).innerHTML + printDivCSSpost;
window.frames["print_frame"].window.focus();
windowInstance.print();
});
updated jsfiddle
Try this one. The problem mainly arises because the css has not been applied to the page when the print command is initiated. setTimeout is one way to solve it as others have mentioned but it is really not possible to predict how much delay you will need. Slow internet connections will require high delays before you fire the print statement. The following code, however, only fires the print event after the css has been properly applied to the iframe.
$('#print').click(function () {
if($("#print_frame").length == 0) {
$('#report').after('<iframe id="print_frame" name="print_frame" width="0" height="0" frameborder="0" src="about:blank"></iframe>');
}
var $head = $("#print_frame").contents().find("head");
// for now for ease I will just empty head
// ideally you would want to check if this is not empty
// append css only if empty
$head.empty();
$.ajax({
url : "https://dl.dropboxusercontent.com/u/7760475/reports.css",
dataType: "text",
success : function (reports) {
// grab css and apply its content to the iframe document
$head.append('<style>'+reports+'</style>');
$.ajax({
url : "https://dl.dropboxusercontent.com/u/7760475/bootstrap.css",
dataType: "text",
success : function (bootstrap) {
// grab another css and apply its content to the iframe document
// there may be better ways to load both css files at once but this works fine too
$head.append('<style>'+bootstrap+'</style>');
// css has been applied
// clone your div and print
var $body = $("#print_frame").contents().find('body');
// empty for ease
// but later append content only if empty
$body.empty();
$("#report").clone().appendTo($body);
$('#print_frame').get(0).contentWindow.print();
}
});
}
});
});
Use inline CSS instead.
Reason: When we PRINT or save as PDF if fails to fetch external css Files, So we have to use Inline css.
edited your file please see: jsfiddle.net/ytzcwykz/18/
As other people mentioned it is hard to see your problem without seeing the working example of a problem, but just guessing from the code:
Browser is not able to load the CSS before your print() call.
Browser is not able to render the CSS before your print() call.
Keeping that in mind changing your JS function that way might do the trick
function printDiv(divId) {
$("link").clone().appendTo($("#print_frame").contents().find("head"));
window.frames["print_frame"].document.body.innerHTML =
printDivCSSpre + document.getElementById(divId).innerHTML + printDivCSSpost;
window.frames["print_frame"].window.focus();
var windowInstance = window.frames["print_frame"].window;
setTimeout(function() {
windowInstance.print();
}, 0);
}
The idea behind this function is to let browser execute it's code after we added changed the HTML/CSS code in the window - see Why is setTimeout(fn, 0) sometimes useful?
WARNING: this approach is not tested for your particular problem, and it might also not work because we escape/leave the mouse-click call-stack, calling print() method might be not possible out of user-interaction stack.
UPDATE: after looking in the posted jsfiddle - my assumption was correct, the browser needs some time to load and render the CSS, that is why calling the print() right after changing iframe contents doesn't give the desired result. There are 3.5 ways to solve that:
Use events to identify when iframe's document and window has finished loading and rendering. I tried two approaches, and failed so far, need to read docs more carefully about when document and window are behiving during the loading sequence:
we can do that from outside of iframe, i.e. listen to events of iframe element and it's children
we can do that from inside of iframe, i.e. add little javascript snippet inside which will send a message to the parent window when loading is done.
Consider forming the print result different, how about print style-sheets? I.e. add one more style sheet with print-media query to the parent doc and just call print on it?
Consider forming an iframe which is already loaded and ready to be printed, but replace just the table contents inside it.
As others mentioned, The problem here is that the CSS files used are external resources and browser takes time to download and cache it locally. Once it is cached, it would serve faster and that's why it works fine from the second click.
As Anton mentioned, setTimeout is the key here! You may probably increase the timeout seconds to make that work. I tried setting it to 500ms and that worked,
setTimeout(function(){windowInstance.print();},500);

Why is my div not updating when changing its class with JavaScript?

I currently have a div that's used to display and image via CSS.
For example:
HTML
<div id="myDiv" class="play"></div>
CSS
.play{background: url('../img/playIcon_black.png') no-repeat;}
This image appears as it should.
What I'm attempted to do is to change the image by changing the class (via JavaScript).
Example:
CSS
.pause{background: url('../img/pauseIcon_black.png') no-repeat;}
JavaScript
function myFunction() {
myDiv.className = "pause";
}
When I call myFunction() everything seems to work correctly with one exception. Occasionally the image does not update in the browser.
A few things to note:
I'm certain the function is being called correctly. If I put a console.log() statement within the function, it prints when it should. Additionally, if I inspect the element within the browser, the class is in fact changed to .pause
The image changes from the "play icon" to blank once the function is called, BUT upon hovering over the div the images then appears permanently.
This only seems to happen once the page is initially loaded. Meaning, I can only recreate the issue once upon refresh, then everything works correctly after that.
I have attempted to clear my cache but nothing seems to have changed.
(I'm not sure how relevant this is) I'm calling myFunction() via onended attribute of an audio tag.
For example:
<audio onended="myFunction()"></audio>
But I'm not certain if this would affect anything because the function appears to be called correctly.
Any ideas of why this might be happening?
So the issue is that when you change the class, the browser has to fetch the new image, which takes time. One way to fix the issue is by using sprites, where both images are actually in one image and you only show a piece of that image at a time.
Another solution is to preload the image and then apply the preloaded image source to your new element like this:
var image = newImage();
image.src = '../img/pauseIcon_black.png';
function myFunction() {
var cssBackground = 'url(' + image.src + ') no-repeat';
myDiv.style.background = cssBackground;
// Optionally with jQuery instead:
// $('#myElementID').css('background', cssBackground);
}
Note that if you call myFunction before the image loads you'll encounter the same error. The difference is that this will load the image when the page is loaded (or more properly, when this JS executes and myFunction is assigned) rather than when myFunction is called. To ensure the image is loaded you can use the onLoad event handler for the image object. For more details on preloading images check out this answer: preload image then change background javascript
You need to get the element id
function myfunction(){
var myDivElem = document.getElementById('myDiv');
myDivElem.className = 'pause';
}
You can use document.getElementById("myDiv").className="";in your function
OK if you don't want use first solution you can use second one:
You can add a class to element using
document.getElementById("myDiv").className +=" n";
Then add a class named .play.n to your css file after class named.play
Then add your image address.
If you want to manipulate the div with id "myDiv". Use it as
document.getElementById('myDiv').class
Sample codesnippet: example snippet

Create an img element into <a> tag using javascript

I want to embed an image inside an tag after the image on tag loaded.
So the sequence goes like this...
<a id="anchorID">
<img onload="MyFunc(anchorID)>IMAGE1</img>
//..After image 1 loaded add
<img>IMAGE2</img>
</a>
<script>
function MyFunc(anchorID)
{
var anchorElement = document.getElementById(anchorID);
//I want to create an image tag inside the anchorElement
}
</script>
Thanks for the help.. T_T
Here's a solution, just add onload="addNextImage('#id_in_which_to_add_new_image', 'second_image_url')" to the image you want to load first. In the next example, ignore the width and style (I put them there to be able to test the functionality, making the image smaller so I don't need to scroll to see the behavior - I chose a huge image to make sure everything works as it should, and the border makes it appear sort of like a progress bar =)
<script>
function addNextImage(selector, url) {
var where = document.querySelector(selector);
if (where) {
var newImage = document.createElement('img');
newImage.src = url;
where.appendChild(newImage);
}
}
</script>
<a id="anchorID">
<img onload="addNextImage('#anchorID', 'http://animalia-life.com/data_images/wallpaper/tiger-wallpaper/tiger-wallpaper-01.jpg')" src="http://hubblesource.stsci.edu/events/iyafinale/support/documents/gal_cen-composite-9725x4862.png" width="400px" style="border: 1px solid black" />
</a>
This should work on most browsers today: IE8+ (as long as you use basic CSS2.1 selectors as the first argument), and pretty much everything else in use. (IE8+ because it depends on querySelector)
I think what you are looking for is
Javascript appendChild()
var node = document.createElement("img");//Create a <img> node
node.src="SomeImageURL";
firstImage.appendChild(node);
JQuery append()
$("#firstImageID").append("<img src="SomeImageURL"/>");
see links for more info
Javascript
jQuery
You can use the following to add an image to the anchor tag
function MyFunc(anchorID) {
var anchorElement = document.getElementById(anchorID);
if (anchorElement) {
//I want to create an image tag inside the anchorElement
var img = document.createElement("img");
img.setAttribute("src", "yourImagePath");
anchorElement.appendChild(img);
}
}
Hope that helps.

Javascript DOM changes have no effect

Using an image map, I am trying to build a graphic that when you click on a "wing" it makes it look like a button and depresses it.
Image map is built, onclick is working, but nothing happens?
This is the code:
<!DOCTYPE html>
<html>
<head></head>
<body>
<map name="location-map" style="cursor:pointer;">
<area id="spot_1" onClick="set_spot(this.id)" shape="poly" coords="66,78,122,38,194,15,186,106,174,112,160,118" />
</map>
<img src="PH.png" usemap="#location-map" id="spot_1" style="position:absolute;top:0px;left:0px;width:402px;height:302px;" />
<script type="text/javascript">
function set_spot(mouse_over_name) {
document.getElementById(mouse_over_name).style.display="none";
};
</script>
</body>
</html>
It is supposed to hide the image?
I have seen other solutions saying that the position of the JavaScript needs to be after the element. I have tried the script in every location and the out come is always the same. No change. I've also tried changing the width to 0 px and changing the image src to ""! I also had the images inside DIV's and tried hiding the DIV but again, nothing?
If I put an an alert:
alert(document.getElementById(mouse_over_name).style.display) before the change, I get a blank alert box, after I get "none."
What am I missing?
You can see the above code live here:
http://www.beaconfasteners.net/beacon_advantage/graph/test.html
Edit:
I have tried this in all major browsers.
Robby Cornelissen was correct. The reason that your img is not hiding is because the onclick uses the id of the area element and you're setting display: none on that, not the img element. I'm not sure if there is a way to hide the contents of an area element, but you could potentially use this to find and hide the image element that shares the same id as the area that is clicked:
function set_spot(mouse_over_name) {
[].forEach.call(document.querySelectorAll('img'), function(el) {
if (el.id === mouse_over_name) {
el.style.display = 'none';
};
});
};
This will iterate through all of the images on the page, so I can't make any guarantees about the speed of such a solution. You can preview it here:
jsfiddle

Using JavaScript to dynamically change display style in img tags

I show links to 240 images on a page. The real images are uploaded by users. I tried to avoid showing an empty image if users did not upload it yet. jQuery did not work for me because of conflicts, so I have to do it in pure JavaScript.
image(s) links:
<img class="photo240" src="http://www.example.com/i/%%GLOBAL__AuthorID%%/p/b01.jpg" onerror="imgError()">
My JavaScript:
function imgError()
{
alert('The image could not be loaded.');
var _aryElm=document.getElementsByTagName('img'); //return an array with every <img> of the page
for( x in _aryElm) {
_elm=_aryElm[x];
_elm.className="photo240off";
}
}
The style photo240off equals to display:none.
Right now, whenever an image misses, all the images are turned to style photo240off and I want only the missing image to be hidden. So there is something wrong with my script.
(the overall script works well, because I get the alert).
Use this to get the image with the error.
Change to:
onerror="imgError(this)"
Then the function can be:
function imgError(el) {
alert('The image could not be loaded.');
el.className = "photo240off";
}
You need to reference the image from your onerror call and change the class only for that one.
Something like this:
HTML
<img class="photo240" src="example.jpg" onerror="imgError(this)">
JS
function imgError(el) {
el.className="photo240off";
}

Categories

Resources