[ Index ] |
PHP Cross Reference of vtigercrm-6.1.0 |
[Summary view] [Print] [Text view]
1 /** 2 * guiders.js 3 * 4 * version 1.2.6 5 * 6 * Developed at Optimizely. (www.optimizely.com) 7 * We make A/B testing you'll actually use. 8 * 9 * Released under the Apache License 2.0. 10 * www.apache.org/licenses/LICENSE-2.0.html 11 * 12 * Questions about Guiders? 13 * You may email me (Jeff Pickhardt) at [email protected] 14 * 15 * Questions about Optimizely should be sent to: 16 * [email protected] or [email protected] 17 * 18 * Enjoy! 19 */ 20 21 var guiders = (function($) { 22 var guiders = {}; 23 24 guiders.version = "1.2.6"; 25 26 guiders._defaultSettings = { 27 attachTo: null, // Selector of the element to attach to. 28 autoFocus: false, // Determines whether or not the browser scrolls to the element. 29 buttons: [{name: "Close"}], 30 buttonCustomHTML: "", 31 classString: null, 32 description: "Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.", 33 highlight: null, 34 isHashable: true, 35 offset: { 36 top: null, 37 left: null 38 }, 39 onShow: null, 40 onHide: null, 41 overlay: false, 42 position: 0, // 1-12 follows an analog clock, 0 means centered. 43 title: "Sample title goes here", 44 width: 400, 45 xButton: false // This places a closer "x" button in the top right of the guider. 46 }; 47 48 guiders._htmlSkeleton = [ 49 "<div class='guider'>", 50 " <div class='guider_content'>", 51 " <div class='guider_close'></div>", 52 " <h1 class='guider_title'></h1>", 53 " <p class='guider_description'></p>", 54 " <div class='guider_buttons'>", 55 " </div>", 56 " </div>", 57 " <div class='guider_arrow'>", 58 " </div>", 59 "</div>" 60 ].join(""); 61 62 guiders._arrowSize = 42; // This is the arrow's width and height. 63 guiders._buttonElement = "<a></a>"; 64 guiders._buttonAttributes = {"href": "javascript:void(0);"}; 65 guiders._closeButtonTitle = "Close"; 66 guiders._currentGuiderID = null; 67 guiders._guiders = {}; 68 guiders._lastCreatedGuiderID = null; 69 guiders._nextButtonTitle = "Next"; 70 guiders._offsetNameMapping = { 71 "topLeft": 11, 72 "top": 12, 73 "topRight": 1, 74 "rightTop": 2, 75 "right": 3, 76 "rightBottom": 4, 77 "bottomRight": 5, 78 "bottom": 6, 79 "bottomLeft": 7, 80 "leftBottom": 8, 81 "left": 9, 82 "leftTop": 10 83 }; 84 guiders._windowHeight = 0; 85 86 guiders._addButtons = function(myGuider) { 87 var guiderButtonsContainer = myGuider.elem.find(".guider_buttons"); 88 89 if (myGuider.buttons === null || myGuider.buttons.length === 0) { 90 guiderButtonsContainer.remove(); 91 return; 92 } 93 94 for (var i = myGuider.buttons.length - 1; i >= 0; i--) { 95 var thisButton = myGuider.buttons[i]; 96 var thisButtonElem = $(guiders._buttonElement, $.extend({ 97 "class" : "guider_button", 98 "html" : thisButton.name }, 99 guiders._buttonAttributes, thisButton.html || {})); 100 101 if (typeof thisButton.classString !== "undefined" && thisButton.classString !== null) { 102 thisButtonElem.addClass(thisButton.classString); 103 } 104 105 guiderButtonsContainer.append(thisButtonElem); 106 107 if (thisButton.onclick) { 108 thisButtonElem.bind("click", thisButton.onclick); 109 } else if (!thisButton.onclick && 110 thisButton.name.toLowerCase() === guiders._closeButtonTitle.toLowerCase()) { 111 thisButtonElem.bind("click", function() { guiders.hideAll(); }); 112 } else if (!thisButton.onclick && 113 thisButton.name.toLowerCase() === guiders._nextButtonTitle.toLowerCase()) { 114 thisButtonElem.bind("click", function() { !myGuider.elem.data('locked') && guiders.next(); }); 115 } 116 } 117 118 if (myGuider.buttonCustomHTML !== "") { 119 var myCustomHTML = $(myGuider.buttonCustomHTML); 120 myGuider.elem.find(".guider_buttons").append(myCustomHTML); 121 } 122 123 if (myGuider.buttons.length === 0) { 124 guiderButtonsContainer.remove(); 125 } 126 }; 127 128 guiders._addXButton = function(myGuider) { 129 var xButtonContainer = myGuider.elem.find(".guider_close"); 130 var xButton = $("<div></div>", { 131 "class" : "x_button", 132 "role" : "button" }); 133 xButtonContainer.append(xButton); 134 xButton.click(function() { guiders.hideAll(); }); 135 }; 136 137 guiders._attach = function(myGuider) { 138 if (typeof myGuider !== 'object') { 139 return; 140 } 141 142 var attachTo = $(myGuider.attachTo); 143 144 var myHeight = myGuider.elem.innerHeight(); 145 var myWidth = myGuider.elem.innerWidth(); 146 147 if (myGuider.position === 0 || attachTo.length === 0) { 148 // The guider is positioned in the center of the screen. 149 myGuider.elem.css("position", "fixed"); 150 myGuider.elem.css("top", ($(window).height() - myHeight) / 3 + "px"); 151 myGuider.elem.css("left", ($(window).width() - myWidth) / 2 + "px"); 152 return; 153 } 154 155 // Otherwise, the guider is positioned relative to the attachTo element. 156 var base = attachTo.offset(); 157 var top = base.top; 158 var left = base.left; 159 160 // topMarginOfBody corrects positioning if body has a top margin set on it. 161 var topMarginOfBody = $("body").outerHeight(true) - $("body").outerHeight(false); 162 base -= topMarginOfBody; 163 164 // Now, take into account how the guider should be positioned relative to the attachTo element. 165 // e.g. top left, bottom center, etc. 166 if (guiders._offsetNameMapping[myGuider.position]) { 167 // As an alternative to the clock model, you can also use keywords to position the guider. 168 myGuider.position = guiders._offsetNameMapping[myGuider.position]; 169 } 170 171 var attachToHeight = attachTo.innerHeight(); 172 var attachToWidth = attachTo.innerWidth(); 173 var bufferOffset = 0.9 * guiders._arrowSize; 174 175 // offsetMap follows the form: [height, width] 176 var offsetMap = { 177 1: [-bufferOffset - myHeight, attachToWidth - myWidth], 178 2: [0, bufferOffset + attachToWidth], 179 3: [attachToHeight/2 - myHeight/2, bufferOffset + attachToWidth], 180 4: [attachToHeight - myHeight, bufferOffset + attachToWidth], 181 5: [bufferOffset + attachToHeight, attachToWidth - myWidth], 182 6: [bufferOffset + attachToHeight, attachToWidth/2 - myWidth/2], 183 7: [bufferOffset + attachToHeight, 0], 184 8: [attachToHeight - myHeight, -myWidth - bufferOffset], 185 9: [attachToHeight/2 - myHeight/2, -myWidth - bufferOffset], 186 10: [0, -myWidth - bufferOffset], 187 11: [-bufferOffset - myHeight, 0], 188 12: [-bufferOffset - myHeight, attachToWidth/2 - myWidth/2] 189 }; 190 var offset = offsetMap[myGuider.position]; 191 top += offset[0]; 192 left += offset[1]; 193 194 var positionType = "absolute"; 195 // If the element you are attaching to is position: fixed, then we will make the guider 196 // position: fixed as well. 197 if (attachTo.css("position") == "fixed") { 198 positionType = "fixed"; 199 top -= $(window).scrollTop(); 200 left -= $(window).scrollLeft(); 201 } 202 203 // If you specify an additional offset parameter when you create the guider, it gets added here. 204 if (myGuider.offset.top !== null) { 205 top += myGuider.offset.top; 206 } 207 if (myGuider.offset.left !== null) { 208 left += myGuider.offset.left; 209 } 210 211 // Finally, set the style of the guider and return it! 212 return myGuider.elem.css({ 213 "position": positionType, 214 "top": top, 215 "left": left 216 }); 217 }; 218 219 guiders._guiderById = function(id) { 220 if (typeof guiders._guiders[id] === "undefined") { 221 throw "Cannot find guider with id " + id; 222 } 223 return guiders._guiders[id]; 224 }; 225 226 guiders._showOverlay = function() { 227 $("#guider_overlay").fadeIn("fast", function(){ 228 if (this.style.removeAttribute) { 229 this.style.removeAttribute("filter"); 230 } 231 }); 232 // This callback is needed to fix an IE opacity bug. 233 // See also: 234 // http://www.kevinleary.net/jquery-fadein-fadeout-problems-in-internet-explorer/ 235 }; 236 237 guiders._highlightElement = function(selector) { 238 $(selector).addClass('guider_highlight'); 239 }; 240 241 guiders._dehighlightElement = function(selector) { 242 $(selector).removeClass('guider_highlight'); 243 }; 244 245 guiders._hideOverlay = function() { 246 $("#guider_overlay").fadeOut("fast"); 247 }; 248 249 guiders._initializeOverlay = function() { 250 if ($("#guider_overlay").length === 0) { 251 $("<div id=\"guider_overlay\"></div>").hide().appendTo("body"); 252 } 253 }; 254 255 guiders._styleArrow = function(myGuider) { 256 var position = myGuider.position || 0; 257 if (!position) { 258 return; 259 } 260 var myGuiderArrow = $(myGuider.elem.find(".guider_arrow")); 261 var newClass = { 262 1: "guider_arrow_down", 263 2: "guider_arrow_left", 264 3: "guider_arrow_left", 265 4: "guider_arrow_left", 266 5: "guider_arrow_up", 267 6: "guider_arrow_up", 268 7: "guider_arrow_up", 269 8: "guider_arrow_right", 270 9: "guider_arrow_right", 271 10: "guider_arrow_right", 272 11: "guider_arrow_down", 273 12: "guider_arrow_down" 274 }; 275 myGuiderArrow.addClass(newClass[position]); 276 277 var myHeight = myGuider.elem.innerHeight(); 278 var myWidth = myGuider.elem.innerWidth(); 279 var arrowOffset = guiders._arrowSize / 2; 280 var positionMap = { 281 1: ["right", arrowOffset], 282 2: ["top", arrowOffset], 283 3: ["top", myHeight/2 - arrowOffset], 284 4: ["bottom", arrowOffset], 285 5: ["right", arrowOffset], 286 6: ["left", myWidth/2 - arrowOffset], 287 7: ["left", arrowOffset], 288 8: ["bottom", arrowOffset], 289 9: ["top", myHeight/2 - arrowOffset], 290 10: ["top", arrowOffset], 291 11: ["left", arrowOffset], 292 12: ["left", myWidth/2 - arrowOffset] 293 }; 294 var position = positionMap[myGuider.position]; 295 myGuiderArrow.css(position[0], position[1] + "px"); 296 }; 297 298 /** 299 * One way to show a guider to new users is to direct new users to a URL such as 300 * http://www.mysite.com/myapp#guider=welcome 301 * 302 * This can also be used to run guiders on multiple pages, by redirecting from 303 * one page to another, with the guider id in the hash tag. 304 * 305 * Alternatively, if you use a session variable or flash messages after sign up, 306 * you can add selectively add JavaScript to the page: "guiders.show('first');" 307 */ 308 guiders._showIfHashed = function(myGuider) { 309 var GUIDER_HASH_TAG = "guider="; 310 var hashIndex = window.location.hash.indexOf(GUIDER_HASH_TAG); 311 if (hashIndex !== -1) { 312 var hashGuiderId = window.location.hash.substr(hashIndex + GUIDER_HASH_TAG.length); 313 if (myGuider.id.toLowerCase() === hashGuiderId.toLowerCase()) { 314 // Success! 315 guiders.show(myGuider.id); 316 } 317 } 318 }; 319 320 guiders.reposition = function() { 321 var currentGuider = guiders._guiders[guiders._currentGuiderID]; 322 guiders._attach(currentGuider); 323 }; 324 325 guiders.next = function() { 326 var currentGuider = guiders._guiders[guiders._currentGuiderID]; 327 if (typeof currentGuider === "undefined") { 328 return; 329 } 330 currentGuider.elem.data('locked', true); 331 332 var nextGuiderId = currentGuider.next || null; 333 if (nextGuiderId !== null && nextGuiderId !== "") { 334 var myGuider = guiders._guiderById(nextGuiderId); 335 var omitHidingOverlay = myGuider.overlay ? true : false; 336 guiders.hideAll(omitHidingOverlay, true); 337 if (currentGuider && currentGuider.highlight) { 338 guiders._dehighlightElement(currentGuider.highlight); 339 } 340 guiders.show(nextGuiderId); 341 } 342 }; 343 344 guiders.createGuider = function(passedSettings) { 345 if (passedSettings === null || passedSettings === undefined) { 346 passedSettings = {}; 347 } 348 349 // Extend those settings with passedSettings 350 myGuider = $.extend({}, guiders._defaultSettings, passedSettings); 351 myGuider.id = myGuider.id || String(Math.floor(Math.random() * 1000)); 352 353 var guiderElement = $(guiders._htmlSkeleton); 354 myGuider.elem = guiderElement; 355 if (typeof myGuider.classString !== "undefined" && myGuider.classString !== null) { 356 myGuider.elem.addClass(myGuider.classString); 357 } 358 myGuider.elem.css("width", myGuider.width + "px"); 359 360 var guiderTitleContainer = guiderElement.find(".guider_title"); 361 guiderTitleContainer.html(myGuider.title); 362 363 guiderElement.find(".guider_description").html(myGuider.description); 364 365 guiders._addButtons(myGuider); 366 367 if (myGuider.xButton) { 368 guiders._addXButton(myGuider); 369 } 370 371 guiderElement.hide(); 372 guiderElement.appendTo("body"); 373 guiderElement.attr("id", myGuider.id); 374 375 // Ensure myGuider.attachTo is a jQuery element. 376 if (typeof myGuider.attachTo !== "undefined" && myGuider !== null) { 377 guiders._attach(myGuider) && guiders._styleArrow(myGuider); 378 } 379 380 guiders._initializeOverlay(); 381 382 guiders._guiders[myGuider.id] = myGuider; 383 guiders._lastCreatedGuiderID = myGuider.id; 384 385 /** 386 * If the URL of the current window is of the form 387 * http://www.myurl.com/mypage.html#guider=id 388 * then show this guider. 389 */ 390 if (myGuider.isHashable) { 391 guiders._showIfHashed(myGuider); 392 } 393 394 return guiders; 395 }; 396 397 guiders.hideAll = function(omitHidingOverlay, next) { 398 next = next || false; 399 400 $(".guider:visible").each(function(index, elem){ 401 var myGuider = guiders._guiderById($(elem).attr('id')); 402 if (myGuider.onHide) { 403 myGuider.onHide(myGuider, next); 404 } 405 }); 406 $(".guider").fadeOut("fast"); 407 var currentGuider = guiders._guiders[guiders._currentGuiderID]; 408 if (currentGuider && currentGuider.highlight) { 409 guiders._dehighlightElement(currentGuider.highlight); 410 } 411 if (typeof omitHidingOverlay !== "undefined" && omitHidingOverlay === true) { 412 // do nothing for now 413 } else { 414 guiders._hideOverlay(); 415 } 416 return guiders; 417 }; 418 419 guiders.show = function(id) { 420 if (!id && guiders._lastCreatedGuiderID) { 421 id = guiders._lastCreatedGuiderID; 422 } 423 424 var myGuider = guiders._guiderById(id); 425 if (myGuider.overlay) { 426 guiders._showOverlay(); 427 // if guider is attached to an element, make sure it's visible 428 if (myGuider.highlight) { 429 guiders._highlightElement(myGuider.highlight); 430 } 431 } 432 433 // You can use an onShow function to take some action before the guider is shown. 434 if (myGuider.onShow) { 435 myGuider.onShow(myGuider); 436 } 437 guiders._attach(myGuider); 438 myGuider.elem.fadeIn("fast").data("locked", false); 439 440 guiders._currentGuiderID = id; 441 442 var windowHeight = guiders._windowHeight = $(window).height(); 443 var scrollHeight = $(window).scrollTop(); 444 var guiderOffset = myGuider.elem.offset(); 445 var guiderElemHeight = myGuider.elem.height(); 446 447 var isGuiderBelow = (scrollHeight + windowHeight < guiderOffset.top + guiderElemHeight); /* we will need to scroll down */ 448 var isGuiderAbove = (guiderOffset.top < scrollHeight); /* we will need to scroll up */ 449 450 if (myGuider.autoFocus && (isGuiderBelow || isGuiderAbove)) { 451 // Sometimes the browser won't scroll if the person just clicked, 452 // so let's do this in a setTimeout. 453 setTimeout(guiders.scrollToCurrent, 10); 454 } 455 456 $(myGuider.elem).trigger("guiders.show"); 457 458 return guiders; 459 }; 460 461 guiders.scrollToCurrent = function() { 462 var currentGuider = guiders._guiders[guiders._currentGuiderID]; 463 if (typeof currentGuider === "undefined") { 464 return; 465 } 466 467 var windowHeight = guiders._windowHeight; 468 var scrollHeight = $(window).scrollTop(); 469 var guiderOffset = currentGuider.elem.offset(); 470 var guiderElemHeight = currentGuider.elem.height(); 471 472 // Scroll to the guider's position. 473 var scrollToHeight = Math.round(Math.max(guiderOffset.top + (guiderElemHeight / 2) - (windowHeight / 2), 0)); 474 window.scrollTo(0, scrollToHeight); 475 }; 476 477 // Change the bubble position after browser gets resized 478 var _resizing = undefined; 479 $(window).resize(function() { 480 if (typeof(_resizing) !== "undefined") { 481 clearTimeout(_resizing); // Prevents seizures 482 } 483 _resizing = setTimeout(function() { 484 _resizing = undefined; 485 guiders.reposition(); 486 }, 20); 487 }); 488 489 return guiders; 490 }).call(this, jQuery);
title
Description
Body
title
Description
Body
title
Description
Body
title
Body
Generated: Fri Nov 28 20:08:37 2014 | Cross-referenced by PHPXref 0.7.1 |