How can i change the innerHTML content when clicking on an image? - html

I'm quite new in coding, trying to educate myself because i'm interested. So, sorry if it's going to be a bit dumb question or not so specific or not really correct...
On my "practicing site" i'm having some navigation links, which are referring to different innerHTML contents (like different pages). I used the 'onClick' event to make them show up, for example like this:
<div class="nav" onClick="changeNavigation('a')">menu</div>
It works with texts perfectly, but my problem is that i don't know how to make the same with an image. So when i click on the image, i want to be redirected to that innerHTML page, like i did it with the text based button. I tried to do it like these two ways, but none of them worked.
<img src="picture.png" onClick="changeNavigation('a')" />
<div onClick="changeNavigation('a')"><img src="picture.png"></div>
Is it possible to make this with an image and the 'onClick' event? Or how else can i make this work?
By the way this is my script to make innerHTML show up:
<script>
function changeNavigation(id) {
document.getElementById('main').innerHTML = document.getElementById(id).innerHTML
}
</script>
I also tried to add my image an id that says 'main' like in the script this way, but with no result.
<img id="main" onClick="changeNavigation('f')" src="picture.png" />
Can you help me please? I would appreciate any answer, because i already searched about this and i didn't find anything that could've helped solve my problem and i'm really stuck right now.
(Sorry if my english isn't the best, it's not my native language.)

I have updated my answer to what you want. You need to the divs id you want to display as a parameter to the function you use for onclick. A sample is below.
var divs = ["Menu1", "Menu2", "Menu3", "Menu4"];
var visibleDivId = null;
function toggleVisibility(divId) {
if(visibleDivId === divId) {
visibleDivId = null;
} else {
visibleDivId = divId;
}
hideNonVisibleDivs();
}
function hideNonVisibleDivs() {
var i, divId, div;
for(i = 0; i < divs.length; i++) {
divId = divs[i];
div = document.getElementById(divId);
if(visibleDivId === divId) {
div.style.display = "block";
} else {
div.style.display = "none";
}
}
}
.main_div{text-align:center; background: #00C492; padding:20px; width: 400px;}
.inner_div{background: #fff; margin-top:20px; height: 100px;}
.buttons a{font-size: 16px;}
.buttons a:hover{cursor:pointer; font-size: 16px;}
img {cursor:pointer}
<div class="main_div">
<div class="buttons">
<img src="http://www.clker.com/cliparts/J/g/2/D/p/I/one-hi.png" width="50px" onclick="toggleVisibility('Menu1');"> <img src="http://www.clker.com/cliparts/E/x/J/x/m/z/blue-number-two-hi.png" width="50px" onclick="toggleVisibility('Menu2');">
<img src="http://www.clker.com/cliparts/L/H/T/b/g/N/three-md.png" width="50px" onclick="toggleVisibility('Menu3');">
<img src="http://www.clker.com/cliparts/v/G/G/A/D/s/four-md.png" width="50px" onclick="toggleVisibility('Menu4');">
</div>
<div class="inner_div">
<div id="Menu1">I'm container one</div>
<div id="Menu2" style="display: none;">I'm container two</div>
<div id="Menu3" style="display: none;">I'm container three</div>
<div id="Menu4" style="display: none;">I'm container four</div>
</div>
</div>

You can just keep all of the sections as children of #main, and selectively show them when the section button in clicked. E.g.,
HTML
<nav>
<button type="button" data-index=0>Show one</button>
<button type="button" data-index=1>Show two</button>
<button type="button" data-index=2>Show three</button>
</nav>
<main id="main">
<section>One</section>
<section class="hidden">Two</section>
<section class="hidden">Three</section>
</main>
CSS
.hidden {
display: none;
}
JavaScript
const buttons = Array.from(document.querySelectorAll('button'));
const contentBlocks = Array.from(document.querySelectorAll('section'));
function hideSections (arr) {
arr.forEach(a => {
a.classList.add('hidden');
});
}
function showSection (index, sections) {
// Just a basic check, not exhaustive by any stretch
if (index !== undefined && sections !== undefined) {
hideSections(sections);
sections[index].classList.remove('hidden');
}
}
buttons.forEach(button => {
button.addEventListener('click', () => {
const contentBlocks = Array.from(document.querySelectorAll('section'));
const index = button.getAttribute('data-index');
showSection(index, contentBlocks);
});
});
Obviously you'll have to adjust your selectors for your use case, but Here's a pen

Here's a GitHub Gist pointing to some examples I created on JSFiddle based off of your specific use case (Stack Overflow doesn't let me post links to JSFiddle directly without including code here, but it's easier to follow along/experiment entirely in JSFiddle):
https://gist.github.com/andresn/f100386f06ee28e35bd83c62d9219890
More advanced stuff:
Ideally, you'd use what's called event delegation instead of adding an onclick to every anchor (DRY = Don't Repeat Yourself is good to always keep in mind while programming and so is KISS = Keep It Simple Silly). Here is a resource explaining event delegation:
https://davidwalsh.name/event-delegate
You can even take this further by preloading all your images so they load behind the scenes when the user first loads the page:
https://perishablepress.com/3-ways-preload-images-css-javascript-ajax/

Related

How to show div only after all the image inputs loaded?

I want the div "container" shows only after all image buttons in the div "inner" fully loaded. Or outer_1 and inner_1 show together after 1.jpg is loaded.
<div class="container" id="top">
<div class="outer" id="outer_1"><div class="inner" id="inner_1"><input type="image" src="1.jpg"></div></div>
<div class="outer" id="outer_2"><div class="inner" id="inner_2"><input type="image" src="2.jpg"></div></div>
<div class="outer" id="outer_3"><div class="inner" id="inner_3"><input type="image" src="3.jpg"></div></div>
</div>
I have tried the below solution I found here but couldn't help. I am totally new in programming, may I know how can I do this?
var $images = $('.inner input');
var loaded_images_count = 0;
$images.load(function(){
loaded_images_count++;
if (loaded_images_count == $images.length) {
$('.container').show();
}
});
Your code is almost correct. The issue you have is that you're using the load() method, which is used to retrieve content from the server using AJAX, not the load event, which fires on img elements when they are ready to be displayed.
To fix this use on() instead of load():
var $images = $('.inner input');
var loaded_images_count = 0;
$images.on('load', function() {
loaded_images_count++;
if (loaded_images_count == $images.length) {
$('.container').show();
}
});
Normally, loaded doesn't mean rendered.
If you develop application on framework such as Angular, It will provided rendered event for you.
In case you develop application by only pure javaScript or even with jQuery,
Use setTimeOut might be help you (just in some case).
$images.load(function(){
loaded_images_count++;
if (loaded_images_count == $images.length) {
setTimeout(function(){
$('.container').show();
}, 0);
}
});

HTML and CSS only show/hide?

I am making a Story Map (ArcGIS/Esri product that allows you to make various types of georeferenced presentations) that allows you to use embedded HTML and CSS (within <style> tags). The problem I am running into is that I want to have a show/hide for additional information on different topics, but I have been unable to successfully implement this functionality.
I tried the collapse Bootstrap method, which works initially but after a few hours it no longer works (with the button method the button stops working, with the href method it just opens the Story Map again in a new page). Here is the code for that:
<p>
<button aria-controls="collapseFlowers" aria-expanded="false"
class="btn btn-primary" data-target="#collapseFlowers"
data-toggle="collapse"
type="button">
More information on Wildflower
</button>
</p>
<div class="collapse">
<div class="card card-body">
<img alt="" src="https://i.imgur.com/Bidb7cR.png" />
</div>
</div>
From what I've gathered, this issue is because the Story Map lacks the Bootstrap dependencies, but I have no idea why it would work initially if that were the case.
I've also tried all of the solutions here, none of which have worked. When I save and exit the HTML editor, it seems to "compile" the code, removing parts of it that are required for it to function. This is probably an inadequate explanation but I can include examples if needed.
Story Maps do support JavaScript and other, deeper HTML work, but you have to download the source and rehost it, which is not an option for this project. I am experienced in Java, C, and some other languages but know very little about HTML and how it is implemented, so this is driving me crazy. Any help is appreciated!
Listen for click events on button,
Using only JavaScript,
const btn = document.querySelector('.btn');
const collapse = document.querySelector('.collapse');
// initially hide the image
collapse.style.display = "none";
var hidden = true;
// click event listener
btn.addEventListener('click', handleClick);
// click event handler
function handleClick (e) {
if (hidden) {
hidden = false;
collapse.style.display = "block";
}
else {
hidden = true;
collapse.style.display = "none";
}
}
<p><button aria-controls="collapseFlowers" aria-expanded="false" class="btn btn-primary" data-target="#collapseFlowers" data-toggle="collapse" type="button">More information on Wildflowers</button></p>
<div class="collapse">
<div class="card card-body"><img alt="" src="https://i.imgur.com/Bidb7cR.png" /></div>
</div>
Using only CSS,
label {
cursor: pointer;
}
div.collapse {
display: none;
}
#btn-checkbox {
width: 0;
height: 0;
opacity: 0;
}
#btn-checkbox:checked + div.collapse {
display: block;
}
<button><label for="btn-checkbox">More information on Wildflower</label></button>
<input id="btn-checkbox" type="checkbox"/>
<div class="collapse">
<div class="card card-body"><img alt="" src="https://i.imgur.com/Bidb7cR.png" /></div>
</div>
I've done some changes to the above code, so that it can work comfortably.
Link relevant to this post,CSS-tricks

Show a loader while waiting for the iframe to load according to the link clicked, and hide the loader after iframe has loaded using AngularJS

I'm trying to show a loader while waiting for the iframe to load according to the link clicked. I use Semantic UI's loader. So far, what it can do is show the loader once the link is clicked. However, the loader will not disappear anymore, even after the iframe document has loaded.
Here is the HTML code:
<div class="drive-link">
<div ng-if = "!READY.value"> <!-- to check if the link has been clicked -->
<div class="ui active centered inline loader"></div>
</div>
<iframe name="embedded-iframe" allowfullscreen="" frameborder="0" iframe-onload></iframe>
</div>
<div class="active content">
<a target="embedded-iframe" href="{{file.link}}" ng-click="show_file_name(file)"> {{file.name}} </a>
<div ng-repeat="next_file in files | limitTo:files.length:$parent.$index">
<a target="embedded-iframe" ng-if="$index > 0 && next_file.category_id == file.category_id" href="{{next_file.link}}" ng-click="show_file_name(next_file)">{{next_file.name}}</a>
</div>
</div>
AngularJS code:
app.controller('mainController', function($scope) {
$scope.READY = {value:true};
$scope.show_file_name = function(file){
$scope.fileName = file.name;
$scope.fileDesc=file.description;
$scope.READY = {value:false};
}
});
app.directive("iframeOnload", function() {
return function(scope) {
scope.READY.value = true;
console.log(scope.READY.value)
};
});
I have a directive to iframe, called iframe-onload. I was thinking that if the anchor tag was clicked, it would somehow connected to the iframe (since clicking the anchor tag would show the embedded document anyway), and it would trigger iframe-onload, which would change READY's value. However, this was not the case, and iframe-onload would only be triggered once, when the HTML page loaded.
Note:
I'm trying to to stay away from timeouts because I don't think hard coding how long the loader will show is the best way to go.
Any help will be very much appreciated. Thank you!
Use simple approach which is that use ng show with your loader code. for example if you have loader in gif image like this
Link To be click
<img src="loader.gif" ng-show="loader"/>
and then in controller you can do like this
$scope.loader=false;
$scope.activateLoader=function(){
$scope.loader=true;
}
this is html table where my data loads.
<tr ng-if="!isDataLoading" ng-repeat="x in companies">
<td>{{x.Id}}</td>
<td>{{x.CompanyName}}</td>
<td>{{x.ContactPerson}}</td>
<td>{{x.TotalRerrals}}</td>
<td>{{TotalRegistered}}</td>
<td>{{x.TotalConverted}}</td>
<td>{{x.TotalSalesAgents}}</td>
<td class="text-green"><i class="fa fa-circle"></i> {{x.AccountStatus}}</td>
</tr>
<div ng-if="isDataLoading" style="width: 100px; margin: auto;">
<img src="assets/loader.gif" style="width: 100px; height: 100px;">
</div>
and here is my controller code
User.getCompanies().success(function(res) {
console.log('All companies', res);
if (res != null || res != "") {
$scope.customers = res;
$scope.companies = [];
for (var i = 0; i < res.length; i++) {
$scope.companies.push({
Id: res[i].Id,
AccountStatus: res[i].AccountStatus,
CompanyName: res[i].CompanyName,
ContactPerson: res[i].ContactPerson,
TotalConverted: res[i].TotalConverted,
TotalRegistered: res[i].TotalRegistered,
TotalRerrals: res[i].TotalRerrals,
TotalSalesAgents: res[i].TotalSalesAgents,
})
}
}
$scope.isDataLoading = false;
})
.error(function(err) {
console.log('error', err);
$scope.isDataLoading = false;
})
You can take this as an example. and change this code according to your need.

How to prevent some background-images caching

adding some random number it works, but only for img
<img src="example.jpg?377489229" />
Is there any way to prevent caching prp. background-image?
<div style="background-image: url(example.jpg )"></div>"
The same technique will work there.
<div style="background-image: url(example.jpg?377489229)"></div>
Assuming your server doesn't act differently with the presence of that GET param.
This will only break the cache once though, if you want it to always hit the server, you will need to use some different techniques.
To generate image urls with dynamic timestamp as query param You need at least JavaScript code that will dynamically add latest timestamp to background image url and make something like this:
someimage.jpg? (new Date()).getTime() => someimage.jpg?1479341018085
You can use this example:
function getNoCacheBgElements() {
return document.querySelectorAll('.no-cache-bg');
}
function loadBgImageForElement(element) {
element.style['background-image'] =
'url('+ element.attributes['data-background-image'].value + '?' + (new Date()).getTime() +')';
}
function loadBgImages() {
for(
var i = 0, elements = getNoCacheBgElements();
i < elements.length;
loadBgImageForElement(elements[i]), i++
);
}
window.onload = function() {
loadBgImages();
};
.size-100x100 {
min-width: 100px;
min-height: 100px;
}
.float-left {float: left;}
.margin-10 {margin: 10px;}
<p> These background images loaded dynamically every time You hit "Run code snippet". </p>
<div class="no-cache-bg size-100x100 float-left margin-10" data-background-image="http://lorempixel.com/output/abstract-q-c-640-480-8.jpg"></div>
<div class="no-cache-bg size-100x100 float-left margin-10" data-background-image="http://lorempixel.com/output/abstract-q-c-640-480-9.jpg"></div>
<div class="no-cache-bg size-100x100 float-left margin-10" data-background-image="http://lorempixel.com/output/abstract-q-c-640-480-10.jpg"></div>
</br>
<p> Check browser's network tab and You'll see that it requests for images on every page load. </p>

jQuery toggle() animating when I don't want it to?

I've got three elements with IDs "albums", "about", and "contact", and three links to show/hide them via the toggle() function, with IDs "togglealbums", "toggleabout", and "togglecontact". I only want one of these elements to be able to be seen at any time, so I wrote the following functions:
$('#togglealbums').click(function() {
if( $('#about').is(':visible') ) {
$('#about').toggle(function() {
$('#albums').toggle();
});
} else if( $('#contact').is(':visible') ) {
$('#contact').toggle(function() {
$('#albums').toggle();
});
} else {
$('#albums').toggle();
}
});
$('#toggleabout').click(function() {
if( $('#albums').is(':visible') ) {
$('#albums').toggle(function() {
$('#about').toggle();
});
} else if( $('#contact').is(':visible') ) {
$('#contact').toggle(function() {
$('#about').toggle();
});
} else {
$('#about').toggle();
}
});
$('#togglecontact').click(function() {
if( $('#albums').is(':visible') ) {
$('#albums').toggle(function() {
$('#contact').toggle();
});
} else if( $('#about').is(':visible') ) {
$('#about').toggle(function() {
$('#contact').toggle();
});
} else {
$('#contact').toggle();
}
});
First of all, if these are wildly inefficient or there is an easier way to do this, please let me know.
What I've found is that if none of the three DIVs is visible, clicking one of the toggle links will show/hide the respective div with no animation. However, if one of the DIVs is visible, clicking another toggle link will cause the div to shrink and fade and the new one expands and fades in, which I don't want (at least for now). This can be seen here: http://new.e17.paca.arvixe.com.
Can anyone tell me why this is happening?
Thanks!
EDIT:
Markup is here:
<body>
<div id="main">
<div id="nav">
<div id="menu">
<ul>
<li>Albums</li>
<li>About Me</li>
<li>Contact</li>
</ul>
</div>
</div>
<div id="albums">
Albums go here
</div>
<div id="about">
About info goes here
</div>
<div id="contact">
Contact info goes here
</div>
</div>
</body>
Your shrink-and-fade was happening because, if .toggle() is given a callback function, it assumes you want to animate the toggle instead of just switching it on/off. (According to the docs, as of this writing, that's only supposed to happen when you provide a duration. I've submitted a bug report about this.)
See http://jsfiddle.net/mblase75/byKeP/1/ for a reduced example of this. To solve it, just remove the callbacks and put the same code in the next line of your function.
As for streamlining your code, classes are your friends. HTML:
toggle albums
toggle about
toggle contact
<div class="toggleblock" id="albums">ALBUMS</div>
<div class="toggleblock" id="about">ABOUT</div>
<div class="toggleblock" id="contact">CONTACT</div>
Note the data- attributes, which jQuery will parse and make accessible through the .data() method. This makes it easy to store a unique div ID on the hyperlink itself, which in turn streamlines our JavaScript immensely. JS:
$('.togglelink').on('click',function(e) {
var id = $(this).data('block');
$('#'+id).toggle().siblings('.toggleblock').hide();
});​
http://jsfiddle.net/mblase75/byKeP/