Changing javascript code with javascript - javascript

Yeah this might look crazy but I just want to know if this is possible or not. I have something like this:
$('button').click(function(){
if(variable == 10){
$('img').attr('src','img/image.jpg');
} else {
$('img').attr('src','img/image-2.jpg');
}
});
Now, the problem is I have more than 2 photos (I have 10 categories of 2 photos each) but I don't want to create 10 variables and copy that block of code 10 times. So I wondered if you can make something like changing that 'img/image...jpg' part with another javascript command or so.

One solution is to use the variable as part of the image name, e.g.
$('img').attr('src','img/image-' + variable + '.jpg');

It depends on the names of your images - if you control the names, then you can make them work better with dynamic variables using a concept called string concatenation:
var num = 2;
$('img').attr('src', 'img/image-' + num + '.jpg');
This code will render img/image-2.jpg. If you change the num variable, the image source will change accordingly.

Related

Correct way to convert your JavaScript function into a string so it can be inserted into innerHTML

This is what I am doing: I am building a fun in house API Voting System. I am using a client side snippet insert onto page
Like this:
<script src="domain.com/api/scripts/main.js"></script>
<div id="content-wrap" id="ac1e435e-c564-48f8-9f45-338616e7a789"></div>
Now in my main .JS I do all ajax request and modify the #content-wrap with creating new elements and inserting additional JS required to run Voting System.
However big issue I am experiencing is when I write JavaScript that I need to insert into #content-wrap I am currently writing it like this:
script.innerHTML = "$(someting).on('click', funciton(){"
+ "$.ajax({type: 'post',"
+ " url: '" + base + "/api/request', data: $('form').serialize(), "
+ "success: function(response){";
As you can see that can cause lot of issues as I build on it.
What is better way to accomplish this or is there a way i can just write my script / code and do something like this.
script.innerHTML = ConvertToString(script.js) OR ConvertToString(function X);
ConvertToString is just an expression I am using to explain what I would like to do instead of what I am doing.
Thank you, I am open to any suggestions.
I also must do this in plain JavaScript or with jQuery library so any suggestions to use VueJs, AngularJS or React will be considered as future references.
Thank you again
Additional explanation:
I would like to insert into my script element JavaScript snippet. But my snippet is about 30 lines long currently and might get bigger with time so it is very difficult to code with all the + " code " on every line that I write so that it can be inserted with innerHTML into element and executed on Client end.
So I would instead like to do something like this
element.innerHTML = mysnippetcode // but with out using + "" on each line like shown above
OR
element.append(snippet)
I hope this makes it little more clear
Solution that worked for me was using back ticks to wrap my sinppet and insert it into innerHTML of the element..
Just use the function's name without the () to convert it to a string:
function foo() {
var a = 10;
var b = 20;
var c = a + b;
return c;
}
document.write(foo);
The document.write will result in this string:
function foo() { var a = 10; var b = 20; var c = a + b; return c; }
If you only want the function's body, then you could just normally remove the first and last characters of the string.
I am not entirely sure this is what you wanted, if not, please make yourself more clear.
Alternatively, you could do an eval([insert function code here]) and there would be no need to add the code to the innterHTML of the script, read up on that function if you haven't heard of it.
Or if you want to create a function from a string, you can use new Function([name] ,[function body string]) if you need arguments you have to sandwich them between the 2 parameters.
But my snippet is about 30 lines long currently and might get bigger with time > so it is very difficult to code with all the + " code " on every line that I
write
You can use template literals if you want multi-line strings in Javascript, you simply have to replace your quotes with backticks.
See this MDN page if you are interested, or even this StackOverflow answer.

send Javascript variable to .css({transform: translate (var,var)})

I wanted to move a div 136px to right with transform property so i wrote:
`
$(".the_div").css({"transform":"translate(136px,0px)"});
and the_div class contains
.the_div
{
transition-duration:2s;
}
and it worked but now i want to send a javascript variable instead of 136px.
is that possible? how can i do that?
a variable like
var my_width = window.innerwidth * 0.1;
i wrote
$(".the_div").css({"transform":"translate(my_width+'px',0px)"});
and it obviously didnt work.
do you have an idea to move a div One-tenth of screen width to right (using transform property)?
You can do this in pure Javascript as well using template strings.
(PS - you don't even need JQuery)
First, save the div in a variable
const theDiv = document.querySelector('.the_div');
Second, save the value you want to translate in a variable
let number = 136;
Lastly, set the style attribute of the div
theDiv.style.transform = `tranlate(${number}px,0)`;
Hope this helps answer your question
Here is a helpful link for template strings
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Template_literals
simply you just need concatenate variable in string in javascript " + my_width + "
$(".the_div").css({"transform":"translate(" + my_width + "px,0px)"});

How to condense similar duplicate jquery functions

Well if my maths is right, my Jquery file is 16 times bigger than it could be.
I am building a tabbed category page which looks like this..
Tab1
cat1
cat2
etc
Tab2
cat1
cat2
etc
All content starts of hidden and then appears when a button in the category header is clicked (also toggling an arrow up/down).
$("#tabName_contentLink_cat1").click(function(){
$("#tabName_contentLink_cat1 > .arrow").toggleClass('greyArrow_down')
.toggleClass('blackArrow_up');
$("#tabName_content_cat1").slideToggle("fast");
});
This code works fine but I've repeated it 16 times!
The only part that varies is the number at the end of '_cat1'.
How can I convert this one piece of code, so that it can be reused 16 times?
I am a newbie, so please keep that in mind.
In my mind; assigning some sought of unique identifier (applicable category number), collecting it in a jQuery variable onClick and then pasted at the end of each _cat'HERE' seams like the way forward. I haven't a clue on how to carry it out though.
Thanks
you could add another class to all cat elements and then use it as selector or you can do what i did. Notice i made the code smaller, efficient. And it does what you wanted by using Function.
addClick(cat1);
addClick(cat2);
addClick(cat3);
addClick(cat4);
function addClick(x) {
$("#tabName_contentLink_"+x).click(function(){
$(this).slideToggle("fast").children(".arrow")
.toggleClass('greyArrow_down blackArrow_up');
});}
What about
$("[id^='tabName_contentLink_cat']").click(function(){
$(this).children(".arrow").toggleClass('greyArrow_down')
.toggleClass('blackArrow_up');
var contentId = this.id.replace(/contentLink/, 'content');
$("#"+ contentId).slideToggle("fast");
});
It's not the most elegant code, but it should work.
Why don't you use a simple for loop?
for(var i = 1; i <= 16; i++){
$("#tabName_contentLink_cat" + i).click(function(){
$("#tabName_contentLink_cat" + i + " > .arrow").toggleClass('greyArrow_down')
.toggleClass('blackArrow_up');
$("#tabName_content_cat" + 1).slideToggle("fast");
});
}
There are other options, but this seems to be the quickest way to make it work without changing too much of the existing code. To make it more generic you can wrap it in a function that receives 'i' as an argument.
Give them all the tabName_contentLink class, then:
$(".tabName_contentLink").click(function(){
$(this).children(".arrow").toggleClass('greyArrow_down')
.toggleClass('blackArrow_up');
$(this).find(".tabName_content").slideToggle("fast");
});
The keyword this allows you to reference the object calling the function, thus relate to a specific object out of a set. It can become a little tricky, but basically - you can use it as described above.

Javascript debugging - script works with hard coded variable, not with getElementById('id').value

I'm trying to debug some javascript I wrote and can't figure out why it's not working. If I hard code the variables it works fine, but if I use document.getElementById('id').value to get the variable it fails.
The example below works fine but as soon as I un-comment the commented lines it doesn't. Printing the variables before and after the second section they seem to be identical.
Really don't get what's going on. Maybe I just need to sleep on it, but if anyone's got suggestions that would be great!
roof_width = 5;
roof_depth = 3;
panel_width = 2;
panel_depth = 1;
panel_power = 200;
roof_margin = 0.100;
panel_gap = 0.05;
roof_width = document.getElementById('roof_width').value;
roof_depth = document.getElementById('roof_depth').value;
// panel_width = document.getElementById('panel_width').value;
// panel_depth = document.getElementById('panel_depth').value;
panel_power = document.getElementById('panel_power').value;
// roof_margin = document.getElementById('roof_margin').value;
panel_gap = document.getElementById('panel_gap').value;
Are you trying to add numbers that are in text boxes? Because of the way JavaScript's variable typing system works (combined with the overloading of the + operator), 2 + 2 === 4 (adding numbers) but '2' + '2' === '22' (string concatenation). Try changing the lines to, for example:
panel_width = parseFloat(document.getElementById('panel_width').value);
or alternatively:
panel_width = Number(document.getElementById('panel_width').value);
This will ensure that JavaScript treats the numbers as numbers rather than as strings.
JavaScript parameters can't be called in the same way that you're calling HTML elements. In order to call
document.getElementById('roof_margin').value;
you need to assign 'roof_margin' to an HTML form element.
Pherhaps you have multiple dom elements with the same id? Remember the dom element ID must be unique. I suggest you to use jquery for interacting javascript with html.
Make sure your code is in an onload function. Otherwise the elements may not have been loaded into the DOM yet.
window.onload = funciton(){/* code here */};

Delimiting four nested items in Javascript/Html

Okay this is frustrating me to no end. I recently coded a page in JS for a buddy of mine who wants to display wedding pictures to a family to see which ones they'd like to purchase.
I used a for loop to count 1-904:
for (beginnum=1;beginnum<=904;beginnum++) { yada yada...
Then, I used adobe bridge to rename the camera files to be 1-904 and their thumbnails (1-904 + _thumb) and used the loop number to display 904 image spaces, and the correctly numbered picture:
[note:using <) in place of the usual open tag since the site wont display it]
IE...
document.write(beginnum + ":" + "<img src='pictures" + beginnum + "_thumb.jpg' />");
Opera...
document.write("<div>" + beginnum + ":" + "<img src='pictures" + beginnum + "_thumb.jpg' /></div>")
This all works perfectly in IE and Opera (with external CSS modifying the div to not line break).
I then created a function to call up the large version of the picture when clicked on.
The problem is, when I try and nest this function into the JavaScript generated HTML I would need four delimiters. I've heard ''' or """ or the &+numeric; work in some cases as a third and fourth but I can't seem to get them to work... where I run into a problem is here...
[note:again using <) for open tag]
document.write("<a href='javascript:void(0); onClick=
Since I've already used up " and ' I now have nothing left to use to call the function when a picture is clicked.
I usually don't ask for any help, but this time I can't think of anything else that should work... I assume maybe using JS to generate the HTML leaves me with ONLY 2 delimiters that will be recognized by the browser but I am not sure, anyone know for sure? Any fixes anyone can think of?
Thanks,
~Z~
Maybe this will work
for (i=0; i<904;i++)
{
document.write("<div class=\"DivClassName\"><img src=\"pictures_" + i + "thumb.jpg\" onclick=\"OpenAWindowAndDisplayTheBigPhoto(" + i + ")\"></div>");
}
Another approach: Suppose you put everything inside a <DIV id="mainDIV">
var mainDIV = document.getElementByID("mainDIV");
var div, img, a;
for (i=0; i<904; i++)
{
div = document.createElement("DIV");
div.className = "DivClassName";
a = document.createElement("A");
a.href = "javascript:void(0)";
a.onclick = function() {OpenAWindowAndDisplayTheBigPhoto(i);};
img = document.createElement("IMG");
img.src = "pictures_" + i + "thumb.jpg";
mainDIV.appendChild(div);
div.appendChild(a);
a.appendChild(img);
};
Try building the string one piece at a time instead of trying to build the whole literal for the document.write.
Whenever things get too convoluted to follow, just do one part at a time.
var s;
s = "'Hello.' ";
s += '"I must be going."';
Without seeing code it is hard to say for a fact, but you may want to take more advantage of the fact that javascript is a first-class language, so you can create functions and pass them as arguments to other functions, or have functions return functions.
By doing this, you can decompose your page into something that sounds a bit more manageable.
Also, take advantage of the onclick event.
You should be able to simplify the javascript and so avoid this problem, IMO.

Categories