How to best utilize jQuery to programmatically generate HTML elements - javascript

I have a bunch of Javascript functions that look like the following:
function generateBusinessImage (business) {
var business_image = document.createElement('img');
business_image.setAttribute('class','photo');
business_image.alt = business.name;
business_image.title = business.name;
business_image.align = 'right';
business_image.src = business.photo_url;
return business_image;
}
This seems like a good canidate for a refactor. From reviewing a few different jQuery docs, it would appear that I should be able to do something similar to this pseudo code:
return var business_image = document.createElement('img').
setAttribute('class','photo').
alt(business.name).
title(business.title).
align('right').
src(business.photo_url);
Am I on the right track?
Thanks!
EDIT
I'm calling the function above with the following code and the line where I do appendChild on div with generateBusinessImage is where my errors are occurring with some of the answers below:
var div = document.createElement('div');
var div_class = document.createAttribute('class');
div.setAttribute('class','business');
div.appendChild(generateBusinessImage(business));

You can create all that with jQuery via chained calls:
function generateBusinessImage (business) {
return $('<img class="photo" align="right" />')
.attr('alt', business.name)
.attr('title', business.name)
.attr('src', business.photo_url)
.get(0)
}
(Note on the get(0) on the last line: to remain backwards compatible with your existing caller of generateBusinessImage() I return the DOM element jQuery created, by calling .get(0))
References:
jQuery.attr
jQuery.fn.get

Yes, you are right. Generally, it is, however, thought to be faster to actually do string concatenation (albeit, it is a bit sloppier).
To do what you want in jquery, it would be like so:
function generateBusinessImage (business) {
var $business_image = $('<img />');
$business_image
.addClass('photo')
.attr('alt',business.name)
.attr('title',business.name)
.attr('align','right')
.attr('src',business.photo_url);
return $business_image;
}
To be perfectly honest, though, this will be faster (but uglier code):
function generateBusinessImage(business) {
return $('<img src="'+business.photo_url+'" alt="'+business.name+'" title="'+business.name+'" align="right" class="photo" />');
}

Related

I am trying to trim the output of a jQuery function

I am modifying a third-party script so that I can style the output.
Here is a segment of the original code:
var tip_content = $('<div>').addClass('tip_content').load(url, function() {
Which produces this output:
<div class="tip_content">
I need to add another class to the output to style it differently on each page. Therefore, it seems like a good solution to add the current html page file name as a class.
But I have no experience with JS.
Here is what I've managed to mangle together:
var tip_content = $('<div>').addClass('tip_content '+elem.attr('href')).load(url, function() {
Which produces this:
<div class="tip_content tickets.php?id=185">
This is almost exactly what I need. But I would be very grateful if someone could demonstrate how to trim the output to:
<div class="tip_content tickets">
You have to split the URL with . and takes the first-value from the splited array and add it to the div as second class.
Do it like below:-
var tip_content = $('<div>').addClass('tip_content '+elem.attr('href').split('.')[0]).load(url, function() {
A hard-coded example:-
var hrefs = "tickets.php?id=185";
$('div').addClass('tip_content '+hrefs.split('.')[0]);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div>Inspect and check my class</div>
try below code
s = elem.attr('href');
s = s.substring(0, s.indexOf('.'));
var tip_content = $('<div>').addClass('tip_content '+ s).load(url, function() {
I would like to add a modification to be safe. suppose your url is: tickets.sold.php and you want tickets.sold. In this case you should try this:
s = elem.attr('href');
s = s.substring(0, s.indexOf('.php'));
var tip_content = $('<div>').addClass('tip_content '+ s).load(url, function() {

Rollover will not swap

Hey im having trouble with my javascript rollover. The image does not change. Ive had a look at some tutorials and i cant see where im going wrong.
Here is my code:
Home.xhtml
<img src="images/Weights.png" width="900" height="300" border="0" alt="Gym Equipment" name="gym"
onMouseOver="swapImage('gym','treadmill');" onmouseout="swapImage('gym','weights');"/>
newjs.js
// Pre load images for rollover
if (document.images)
{
treadmill = new Image
weights = new Image
treadmill.src = "images/Treadmill.png"
weights.src = "images/Weights.png"
}
function swapImage(thisImage,newImage)
{
if (document.images)
{
document[thisImage].src = eval(newImage + ".src")
}
}
How i tell the app where the js is:
document[thisImage].src = eval(newImage + ".src")
should be
document[thisImage].src = eval(newImage ).src
Please avoid using eval() as it is generally the slowest way to evaluate code and there are some circumstances where it introduces security risks depending upon where the data comes from that you're calling eval on.
You should be able to make this work:
HTML:
<img src="images/Weights.png" width="900" height="300" border="0" alt="Gym Equipment" name="gym"
onMouseOver="swapImage(this,'treadmill');" onmouseout="swapImage(this,'weights');"/>
Javascript:
// Pre load images for rollover
window.treadmill = new Image();
window.weights = new Image();
treadmill.src = "images/Treadmill.png"
weights.src = "images/Weights.png"
// this function must be defined globally
// (e.g. not defined inside any other function)
function swapImage(thisImage,newImageName) {
thisImage.src = window[newImageName].src;
}
Working demo here: http://jsfiddle.net/jfriend00/cv8tT/
Changes I made:
Removed the use of eval() and use window[name] to access global variables.
Changed the way swapImage() is called in the HTML to pass this so you can directly access the desired image.
Remove the if (document.images) checks since it is no longer used by the code.
FYI, all this could be done with CSS and background images with no javascript at all.
I would take a slightly different approach by taking the mouseover and mouseout attributes out of your image tag. This will help keep your code more maintainable.
I made a DEMO jsfiddle here
Note that I am using 3 images from Flickr, the default, one on mouseover, and one on mouseout. I hope this helps.
** Also note that the img tag now has an ID which is referenced in the bindings.
// Pre Load Images
var img1 = new Image();
var img2 = new Image();
img1.src = "http://farm4.staticflickr.com/3230/2953035318_b54956e7df_q.jpg";
img2.src = "http://farm4.staticflickr.com/3026/2992860864_aa9e8b0818_q.jpg";
// Event binding function
var bindEvent = function (el, eventName, eventHandler) {
if (el.addEventListener != null) {
return el.addEventListener(eventName, eventHandler, false);
} else if (el.attachEvent != null) {
return el.attachEvent('on' + eventName, eventHandler);
}
}
// Mouseover binding
bindEvent(document.getElementById('surfer'), "mouseover", function (e) {
this.setAttribute("src", img1.src);
});
// Mouseout Binding
bindEvent(document.getElementById('surfer'), "mouseout", function (e) {
this.setAttribute("src", img2.src);
});

javascript - trying to make an onClick alert based on id/class

I'm new to programming and was wondering how to make a customized alert that shows the id or class name of the object when I click on it. My site has a picture of 8 different animals, and I want it so that every time I click on one of the animals there's an alert with "This is a (animal's name)". Why won't my javascript code below work?
should i be using "this" instead of "parama"? i don't understand whether or not to have any parameters for my function clicky.
var images = new Array()
images[0] = "bison"
images[1] = "frog"
function clicky(parama){
for (entry in images){
if (parama.attributes["name"].value === images[entry]){
$(parama).onClick(alert("This is a" + parama.attributes["name"].value));
} else {
$(parama).onClick(alert("dang it");
}
}
}
using sort of a combination of both your answers, I figured out a way to do it with a lot less code than I originally had. Check it out! (images all had classes of "pic")
$('.pic').click(function(){
alert("This is a " + this.getAttribute('alt'))
});
I'd recommend to use the title or alt attribute on images instead of a JS array - that's more SEO friendly and semantic. Not to mention that alt is required on images to make your HTML valid - DEMO
var images = document.getElementsByTagName("img");
for ( var i = 0, count = images.length; i < count; i++ ) {
images[i].addEventListener("click", function() {
alert( this.getAttribute("alt") );
});
}
UPDATE
if you open to use jQuery - DEMO
$("img").on("click", function() {
alert( $(this).prop("alt") );
});​
You can use .click() but it's recommended to use .on() instead to attach different kind of event listeners to elements. jQuery also provides a shorthand for getting the properties - .prop()

JavaScript/jQuery: hasDescendant / hasAncestor

Hilariously, I'm having incredible difficulty finding any half-good way to determine whether or not an HTML element is inside another one or not -- which seems like it should be a basic core feature of traversing and analyzing the HTML DOM. I was immensely surprised and disappointed that the "hasDescendant" (or likewise) method is missing.
I'm trying to do this:
var frog = $('#frog');
var walrus = $('#walrus');
if (frog.hasDescendant(walrus)) console.log("Frog is within walrus.");
else console.log("Frog is outside walrus.");
I've tried to reproduce what I'm looking for with many jQuery combinations.
walrus.is(frog.parents());
walrus.has(frog);
walrus.find(' *').has(frog);
frog.is(walrus.find(' *'));
I haven't found a working solution yet.
[edit]
Solution: walrus.has(frog)
Alternate: if (walrus.has(frog)) { doStuff(); }
Alternate: var booleanResult = walrus.has(frog).length>0;
//Chase.
jQuery has just the function for this: jQuery.contains: "Check to see if a DOM element is within another DOM element."
Demo (live copy):
HTML:
<p id="frog">Frog <span id="walrus">walrus</span></p>
JavaScript:
jQuery(function($) {
var frog = $("#frog"),
walrus = $("#walrus");
display("frog contains walrus? " + $.contains(frog[0], walrus[0]));
display("walrus contains frog? " + $.contains(walrus[0], frog[0]));
function display(msg) {
$("<p>").html(msg).appendTo(document.body);
}
});
Use
if (walrus.has(frog).length) {
// frog is contained in walrus..
}
Demo at http://jsfiddle.net/gaby/pZfLm/
An alternative
if ( $('#frog').closest('#walrus').length ){
// frog is contained in walrus..
}
demo at http://jsfiddle.net/gaby/pZfLm/1/
If you wanted to write your own function you could do it without jQuery, perhaps something like this:
function isAncestor(ancestor, descendent) {
while ((descendent = descendent.parentNode) != null)
if (descendent == ancestor)
return true;
return false;
}

Help me simplify this JS code

I'm a beginner in JS and want to know a way to simplify this code. There are 7 different divs with iframes, and also 7 different links. I have shown 1 div with iframe and 1 link. I have no idea where to start. Any help would be greatly appreciated.
NOTE: The code works to my needs, but I just need to simplify it (less js code in html, and more in js file).
JavaScript in .js file:
function show_visibility(){
for(var i = 0,e = arguments.length;i < e;i++){
var myDiv = document.getElementById(arguments[i]).style;
myDiv.display = "block";}
}
function hide_visibility(){
for(var i = 0,e = arguments.length;i < e;i++){
var myDiv = document.getElementById(arguments[i]).style;
myDiv.display = "none";}
}
function refFrame() {
for(var i = 0,e = arguments.length;i < e;i++){
document.getElementById(arguments[i]).src = document.getElementById(arguments[i]).src;
}
}
Div/iframe to be modified:
<div id="r1-box">
<iframe id="frame-box1" class="work" src="youtubelink" width="720" height="405" frameborder="0"></iframe>
</div>
Link to execute JS:
<a id="r1" href="javascript:refFrame('frame-box2','frame-box3','frame-box4','frame-box5','frame-box6','frame-box7');show_visibility('r1-box');hide_visibility('r2-box','r3-box', 'r4-box','r5-box','r6-box','r7-box');">
</a>
As a beginner you shouldn't start using jQuery until you understand Javascript more.
There are a few ways you could simplify this, the most immediate one would be to get the Javascript out of the link and into a Javascript file, or at the top of the page:
window.onload = function() {
document.getElementById('#r1').onclick = function() {
refFrame('frame-box2','frame-box3','frame-box4','frame-box5','frame-box6','frame-box7');
show_visibility('r1-box');
hide_visibility('r2-box','r3-box', 'r4-box','r5-box','r6-box','r7-box');
};
// more...
};
window.onload is an event which fires once the page has - you guessed it - finished loading. There are better ways of doing this, but this is about as basic as it gets. I'd advise you look at javascript domready?
After looking at your code a bit more, I realised all your seven links will do essentially the same thing. You can simply this by using a single function:
function refClick(id) {
var i = 7,
frames = [],
boxes = [];
while(i--) {
if(i != id) {
frames.push('frame-box' + i);
boxes.push('r' + i + '-box');
}
}
refFrame.apply(null, frames);
hide_visibility.apply(null, boxes);
show_visibility('r' + id + '-box');
}
What I'm doing here is looping through 7 times, and building an array of arguments for the refFrame and hide_visibility functions. The id variable tells the loop not to put in that id into the arrays.
Using the .apply method, I can apply an array as the arguments and call it normally.
For each of your links, you can apply the following function
document.getElementById('#r1').onclick = function() {
refClick(1);
};
document.getElementById('#r2').onclick = function() {
refClick(2);
};
//.....
You could start using jQuery.
http://jquery.com/

Categories

Resources