I wrote a little code sample which:
- load images
- manipulate DOM (replace images)
- store/retrieve related data using localStorage
$(document).on('ready', function(){
$('#chooseFile').on('click', function (e) {
url = $('#image-url').val();
// check if it's empty
if (url === "")
alert('Please type a URL');
url = addHTTP(url);
if (checkURL(url)){
// get image size (and save dimensions in local storage)
getImageDimensions(url, updateBackgroundDimensions);
localStorage.setItem('myImageURL', url);
updateBackgroundImage(url);
$('#fileModal').modal('hide');
}else{
alert('Not a valid image!');
}
});
$('#resetImage').on('click', function (e) {
window.localStorage.clear();
location.reload();
});
checkLocalStorage();
});
function checkLocalStorage(){
if(localStorage.getItem('myImageURL') &&
localStorage.getItem('myImageURLWidth') &&
localStorage.getItem('myImageURLHeight')) {
updateBackgroundDimensions(localStorage.getItem('myImageURLWidth'),localStorage.getItem('myImageURLHeight'));
updateBackgroundImage(localStorage.getItem('myImageURL'));
}
}
function updateBackgroundDimensions(w, h){
$('#image').css('width', w);
$('#image').css('height', h);
$('#image').css('background-size', w + 'px ' + h + 'px');
}
function updateBackgroundImage(url){
$('#image').css('background-image', 'url('+url+')');
}
function getImageDimensions(url, callback){
var img = $('<img src="'+url+'"/>').load(function(){
localStorage.setItem('myImageURLWidth', this.width);
localStorage.setItem('myImageURLHeight', this.height);
callback(this.width, this.height);
});
}
function addHTTP(url) {
if (!/^(f|ht)tps?:\/\//i.test(url)) {
url = "http://" + url;
}
return url;
}
function checkURL(url) {
return(url.match(/\.(jpeg|jpg|gif|png)$/) !== null);
}
Full demo here
It works, but many parts could be improved. To begin with:
I believe these lines should be together, maybe wrapped into a function. Probably it would be better to have only one item on localStorage (an object with three properties):
localStorage.setItem('myImageURLWidth', this.width); localStorage.setItem('myImageURLHeight', this.height);
and
localStorage.setItem('myImageURL', url);
...but they aren't, because in order to know the image's width and height, the image must be loaded beforehand. And it wouldn't make sense to pass the image's URL along for the callback function
updateBackgroundDimensions()
to use it.For the same reason,
updateBackgroundImage(url);
and
updateBackgroundDimensions();
also aren't together.
Are there recommended practices for separating
localStorage
related code (ex:checkURL()
andaddHTTP()
) into a module or something?This seems to be very inappropriate:
getImageDimensions(url, updateBackgroundDimensions);
What if I need to usegetImageDimensions()
with more than one image?How can I approach this particular problem by separating all the DOM-related code from the application logic?
These are the main points that bother me now. If there's anything else not mentioned that could be improved, I'd love to hear.
Obs: I'd preferably handle these situations without an external library, using only JavaScript, but if there are some helpful ones, they're also welcome.
Here I quickly rewrote that to make it more readable and to arrange a couple things together. There's a lot that could be improved yet (by separating DOM manipulation from localStorage
and other logic for example). It may look like that there's no really need considering that it would be a very simple app like this, but that's just an example, I actually want to grasp all information I can that relates to code design and that can improve maintenance and scalability, because I still got some bad habits of writing script on a single document, and while I've been trying to avoid that, often it doesn't really make a big difference.
And even though I'm able to grasp some concepts like closures and other stuff, It's not that easy to apply all that to my daily coding, it's hard sometimes to let go the 'automatic mode' despite my effort.