|
1 | 1 | /**
|
2 | 2 | * jquery-bootstrap-scrolling-tabs
|
3 |
| - * @version v2.3.1 |
| 3 | + * @version v2.4.0 |
4 | 4 | * @link https://github.com/mikejacobson/jquery-bootstrap-scrolling-tabs
|
5 | 5 | * @author Mike Jacobson <michaeljjacobson1@gmail.com>
|
6 | 6 | * @license MIT License, http://www.opensource.org/licenses/MIT
|
|
176 | 176 | * default scrtabs-tab-scroll-arrow classes.
|
177 | 177 | * This plunk shows it working with svg icons:
|
178 | 178 | * http://plnkr.co/edit/2MdZCAnLyeU40shxaol3?p=preview
|
| 179 | + * |
| 180 | + * When using this option, you can also mark a child |
| 181 | + * element within the arrow content as the click target |
| 182 | + * if you don't want the entire content to be |
| 183 | + * clickable. You do that my adding the CSS class |
| 184 | + * 'scrtabs-click-target' to the element that should |
| 185 | + * be clickable, like so: |
| 186 | + * |
| 187 | + * leftArrowContent: [ |
| 188 | + * '<div class="scrtabs-tab-scroll-arrow scrtabs-tab-scroll-arrow-left">', |
| 189 | + * ' <button class="scrtabs-click-target" type="button">', |
| 190 | + * ' <i class="custom-chevron-left"></i>', |
| 191 | + * ' </button>', |
| 192 | + * '</div>' |
| 193 | + * ].join(''), |
| 194 | + * rightArrowContent: [ |
| 195 | + * '<div class="scrtabs-tab-scroll-arrow scrtabs-tab-scroll-arrow-right">', |
| 196 | + * ' <button class="scrtabs-click-target" type="button">', |
| 197 | + * ' <i class="custom-chevron-right"></i>', |
| 198 | + * ' </button>', |
| 199 | + * '</div>' |
| 200 | + * ].join('') |
| 201 | + * |
179 | 202 | * enableRtlSupport:
|
180 | 203 | * set to true if you want your site to support
|
181 | 204 | * right-to-left languages. If true, the plugin will
|
|
279 | 302 | CSS_CLASSES: {
|
280 | 303 | BOOTSTRAP4: 'scrtabs-bootstrap4',
|
281 | 304 | RTL: 'scrtabs-rtl',
|
282 |
| - SCROLL_ARROW_DISABLE: 'scrtabs-disable' |
| 305 | + SCROLL_ARROW_CLICK_TARGET: 'scrtabs-click-target', |
| 306 | + SCROLL_ARROW_DISABLE: 'scrtabs-disable', |
| 307 | + SCROLL_ARROW_WITH_CLICK_TARGET: 'scrtabs-with-click-target' |
283 | 308 | },
|
284 | 309 |
|
285 | 310 | SLIDE_DIRECTION: {
|
|
346 | 371 | p.initElements = function (options) {
|
347 | 372 | var ehd = this;
|
348 | 373 |
|
349 |
| - ehd.setElementReferences(); |
| 374 | + ehd.setElementReferences(options); |
350 | 375 | ehd.setEventListeners(options);
|
351 | 376 | };
|
352 | 377 |
|
|
451 | 476 | return actionsTaken;
|
452 | 477 | };
|
453 | 478 |
|
454 |
| - p.setElementReferences = function () { |
| 479 | + p.setElementReferences = function (settings) { |
455 | 480 | var ehd = this,
|
456 | 481 | stc = ehd.stc,
|
457 | 482 | $tabsContainer = stc.$tabsContainer,
|
458 | 483 | $leftArrow,
|
459 |
| - $rightArrow; |
| 484 | + $rightArrow, |
| 485 | + $leftArrowClickTarget, |
| 486 | + $rightArrowClickTarget; |
460 | 487 |
|
461 | 488 | stc.isNavPills = false;
|
462 | 489 |
|
|
472 | 499 | $leftArrow = stc.$fixedContainer.prev();
|
473 | 500 | $rightArrow = stc.$fixedContainer.next();
|
474 | 501 |
|
| 502 | + // if we have custom arrow content, we might have a click target defined |
| 503 | + if (settings.leftArrowContent) { |
| 504 | + $leftArrowClickTarget = $leftArrow.find('.' + CONSTANTS.CSS_CLASSES.SCROLL_ARROW_CLICK_TARGET); |
| 505 | + } |
| 506 | + |
| 507 | + if (settings.rightArrowContent) { |
| 508 | + $rightArrowClickTarget = $rightArrow.find('.' + CONSTANTS.CSS_CLASSES.SCROLL_ARROW_CLICK_TARGET); |
| 509 | + } |
| 510 | + |
| 511 | + if ($leftArrowClickTarget && $leftArrowClickTarget.length) { |
| 512 | + $leftArrow.addClass(CONSTANTS.CSS_CLASSES.SCROLL_ARROW_WITH_CLICK_TARGET); |
| 513 | + } else { |
| 514 | + $leftArrowClickTarget = $leftArrow; |
| 515 | + } |
| 516 | + |
| 517 | + if ($rightArrowClickTarget && $rightArrowClickTarget.length) { |
| 518 | + $rightArrow.addClass(CONSTANTS.CSS_CLASSES.SCROLL_ARROW_WITH_CLICK_TARGET); |
| 519 | + } else { |
| 520 | + $rightArrowClickTarget = $rightArrow; |
| 521 | + } |
| 522 | + |
475 | 523 | stc.$movableContainer = $tabsContainer.find('.scrtabs-tabs-movable-container');
|
476 | 524 | stc.$tabsUl = $tabsContainer.find('.nav-tabs');
|
477 | 525 |
|
|
487 | 535 | stc.$tabsLiCollection = stc.$tabsUl.find('> li');
|
488 | 536 |
|
489 | 537 | stc.$slideLeftArrow = stc.reverseScroll ? $leftArrow : $rightArrow;
|
| 538 | + stc.$slideLeftArrowClickTarget = stc.reverseScroll ? $leftArrowClickTarget : $rightArrowClickTarget; |
490 | 539 | stc.$slideRightArrow = stc.reverseScroll ? $rightArrow : $leftArrow;
|
| 540 | + stc.$slideRightArrowClickTarget = stc.reverseScroll ? $rightArrowClickTarget : $leftArrowClickTarget; |
491 | 541 | stc.$scrollArrows = stc.$slideLeftArrow.add(stc.$slideRightArrow);
|
492 | 542 |
|
493 | 543 | stc.$win = $(window);
|
|
515 | 565 | ehd.listenForTouchEvents();
|
516 | 566 | }
|
517 | 567 |
|
518 |
| - stc.$slideLeftArrow |
| 568 | + stc.$slideLeftArrowClickTarget |
519 | 569 | .off('.scrtabs')
|
520 | 570 | .on(ev.MOUSEDOWN, function (e) { evh.handleMousedownOnSlideMovContainerLeftArrow.call(evh, e); })
|
521 | 571 | .on(ev.MOUSEUP, function (e) { evh.handleMouseupOnSlideMovContainerLeftArrow.call(evh, e); })
|
522 | 572 | .on(ev.CLICK, function (e) { evh.handleClickOnSlideMovContainerLeftArrow.call(evh, e); });
|
523 | 573 |
|
524 |
| - stc.$slideRightArrow |
| 574 | + stc.$slideRightArrowClickTarget |
525 | 575 | .off('.scrtabs')
|
526 | 576 | .on(ev.MOUSEDOWN, function (e) { evh.handleMousedownOnSlideMovContainerRightArrow.call(evh, e); })
|
527 | 577 | .on(ev.MOUSEUP, function (e) { evh.handleMouseupOnSlideMovContainerRightArrow.call(evh, e); })
|
|
655 | 705 | var evh = this,
|
656 | 706 | stc = evh.stc;
|
657 | 707 |
|
658 |
| - stc.$slideLeftArrow.data(CONSTANTS.DATA_KEY_IS_MOUSEDOWN, true); |
| 708 | + stc.$slideLeftArrowClickTarget.data(CONSTANTS.DATA_KEY_IS_MOUSEDOWN, true); |
659 | 709 | stc.scrollMovement.continueSlideMovableContainerLeft();
|
660 | 710 | };
|
661 | 711 |
|
662 | 712 | p.handleMousedownOnSlideMovContainerRightArrow = function () {
|
663 | 713 | var evh = this,
|
664 | 714 | stc = evh.stc;
|
665 | 715 |
|
666 |
| - stc.$slideRightArrow.data(CONSTANTS.DATA_KEY_IS_MOUSEDOWN, true); |
| 716 | + stc.$slideRightArrowClickTarget.data(CONSTANTS.DATA_KEY_IS_MOUSEDOWN, true); |
667 | 717 | stc.scrollMovement.continueSlideMovableContainerRight();
|
668 | 718 | };
|
669 | 719 |
|
670 | 720 | p.handleMouseupOnSlideMovContainerLeftArrow = function () {
|
671 | 721 | var evh = this,
|
672 | 722 | stc = evh.stc;
|
673 | 723 |
|
674 |
| - stc.$slideLeftArrow.data(CONSTANTS.DATA_KEY_IS_MOUSEDOWN, false); |
| 724 | + stc.$slideLeftArrowClickTarget.data(CONSTANTS.DATA_KEY_IS_MOUSEDOWN, false); |
675 | 725 | };
|
676 | 726 |
|
677 | 727 | p.handleMouseupOnSlideMovContainerRightArrow = function () {
|
678 | 728 | var evh = this,
|
679 | 729 | stc = evh.stc;
|
680 | 730 |
|
681 |
| - stc.$slideRightArrow.data(CONSTANTS.DATA_KEY_IS_MOUSEDOWN, false); |
| 731 | + stc.$slideRightArrowClickTarget.data(CONSTANTS.DATA_KEY_IS_MOUSEDOWN, false); |
682 | 732 | };
|
683 | 733 |
|
684 | 734 | p.handleWindowResize = function () {
|
|
714 | 764 |
|
715 | 765 | setTimeout(function() {
|
716 | 766 | if (stc.movableContainerLeftPos <= smv.getMinPos() ||
|
717 |
| - !stc.$slideLeftArrow.data(CONSTANTS.DATA_KEY_IS_MOUSEDOWN)) { |
| 767 | + !stc.$slideLeftArrowClickTarget.data(CONSTANTS.DATA_KEY_IS_MOUSEDOWN)) { |
718 | 768 | return;
|
719 | 769 | }
|
720 | 770 |
|
|
730 | 780 |
|
731 | 781 | setTimeout(function() {
|
732 | 782 | if (stc.movableContainerLeftPos >= 0 ||
|
733 |
| - !stc.$slideRightArrow.data(CONSTANTS.DATA_KEY_IS_MOUSEDOWN)) { |
| 783 | + !stc.$slideRightArrowClickTarget.data(CONSTANTS.DATA_KEY_IS_MOUSEDOWN)) { |
734 | 784 | return;
|
735 | 785 | }
|
736 | 786 |
|
|
879 | 929 | p.scrollToActiveTab = function () {
|
880 | 930 | var smv = this,
|
881 | 931 | stc = smv.stc,
|
882 |
| - RIGHT_OFFSET_BUFFER = 20, |
883 | 932 | $activeTab,
|
884 | 933 | $activeTabAnchor,
|
885 | 934 | activeTabLeftPos,
|
|
905 | 954 | return;
|
906 | 955 | }
|
907 | 956 |
|
| 957 | + rightScrollArrowWidth = stc.$slideRightArrow.outerWidth(); |
| 958 | + |
908 | 959 | /**
|
909 | 960 | * @author poletaew
|
910 | 961 | * We need relative offset (depends on $fixedContainer), don't absolute
|
911 | 962 | */
|
912 | 963 | activeTabLeftPos = $activeTab.offset().left - stc.$fixedContainer.offset().left;
|
913 | 964 | activeTabRightPos = activeTabLeftPos + $activeTab.outerWidth();
|
914 | 965 |
|
915 |
| - rightArrowLeftPos = stc.fixedContainerWidth - RIGHT_OFFSET_BUFFER; |
| 966 | + rightArrowLeftPos = stc.fixedContainerWidth - rightScrollArrowWidth; |
916 | 967 |
|
917 | 968 | if (stc.rtl) {
|
918 | 969 | leftScrollArrowWidth = stc.$slideLeftArrow.outerWidth();
|
|
922 | 973 | smv.slideMovableContainerToLeftPos();
|
923 | 974 | return true;
|
924 | 975 | } else { // active tab off right side
|
925 |
| - rightScrollArrowWidth = stc.$slideRightArrow.outerWidth(); |
926 | 976 | if (activeTabRightPos > rightArrowLeftPos) {
|
927 |
| - stc.movableContainerLeftPos += (activeTabRightPos - rightArrowLeftPos) + rightScrollArrowWidth + RIGHT_OFFSET_BUFFER; |
| 977 | + stc.movableContainerLeftPos += (activeTabRightPos - rightArrowLeftPos) + (2 * rightScrollArrowWidth); |
928 | 978 | smv.slideMovableContainerToLeftPos();
|
929 | 979 | return true;
|
930 | 980 | }
|
931 | 981 | }
|
932 | 982 | } else {
|
933 | 983 | if (activeTabRightPos > rightArrowLeftPos) { // active tab off right side
|
934 |
| - rightScrollArrowWidth = stc.$slideRightArrow.outerWidth(); |
935 | 984 | stc.movableContainerLeftPos -= (activeTabRightPos - rightArrowLeftPos + rightScrollArrowWidth);
|
936 | 985 | smv.slideMovableContainerToLeftPos();
|
937 | 986 | return true;
|
|
1138 | 1187 | $movableContainer = $('<div class="scrtabs-tabs-movable-container"></div>');
|
1139 | 1188 |
|
1140 | 1189 | if (settings.disableScrollArrowsOnFullyScrolled) {
|
1141 |
| - $leftArrow.add($rightArrow).addClass('scrtabs-disable'); |
| 1190 | + $leftArrow.add($rightArrow).addClass(CONSTANTS.CSS_CLASSES.SCROLL_ARROW_DISABLE); |
1142 | 1191 | }
|
1143 | 1192 |
|
1144 | 1193 | return $tabsContainer
|
|
0 commit comments