Skip to content
View in the app

A better way to browse. Learn more.

Web Designer Forum

A full-screen app on your home screen with push notifications, badges and more.

To install this app on iOS and iPadOS
  1. Tap the Share icon in Safari
  2. Scroll the menu and tap Add to Home Screen.
  3. Tap Add in the top-right corner.
To install this app on Android
  1. Tap the 3-dot menu (⋮) in the top-right corner of the browser.
  2. Tap Add to Home screen or Install app.
  3. Confirm by tapping Install.

Javascript Beginner!

Featured Replies

Hello, could someone tell me where i'm going wrong with the following code?

<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.4.4/jquery.min.js"></script>
			<script src="script/speechbubbles.js"></script>
			<script src="script/speechbubbles2.js"></script>

			<script type="text/javascript">

				jQuery(function($){ //on document.ready
 					//Apply tooltip to links with class="addspeech", plus look inside 'speechdata.txt' for the tooltip markups
					$('a.addspeech').speechbubble({url:'speechdata.txt'});
					$('a.addspeech2').speechbubble2({url:'speechdata.txt'})
				})
</script>

Is there any reason that shouldn't work?

Basically I have two tooltips to display, i've got them both displaying how I want them to, except I want to style 1 a little differently... So i've edited the css, and edited the code in the 2nd src file so that speechbubble2 links to that 2nd file?

Also, where's the best place to start learning Javascript? From the bottom up... Any specific books anyone can recommend?

Edited by Lee_K

  • Author

Yeah I have "a class="addspeech" and "a class="addspeech2" Obviously 1 is styled differently to the other...

 

I can get both of them styled as "style1" or "style2" but not 1 of each...

  • Author

It seems as though the code in these 2 are causing the problem:

<script src="script/speechbubbles.js"></script>
<script src="script/speechbubbles2.js"></script>

Some sort of clash between the 2.

  • Author


var speechbubbles_tooltip={

	loadcontent:function($, selector, options, callback){
		var ajaxfriendlyurl=options.url.replace(/^http:\/\/[^\/]+\//i, "http://"+window.location.hostname+"/") 
		$.ajax({
			url: ajaxfriendlyurl, //path to external content
			async: true,
			error:function(ajaxrequest){
				alert('Error fetching Ajax content.<br />Server Response: '+ajaxrequest.responseText)
			},
			success:function(content){
				$(document.body).append(content)
				callback(selector)
				$(content).remove()
			}
		})

	},

	buildtooltip:function($, setting){
	var speechtext=(setting.speechid)? $('div#'+setting.speechid).html() : setting.speechtext
	if (speechtext){
		$speech=$('<div class="speechbubbles2">'+speechtext+'</div>').appendTo(document.body)
		$speech.addClass('speechbubbles').append('<div class="speechbubbles-arrow-border"></div>\n<div class="speechbubbles-arrow"></div>')
		$speech.data('$arrowparts', $speech.find('div.speechbubbles-arrow, div.speechbubbles-arrow-border')) //store ref to the two arrow DIVs within tooltip
		var arrowheight=(window.XMLHttpRequest)? $speech.data('$arrowparts').eq(0).outerHeight() : 10
		$speech.data('measure', {w:$speech.outerWidth(), h:$speech.outerHeight()+arrowheight, arroww:$speech.data('$arrowparts').eq(0).outerWidth()}) //cache tooltip dimensions
		$speech.css({display:'none', visibility:'visible'})
		setting.$speech=$speech //remember ref to tooltip
	}
	return setting.$speech
	},
	

	positiontip:function($, $anchor, s, e){
		var $speech=s.$speech
		var $offset=$anchor.offset()
		var windowmeasure={w:$(window).width(), h:$(window).height(), left:$(document).scrollLeft(), top:$(document).scrollTop()} //get various window measurements
		var anchormeasure={w:$anchor.outerWidth(), h:$anchor.outerHeight(), left:$offset.left, top:$offset.top} //get various anchor link measurements
		var speechmeasure={w:$speech.data('measure').w, h:$speech.data('measure').h} //get tooltip measurements
		var x=anchormeasure.left
		var y=anchormeasure.top+anchormeasure.h
		x=(x+speechmeasure.w>windowmeasure.left+windowmeasure.w-10)? x-speechmeasure.w+anchormeasure.w-15 : x //right align tooltip if no space to the right of the anchor
		
		var isrightaligned=x!=anchormeasure.left //Boolean to indicate if tooltip is right aligned
		var istopaligned=y!=anchormeasure.top+anchormeasure.h+10 //Boolean to indicate if tooltip is top aligned

		
		
		var speechcss_before={opacity:0, left:x, top:(istopaligned)? y-speechmeasure.h-10 : y+speechmeasure.h+10}
		var speechcss_after={opacity:1, top:y+10}
		if (document.all && !window.msPerformance){ //detect IE8 and below
			delete speechcss_before.opacity //remove opacity property, as IE8- does not animate this property well with CSS triangles present
			delete speechcss_after.opacity
		}
		$speech.css(speechcss_before).show().animate(speechcss_after)
	},


	init:function($, $anchor, options){
		var s={speechtext:$anchor.attr('title'), speechid:$anchor.attr('rel')}
		$.extend(s, options)
		if (this.buildtooltip($, s)){
			if (s.speechtext) //if title attribute of anchor is defined
				$anchor.attr('title', "") //disable it
			$anchor.click(function(e){
				if (s.$speech.queue().length==0){
					clearTimeout(s.hidetimer)
					speechbubbles_tooltip.positiontip($, $anchor, s, e)
				}
			})
			$speech.click(function(e){
				s.hidetimer=setTimeout(function(){s.$speech.stop(true,true).hide()}, 200)
			})
		}
	}

}

jQuery.fn.speechbubble2=function(options){
	var $=jQuery
	function processanchor(selector){
		return selector.each(function(){ //return jQuery obj
			var $anchor=$(this)
				speechbubbles_tooltip.init($, $anchor, options)
		})
	}
	if (options && options.url)
		speechbubbles_tooltip.loadcontent($, this, options, processanchor)
	else
		processanchor(this)
};

That is the code that each 1 links to, it's basically the same code on each of them except for "div class="speechbubbles2".

 

One of them is "div class="speechbubbles2", while the other is "div class="speechbubbles".

 

I can get both styles display but not at the same time. All i'm getting is 1 style for both of them.

In terms of learning:

 

Good sites are Treehouse, code academy, code school etc - some free, some not.

 

You have to team it up with coding/ reading others source code too. I always see something new when I look at other peoples source code.

 

Books are good too, I first got Javascript the definitive guide by o'rielly but it is too dense for me. Then my wife got me this:

 

http://www.amazon.co.uk/Professional-JavaScript-Developers-Nicholas-Zakas/dp/1118026691/ref=sr_1_2?ie=UTF8&qid=1392820083&sr=8-2&keywords=javascript

 

For me Wrox books are great as they are a good mixture of content that is well explained but it not as dense as other books.

**** me, bro. its seems ilke you're taking a round the world flight just to visit the shop across the road. But I don't know what your particular requirements are for this. so hey hoo, here goes...

 

Firstly, you don't need to duplicate speechbubbles.js, keep one version (unaltered). (Most of the time, if you're using a plugin, or a script, you won't ever need to alter what's in there).

 

You're then declaring the following:

 

 

jQuery(function($){ //on document.ready
    //Apply tooltip to links with class="addspeech", plus look inside 'speechdata.txt' for the tooltip markups
    $('a.addspeech').speechbubble({url:'speechdata.txt'});
});
 

As it says, it will display the tooltip to any link with the class "addspeech", and will look inside the external file "speechdata.txt" for the specific markup. In that file, I guess you probably have two speech bubbles set-up:

 

eg.

 

 

<div id="speechbubble1" class="speechbubbles">
This is the first speech bubble.
</div>

<div id="speechbubble2" class="speechbubbles">
This is the second speech bubble.
</div>
 

Each div has the same name class-name, "speechbubbles", and in our CSS you can declare shared styles, that both of them have that are similar.

 

Each div has a unique ID - you can style these via CSS again, by declaring the ID, and then writing the specific styles - this will override the shared styles.

 

To match up a specific anchor link to a specific speechbubble, use the "rel" attribute to point to the desired ID.

eg,

 

 

<a class="addspeech" href="#" title="Speech Bubble 1" rel="speechbubble1">Speech Bubble 1</a>
<a class="addspeech" href="#" title="Speech Bubble 2" rel="speechbubble2">Speech Bubble 2</a>
 

Now, when the anchor link 'Speech Bubble 1' is hovered over, it will look up the contents in speechdata.txt, and only display the contents of the div with id#speechbubble1, as declared in the "rel" attribute.

When you hover over 'Speech Bubble 2', that will display the contents of the div with id#speechbubble2 as found in speechdata.txt.

 

To style the two tooltips differently, you will declare separate CSS values via their specific id's.

 

Hope that helps...

 

Re; learning JS, I'd start with http://www.codecademy.com/

To summarise, basically, you don't need to duplicate the script to style individual elements: to style the elements you would that via CSS, and by either classnames (shared styles) or IDs (specific style pertaining to that particular ID).

This script seems to have a really odd and difficult method to get a pretty trivial result.

 

Why not use data attributes in the html and use those to populate the speech bubbles, the data-attributes could quite easily be populated from the back-end cms..

  • Author

I really haven't explained this well at all...

 

Basically what i've got is this:

<a style="cursor: pointer;" class="addspeech" rel="#name1">
<a style="cursor: pointer;" class="addspeech" rel="#name2">

 

Which points to:

<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.4.4/jquery.min.js"></script>
<script src="script/speechbubbles.js"></script>

<script type="text/javascript">

jQuery(function($){ //on document.ready
		//Apply tooltip to links with class="addspeech", plus look inside 'speechdata.txt' for the tooltip markups
	$('a.addspeech').speechbubble({url:'speechdata.txt'})
})

</script>

 

That then points to the following script:


var speechbubbles_tooltip={

	loadcontent:function($, selector, options, callback){
		var ajaxfriendlyurl=options.url.replace(/^http:\/\/[^\/]+\//i, "http://"+window.location.hostname+"/") 
		$.ajax({
			url: ajaxfriendlyurl, //path to external content
			async: true,
			error:function(ajaxrequest){
				alert('Error fetching Ajax content.<br />Server Response: '+ajaxrequest.responseText)
			},
			success:function(content){
				$(document.body).append(content)
				callback(selector)
				$(content).remove()
			}
		})

	},

	buildtooltip:function($, setting){
	var speechtext=(setting.speechid)? $('div#'+setting.speechid).html() : setting.speechtext
	if (speechtext){
		$speech=$('<div class="speechbubbles">'+speechtext+'</div>').appendTo(document.body)
		$speech.addClass('speechbubbles').append('<div class="speechbubbles-arrow-border"></div>\n<div class="speechbubbles-arrow"></div>')
		$speech.data('$arrowparts', $speech.find('div.speechbubbles-arrow, div.speechbubbles-arrow-border')) //store ref to the two arrow DIVs within tooltip
		var arrowheight=(window.XMLHttpRequest)? $speech.data('$arrowparts').eq(0).outerHeight() : 10
		$speech.data('measure', {w:$speech.outerWidth(), h:$speech.outerHeight()+arrowheight, arroww:$speech.data('$arrowparts').eq(0).outerWidth()}) //cache tooltip dimensions
		$speech.css({display:'none', visibility:'visible'})
		setting.$speech=$speech //remember ref to tooltip
	}
	return setting.$speech
	},
	

	positiontip:function($, $anchor, s, e){
		var $speech=s.$speech
		var $offset=$anchor.offset()
		var windowmeasure={w:$(window).width(), h:$(window).height(), left:$(document).scrollLeft(), top:$(document).scrollTop()} //get various window measurements
		var anchormeasure={w:$anchor.outerWidth(), h:$anchor.outerHeight(), left:$offset.left, top:$offset.top} //get various anchor link measurements
		var speechmeasure={w:$speech.data('measure').w, h:$speech.data('measure').h} //get tooltip measurements
		var x=anchormeasure.left
		var y=anchormeasure.top+anchormeasure.h
		x=(x+speechmeasure.w>windowmeasure.left+windowmeasure.w-10)? x-speechmeasure.w+anchormeasure.w-15 : x //right align tooltip if no space to the right of the anchor
		
		var isrightaligned=x!=anchormeasure.left //Boolean to indicate if tooltip is right aligned
		var istopaligned=y!=anchormeasure.top+anchormeasure.h+10 //Boolean to indicate if tooltip is top aligned

		
		
		var speechcss_before={opacity:0, left:x, top:(istopaligned)? y-speechmeasure.h-10 : y+speechmeasure.h+10}
		var speechcss_after={opacity:1, top:y+10}
		if (document.all && !window.msPerformance){ //detect IE8 and below
			delete speechcss_before.opacity //remove opacity property, as IE8- does not animate this property well with CSS triangles present
			delete speechcss_after.opacity
		}
		$speech.css(speechcss_before).show().animate(speechcss_after)
	},


	init:function($, $anchor, options){
		var s={speechtext:$anchor.attr('title'), speechid:$anchor.attr('rel')}
		$.extend(s, options)
		if (this.buildtooltip($, s)){
			if (s.speechtext) //if title attribute of anchor is defined
				$anchor.attr('title', "") //disable it
			$anchor.click(function(e){
				if (s.$speech.queue().length==0){
					clearTimeout(s.hidetimer)
					speechbubbles_tooltip.positiontip($, $anchor, s, e)
				}
			})
			$speech.click(function(e){
				s.hidetimer=setTimeout(function(){s.$speech.stop(true,true).hide()}, 200)
			})
		}
	}

}

jQuery.fn.speechbubble=function(options){
	var $=jQuery
	function processanchor(selector){
		return selector.each(function(){ //return jQuery obj
			var $anchor=$(this)
				speechbubbles_tooltip.init($, $anchor, options)
		})
	}
	if (options && options.url)
		speechbubbles_tooltip.loadcontent($, this, options, processanchor)
	else
		processanchor(this)
};

 

As you can see, 4 lines down from "buildtooltip:function($, setting){" is "(<div class="speechbubbles">)" which points to the class inside the CSS. What I have in there is "div.speechbubbles" and "div.speechbubbles2". So what I want is to style these individually:

<a style="cursor: pointer;" class="addspeech" rel="#name1">
<a style="cursor: pointer;" class="addspeech" rel="#name2">

 

I should probably point out that the reason of doing the tooltip this way was so that I could put the contents of the tooltips inside an external file that I could keep blocked from crawlers, basically so that the contents of it aren't indexed. Only viewable by the user.

Edited by Lee_K

Create an account or sign in to comment

Account

Navigation

Search

Search

Configure browser push notifications

Chrome (Android)
  1. Tap the lock icon next to the address bar.
  2. Tap Permissions → Notifications.
  3. Adjust your preference.
Chrome (Desktop)
  1. Click the padlock icon in the address bar.
  2. Select Site settings.
  3. Find Notifications and adjust your preference.