February 19, 201412 yr 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 February 19, 201412 yr by Lee_K
February 19, 201412 yr 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...
February 19, 201412 yr 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.
February 19, 201412 yr 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.
February 19, 201412 yr 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.
February 19, 201412 yr **** 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/
February 19, 201412 yr 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).
February 19, 201412 yr 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..
February 19, 201412 yr 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 February 19, 201412 yr by Lee_K
February 21, 201412 yr Author Is it even possible? I'm guessing if it is then it's not an easy job to do?
Create an account or sign in to comment