Permalink
Browse files

Add ability to define introductions without focusing on elements + fi…

…x IE8 issue in programmatic version
  • Loading branch information...
1 parent 44852a1 commit be96db02967e9144695e7e9b99ceaa1a11718b4f @afshinm afshinm committed Mar 25, 2014
Showing with 234 additions and 37 deletions.
  1. +1 −0 example/index.html
  2. +3 −0 example/programmatic/index.html
  3. +113 −0 example/withoutElement/index.html
  4. +84 −13 intro.js
  5. +7 −0 introjs.css
  6. +25 −23 minified/intro.min.js
  7. +1 −1 minified/introjs.min.css
View
@@ -29,6 +29,7 @@ <h3 class="muted">Examples</h3>
<li><a href="RTL/index.html" title='RTL version'>RTL version</a></li>
<li><a href="html-tooltip/index.html" title='HTML in tooltip'>HTML in tooltip</a></li>
<li><a href="custom-class/index.html" title='Custom CSS Class'>Custom CSS Class</a></li>
+ <li><a href="withoutElement/index.html" title='Introduction without focusing on elements'>Introduction without focusing on elements</a></li>
</ul>
</div>
</body>
@@ -74,6 +74,9 @@ <h1 id="step1">Programmatic</h1>
var intro = introJs();
intro.setOptions({
steps: [
+ {
+ intro: "Hello world!"
+ },
{
element: document.querySelector('#step1'),
intro: "This is a tooltip."
@@ -0,0 +1,113 @@
+<!DOCTYPE html>
+<html lang="en">
+ <head>
+ <meta charset="utf-8">
+ <title>Intro without focusing on elements</title>
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
+ <meta name="description" content="Intro.js - Better introductions for websites and features with a step-by-step guide for your projects.">
+ <meta name="author" content="Afshin Mehrabani (@afshinmeh) in usabli.ca group">
+
+ <!-- styles -->
+ <link href="../assets/css/bootstrap.min.css" rel="stylesheet">
+ <link href="../assets/css/demo.css" rel="stylesheet">
+
+ <!-- Add IntroJs styles -->
+ <link href="../../introjs.css" rel="stylesheet">
+
+ <link href="../assets/css/bootstrap-responsive.min.css" rel="stylesheet">
+ </head>
+
+ <body>
+
+ <div class="container-narrow">
+
+ <div class="masthead">
+ <ul id="step5" class="nav nav-pills pull-right">
+ <li><a href="https://github.com/usablica/intro.js/tags"><i class='icon-black icon-download-alt'></i> Download</a></li>
+ <li><a href="https://github.com/usablica/intro.js">Github</a></li>
+ <li><a href="https://twitter.com/usablica">@usablica</a></li>
+ </ul>
+ <h3 class="muted">Intro.js</h3>
+ </div>
+
+ <hr>
+
+ <div class="jumbotron">
+ <h1 id="step1">Without Element</h1>
+ <p id="step4" class="lead">This example shows the introductions without focusing on elements.</p>
+ <a class="btn btn-large btn-success" href="javascript:void(0);" onclick="startIntro();">Show me how</a>
+ </div>
+
+ <hr>
+
+ <div class="row-fluid marketing">
+ <div id="step2" class="span6">
+ <h4>Section One</h4>
+ <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Duis mollis augue a neque cursus ac blandit orci faucibus. Phasellus nec metus purus.</p>
+
+ <h4>Section Two</h4>
+ <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Duis mollis augue a neque cursus ac blandit orci faucibus. Phasellus nec metus purus.</p>
+
+ <h4>Section Three</h4>
+ <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Duis mollis augue a neque cursus ac blandit orci faucibus. Phasellus nec metus purus.</p>
+ </div>
+
+ <div id="step3" class="span6">
+ <h4>Section Four</h4>
+ <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Duis mollis augue a neque cursus ac blandit orci faucibus. Phasellus nec metus purus.</p>
+
+
+ <h4>Section Five</h4>
+ <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Duis mollis augue a neque cursus ac blandit orci faucibus. Phasellus nec metus purus.</p>
+
+ <h4>Section Six</h4>
+ <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Duis mollis augue a neque cursus ac blandit orci faucibus. Phasellus nec metus purus.</p>
+ </div>
+ </div>
+
+ <hr>
+
+ </div>
+ <script type="text/javascript" src="../../intro.js"></script>
+ <script type="text/javascript">
+ function startIntro(){
+ var intro = introJs();
+ intro.setOptions({
+ steps: [
+ {
+ intro: "Hello world!"
+ },
+ {
+ intro: "You <b>don't need</b> to define element to focus, this is a floating tooltip."
+ },
+ {
+ element: document.querySelector('#step1'),
+ intro: "This is a tooltip."
+ },
+ {
+ element: document.querySelectorAll('#step2')[0],
+ intro: "Ok, wasn't that fun?",
+ position: 'right'
+ },
+ {
+ element: '#step3',
+ intro: 'More features, more fun.',
+ position: 'left'
+ },
+ {
+ element: '#step4',
+ intro: "Another step.",
+ position: 'bottom'
+ },
+ {
+ element: '#step5',
+ intro: 'Get it, use it.'
+ }
+ ]
+ });
+
+ intro.start();
+ }
+ </script>
+ </body>
+</html>
View
@@ -1,5 +1,5 @@
/**
- * Intro.js v0.7.1
+ * Intro.js v0.8.0
* https://github.com/usablica/intro.js
* MIT licensed
*
@@ -19,7 +19,7 @@
}
} (this, function (exports) {
//Default config/variables
- var VERSION = '0.7.1';
+ var VERSION = '0.8.0';
/**
* IntroJs main class
@@ -85,6 +85,21 @@
currentItem.element = document.querySelector(currentItem.element);
}
+ //intro without element
+ if (typeof(currentItem.element) === 'undefined' || currentItem.element == null) {
+ var floatingElementQuery = document.querySelector(".introjsFloatingElement");
+
+ if (floatingElementQuery == null) {
+ floatingElementQuery = document.createElement('div');
+ floatingElementQuery.className = 'introjsFloatingElement';
+
+ document.body.appendChild(floatingElementQuery);
+ }
+
+ currentItem.element = floatingElementQuery;
+ currentItem.position = 'floating';
+ }
+
if (currentItem.element != null) {
introItems.push(currentItem);
}
@@ -215,7 +230,7 @@
* @method _cloneObject
*/
function _cloneObject(object) {
- if (object == null || typeof (object) != 'object' || object.hasOwnProperty("nodeName") === true || typeof (object.nodeType) != 'undefined') {
+ if (object == null || typeof (object) != 'object' || typeof (object.nodeType) != 'undefined') {
return object;
}
var temp = {};
@@ -266,6 +281,7 @@
this._introBeforeChangeCallback.call(this, nextStep.element);
}
+ this._direction = 'forward';
@SamyCookie
SamyCookie Mar 25, 2014

@afshinm
should this property be affected before _introBeforeChangeCallback function ? I have a use case which needs this property there.
example #143

@afshinm
afshinm Mar 25, 2014 Member

Ops, yeah you're right. I will fix it.

@SamyCookie
SamyCookie Mar 25, 2014

Thanks a lot for that ! :)
(and thanks for your great software btw !)

@afshinm
afshinm Mar 25, 2014 Member

No problem dude. Fixed!

_showElement.call(this, nextStep);
}
@@ -285,6 +301,7 @@
this._introBeforeChangeCallback.call(this, nextStep.element);
}
+ this._direction = 'backward';
@SamyCookie
SamyCookie Mar 25, 2014

@afshinm
same as my previous comment

_showElement.call(this, nextStep);
}
@@ -298,22 +315,32 @@
function _exitIntro(targetElement) {
//remove overlay layer from the page
var overlayLayer = targetElement.querySelector('.introjs-overlay');
+
//return if intro already completed or skipped
if (overlayLayer == null) {
return;
}
+
//for fade-out animation
overlayLayer.style.opacity = 0;
setTimeout(function () {
if (overlayLayer.parentNode) {
overlayLayer.parentNode.removeChild(overlayLayer);
}
}, 500);
+
//remove all helper layers
var helperLayer = targetElement.querySelector('.introjs-helperLayer');
if (helperLayer) {
helperLayer.parentNode.removeChild(helperLayer);
}
+
+ //remove intro floating element
+ var floatingElement = document.querySelector('.introjsFloatingElement');
+ if (floatingElement) {
+ floatingElement.parentNode.removeChild(floatingElement);
+ }
+
//remove `introjs-showElement` class from the element
var showElement = document.querySelector('.introjs-showElement');
if (showElement) {
@@ -327,12 +354,14 @@
fixParents[i].className = fixParents[i].className.replace(/introjs-fixParent/g, '').replace(/^\s+|\s+$/g, '');
};
}
+
//clean listeners
if (window.removeEventListener) {
window.removeEventListener('keydown', this._onKeyDown, true);
} else if (document.detachEvent) { //IE
document.detachEvent('onkeydown', this._onKeyDown);
}
+
//set the step to zero
this._currentStep = undefined;
}
@@ -346,12 +375,21 @@
* @param {Object} tooltipLayer
* @param {Object} arrowLayer
*/
- function _placeTooltip(targetElement, tooltipLayer, arrowLayer) {
+ function _placeTooltip(targetElement, tooltipLayer, arrowLayer, helperNumberLayer) {
//reset the old style
- tooltipLayer.style.top = null;
- tooltipLayer.style.right = null;
- tooltipLayer.style.bottom = null;
- tooltipLayer.style.left = null;
+ tooltipLayer.style.top = null;
+ tooltipLayer.style.right = null;
+ tooltipLayer.style.bottom = null;
+ tooltipLayer.style.left = null;
+ tooltipLayer.style.marginLeft = null;
+ tooltipLayer.style.marginTop = null;
+
+ arrowLayer.style.display = 'inherit';
+
+ if (typeof(helperNumberLayer) != 'undefined' && helperNumberLayer != null) {
+ helperNumberLayer.style.top = null;
+ helperNumberLayer.style.left = null;
+ }
//prevent error when `this._currentStep` is undefined
if (!this._introItems[this._currentStep]) return;
@@ -389,6 +427,23 @@
tooltipLayer.style.right = (_getOffset(targetElement).width + 20) + 'px';
arrowLayer.className = 'introjs-arrow right';
break;
+ case 'floating':
+ arrowLayer.style.display = 'none';
+
+ //we have to adjust the top and left of layer manually for intro items without element{
+ var tooltipOffset = _getOffset(tooltipLayer);
+
+ tooltipLayer.style.left = '50%';
+ tooltipLayer.style.top = '50%';
+ tooltipLayer.style.marginLeft = '-' + (tooltipOffset.width / 2) + 'px';
+ tooltipLayer.style.marginTop = '-' + (tooltipOffset.height / 2) + 'px';
+
+ if (typeof(helperNumberLayer) != 'undefined' && helperNumberLayer != null) {
+ helperNumberLayer.style.left = '-' + ((tooltipOffset.width / 2) + 18) + 'px';
+ helperNumberLayer.style.top = '-' + ((tooltipOffset.height / 2) + 18) + 'px';
+ }
+
+ break;
case 'bottom':
// Bottom going to follow the default behavior
default:
@@ -410,10 +465,17 @@
//prevent error when `this._currentStep` in undefined
if (!this._introItems[this._currentStep]) return;
- var elementPosition = _getOffset(this._introItems[this._currentStep].element);
+ var currentElement = this._introItems[this._currentStep];
+ var elementPosition = _getOffset(currentElement.element);
+
+ var widthHeightPadding = 10;
+ if (currentElement.position == 'floating') {
+ widthHeightPadding = 0;
+ }
+
//set new position to helper layer
- helperLayer.setAttribute('style', 'width: ' + (elementPosition.width + 10) + 'px; ' +
- 'height:' + (elementPosition.height + 10) + 'px; ' +
+ helperLayer.setAttribute('style', 'width: ' + (elementPosition.width + widthHeightPadding) + 'px; ' +
+ 'height:' + (elementPosition.height + widthHeightPadding) + 'px; ' +
'top:' + (elementPosition.top - 5) + 'px;' +
'left: ' + (elementPosition.left - 5) + 'px;');
}
@@ -448,6 +510,14 @@
//hide the tooltip
oldtooltipContainer.style.opacity = 0;
+ if (oldHelperNumberLayer != null) {
+ var lastIntroItem = this._introItems[(targetElement.step - 2 >= 0 ? targetElement.step - 2 : 0)];
+
+ if (lastIntroItem != null && (this._direction == 'forward' && lastIntroItem.position == 'floating') || (this._direction == 'backward' && targetElement.position == 'floating')) {
+ oldHelperNumberLayer.style.opacity = 0;
+ }
+ }
+
//set new position to helper layer
_setHelperLayerPosition.call(self, oldHelperLayer);
@@ -474,14 +544,15 @@
//set current tooltip text
oldtooltipLayer.innerHTML = targetElement.intro;
//set the tooltip position
- _placeTooltip.call(self, targetElement.element, oldtooltipContainer, oldArrowLayer);
+ _placeTooltip.call(self, targetElement.element, oldtooltipContainer, oldArrowLayer, oldHelperNumberLayer);
//change active bullet
oldHelperLayer.querySelector('.introjs-bullets li > a.active').className = '';
oldHelperLayer.querySelector('.introjs-bullets li > a[data-stepnumber="' + targetElement.step + '"]').className = 'active';
//show the tooltip
oldtooltipContainer.style.opacity = 1;
+ oldHelperNumberLayer.style.opacity = 1;
}, 350);
} else {
@@ -605,7 +676,7 @@
tooltipLayer.appendChild(buttonsLayer);
//set proper position
- _placeTooltip.call(self, targetElement.element, tooltipLayer, arrowLayer);
+ _placeTooltip.call(self, targetElement.element, tooltipLayer, arrowLayer, helperNumberLayer);
}
if (this._currentStep == 0 && this._introItems.length > 1) {
View
@@ -245,4 +245,11 @@
}
.introjs-bullets ul li a.active {
background: #999;
+}
+.introjsFloatingElement {
+ position: absolute;
+ height: 0;
+ width: 0;
+ left: 50%;
+ top: 50%;
}
Oops, something went wrong.

0 comments on commit be96db0

Please sign in to comment.