2017-06-02 12 views
1


最初の2つの関数で引数としてjQueryを渡す必要があります。そうでないと、initialiseStickyのコードは機能しません。関数内でjQuery要素を渡す方法 - 構文

:私はすべてのコードと、機能を編集した前

jQuery(function($) { 
    console.log('document ready- sticky'); 
    initialiseSticky($); 
}); 
$(document).ajaxComplete(function ($) { 
    console.log('ajax complete- sticky'); 
    initialiseSticky($); 

}(jQuery)); 

function initialiseSticky($) { 
//my code 
} 

...
それはdocument.readyのための作業を行いますがないajaxCompleteのために、私の構文は、おそらくすべてではない良いですが、以下に、このように見えました

!function ($) { 
    //my code (now initialiseSticky function) 
}(jQuery) 

EDIT:それが役立つならば、私は知らないが、ここではこの問題があるウェブサイトは次のとおりです。http://lesdeuxvagues.com/demoは、メニューを見て、それは粘着性の状態です。これまでのところ、通常のページロードでは動作しますが、ajaxでは動作しません。


EDIT 2: はここに残りのコードです:

function initialiseSticky($) { 

    console.log('initialise- sticky'); 
/** 
* Sticky module. 
* @module foundation.sticky 
* @requires foundation.util.triggers 
* @requires foundation.util.mediaQuery 
*/ 

class Sticky { 
    /** 
    * Creates a new instance of a sticky thing. 
    * @class 
    * @param {jQuery} element - jQuery object to make sticky. 
    * @param {Object} options - options object passed when creating the element programmatically. 
    */ 
    constructor(element, options) { 
    this.$element = element; 
    this.options = $.extend({}, Sticky.defaults, this.$element.data(), options); 

    this._init(); 

    Foundation.registerPlugin(this, 'Sticky'); 
    } 

    /** 
    * Initializes the sticky element by adding classes, getting/setting dimensions, breakpoints and attributes 
    * @function 
    * @private 
    */ 
    _init() { 
    var $parent = this.$element.parent('[data-sticky-container]'), 
     id = this.$element[0].id || Foundation.GetYoDigits(6, 'sticky'), 
     _this = this; 

    if (!$parent.length) { 
     this.wasWrapped = true; 
    } 
    this.$container = $parent.length ? $parent : $(this.options.container).wrapInner(this.$element); 
    this.$container.addClass(this.options.containerClass); 

    this.$element.addClass(this.options.stickyClass).attr({ 'data-resize': id, 'data-mutate': id }); 
    if (this.options.anchor !== '') { 
     $('#' + _this.options.anchor).attr({ 'data-mutate': id }); 
    } 

    this.scrollCount = this.options.checkEvery; 
    this.isStuck = false; 
    $(window).one('load.zf.sticky', function(){ 
     //We calculate the container height to have correct values for anchor points offset calculation. 
     _this.containerHeight = _this.$element.css("display") == "none" ? 0 : _this.$element[0].getBoundingClientRect().height; 
     _this.$container.css('height', _this.containerHeight); 
     _this.elemHeight = _this.containerHeight; 
     if(_this.options.anchor !== ''){ 
     _this.$anchor = $('#' + _this.options.anchor); 
     }else{ 
     _this._parsePoints(); 
     } 

     _this._setSizes(function(){ 
     var scroll = window.pageYOffset; 
     _this._calc(false, scroll); 
     //Unstick the element will ensure that proper classes are set. 
     if (!_this.isStuck) { 
      _this._removeSticky((scroll >= _this.topPoint) ? false : true); 
     } 
     }); 
     _this._events(id.split('-').reverse().join('-')); 
    }); 
    } 

    /** 
    * If using multiple elements as anchors, calculates the top and bottom pixel values the sticky thing should stick and unstick on. 
    * @function 
    * @private 
    */ 
    _parsePoints() { 
    var top = this.options.topAnchor == "" ? 1 : this.options.topAnchor, 
     btm = this.options.btmAnchor== "" ? document.documentElement.scrollHeight : this.options.btmAnchor, 
     pts = [top, btm], 
     breaks = {}; 
    for (var i = 0, len = pts.length; i < len && pts[i]; i++) { 
     var pt; 
     if (typeof pts[i] === 'number') { 
     pt = pts[i]; 
     } else { 
     var place = pts[i].split(':'), 
      anchor = $(`#${place[0]}`); 

     pt = anchor.offset().top; 
     if (place[1] && place[1].toLowerCase() === 'bottom') { 
      pt += anchor[0].getBoundingClientRect().height; 
     } 
     } 
     breaks[i] = pt; 
    } 


    this.points = breaks; 
    return; 
    } 

    /** 
    * Adds event handlers for the scrolling element. 
    * @private 
    * @param {String} id - psuedo-random id for unique scroll event listener. 
    */ 
    _events(id) { 
    var _this = this, 
     scrollListener = this.scrollListener = `scroll.zf.${id}`; 
    if (this.isOn) { return; } 
    if (this.canStick) { 
     this.isOn = true; 
     $(window).off(scrollListener) 
       .on(scrollListener, function(e) { 
       if (_this.scrollCount === 0) { 
        _this.scrollCount = _this.options.checkEvery; 
        _this._setSizes(function() { 
        _this._calc(false, window.pageYOffset); 
        }); 
       } else { 
        _this.scrollCount--; 
        _this._calc(false, window.pageYOffset); 
       } 
       }); 
    } 

    this.$element.off('resizeme.zf.trigger') 
       .on('resizeme.zf.trigger', function(e, el) { 
        _this._eventsHandler(id); 
    }); 

    this.$element.on('mutateme.zf.trigger', function (e, el) { 
     _this._eventsHandler(id); 
    }); 

    if(this.$anchor) { 
     this.$anchor.on('mutateme.zf.trigger', function (e, el) { 
      _this._eventsHandler(id); 
     }); 
    } 
    } 

    /** 
    * Handler for events. 
    * @private 
    * @param {String} id - psuedo-random id for unique scroll event listener. 
    */ 
    _eventsHandler(id) { 
     var _this = this, 
     scrollListener = this.scrollListener = `scroll.zf.${id}`; 

     _this._setSizes(function() { 
     _this._calc(false); 
     if (_this.canStick) { 
     if (!_this.isOn) { 
      _this._events(id); 
     } 
     } else if (_this.isOn) { 
     _this._pauseListeners(scrollListener); 
     } 
    }); 
    } 

    /** 
    * Removes event handlers for scroll and change events on anchor. 
    * @fires Sticky#pause 
    * @param {String} scrollListener - unique, namespaced scroll listener attached to `window` 
    */ 
    _pauseListeners(scrollListener) { 
    this.isOn = false; 
    $(window).off(scrollListener); 

    /** 
    * Fires when the plugin is paused due to resize event shrinking the view. 
    * @event Sticky#pause 
    * @private 
    */ 
    this.$element.trigger('pause.zf.sticky'); 
    } 

    /** 
    * Called on every `scroll` event and on `_init` 
    * fires functions based on booleans and cached values 
    * @param {Boolean} checkSizes - true if plugin should recalculate sizes and breakpoints. 
    * @param {Number} scroll - current scroll position passed from scroll event cb function. If not passed, defaults to `window.pageYOffset`. 
    */ 
    _calc(checkSizes, scroll) { 
    if (checkSizes) { this._setSizes(); } 

    if (!this.canStick) { 
     if (this.isStuck) { 
     this._removeSticky(true); 
     } 
     return false; 
    } 

    if (!scroll) { scroll = window.pageYOffset; } 

    if (scroll >= this.topPoint) { 
     if (scroll <= this.bottomPoint) { 
     if (!this.isStuck) { 
      this._setSticky(); 
     } 
     } else { 
     if (this.isStuck) { 
      this._removeSticky(false); 
     } 
     } 
    } else { 
     if (this.isStuck) { 
     this._removeSticky(true); 
     } 
    } 
    } 

    /** 
    * Causes the $element to become stuck. 
    * Adds `position: fixed;`, and helper classes. 
    * @fires Sticky#stuckto 
    * @function 
    * @private 
    */ 
    _setSticky() { 
    var _this = this, 
     stickTo = this.options.stickTo, 
     mrgn = stickTo === 'top' ? 'marginTop' : 'marginBottom', 
     notStuckTo = stickTo === 'top' ? 'bottom' : 'top', 
     css = {}; 

    css[mrgn] = `${this.options[mrgn]}em`; 
    css[stickTo] = 0; 
    css[notStuckTo] = 'auto'; 
    this.isStuck = true; 
    this.$element.removeClass(`is-anchored is-at-${notStuckTo}`) 
       .addClass(`is-stuck is-at-${stickTo}`) 
       .css(css) 
       /** 
        * Fires when the $element has become `position: fixed;` 
        * Namespaced to `top` or `bottom`, e.g. `sticky.zf.stuckto:top` 
        * @event Sticky#stuckto 
        */ 
       .trigger(`sticky.zf.stuckto:${stickTo}`); 
    this.$element.on("transitionend webkitTransitionEnd oTransitionEnd otransitionend MSTransitionEnd", function() { 
     _this._setSizes(); 
    }); 
    } 

    /** 
    * Causes the $element to become unstuck. 
    * Removes `position: fixed;`, and helper classes. 
    * Adds other helper classes. 
    * @param {Boolean} isTop - tells the function if the $element should anchor to the top or bottom of its $anchor element. 
    * @fires Sticky#unstuckfrom 
    * @private 
    */ 
    _removeSticky(isTop) { 
    var stickTo = this.options.stickTo, 
     stickToTop = stickTo === 'top', 
     css = {}, 
     anchorPt = (this.points ? this.points[1] - this.points[0] : this.anchorHeight) - this.elemHeight, 
     mrgn = stickToTop ? 'marginTop' : 'marginBottom', 
     notStuckTo = stickToTop ? 'bottom' : 'top', 
     topOrBottom = isTop ? 'top' : 'bottom'; 

    css[mrgn] = 0; 

    css['bottom'] = 'auto'; 
    if(isTop) { 
     css['top'] = 0; 
    } else { 
     css['top'] = anchorPt; 
    } 

    this.isStuck = false; 
    this.$element.removeClass(`is-stuck is-at-${stickTo}`) 
       .addClass(`is-anchored is-at-${topOrBottom}`) 
       .css(css) 
       /** 
        * Fires when the $element has become anchored. 
        * Namespaced to `top` or `bottom`, e.g. `sticky.zf.unstuckfrom:bottom` 
        * @event Sticky#unstuckfrom 
        */ 
       .trigger(`sticky.zf.unstuckfrom:${topOrBottom}`); 
    } 

    /** 
    * Sets the $element and $container sizes for plugin. 
    * Calls `_setBreakPoints`. 
    * @param {Function} cb - optional callback function to fire on completion of `_setBreakPoints`. 
    * @private 
    */ 
    _setSizes(cb) { 
    this.canStick = Foundation.MediaQuery.is(this.options.stickyOn); 
    if (!this.canStick) { 
     if (cb && typeof cb === 'function') { cb(); } 
    } 
    var _this = this, 
     newElemWidth = this.$container[0].getBoundingClientRect().width, 
     comp = window.getComputedStyle(this.$container[0]), 
     pdngl = parseInt(comp['padding-left'], 10), 
     pdngr = parseInt(comp['padding-right'], 10); 

    if (this.$anchor && this.$anchor.length) { 
     this.anchorHeight = this.$anchor[0].getBoundingClientRect().height; 
    } else { 
     this._parsePoints(); 
    } 

    this.$element.css({ 
     'max-width': `${newElemWidth - pdngl - pdngr}px` 
    }); 

    var newContainerHeight = this.$element[0].getBoundingClientRect().height || this.containerHeight; 
    if (this.$element.css("display") == "none") { 
     newContainerHeight = 0; 
    } 
    this.containerHeight = newContainerHeight; 
    this.$container.css({ 
     height: newContainerHeight 
    }); 
    this.elemHeight = newContainerHeight; 

    if (!this.isStuck) { 
     if (this.$element.hasClass('is-at-bottom')) { 
     var anchorPt = (this.points ? this.points[1] - this.$container.offset().top : this.anchorHeight) - this.elemHeight; 
     this.$element.css('top', anchorPt); 
     } 
    } 

    this._setBreakPoints(newContainerHeight, function() { 
     if (cb && typeof cb === 'function') { cb(); } 
    }); 
    } 

    /** 
    * Sets the upper and lower breakpoints for the element to become sticky/unsticky. 
    * @param {Number} elemHeight - px value for sticky.$element height, calculated by `_setSizes`. 
    * @param {Function} cb - optional callback function to be called on completion. 
    * @private 
    */ 
    _setBreakPoints(elemHeight, cb) { 
    if (!this.canStick) { 
     if (cb && typeof cb === 'function') { cb(); } 
     else { return false; } 
    } 
    var mTop = emCalc(this.options.marginTop), 
     mBtm = emCalc(this.options.marginBottom), 
     topPoint = this.points ? this.points[0] : this.$anchor.offset().top, 
     bottomPoint = this.points ? this.points[1] : topPoint + this.anchorHeight, 
     // topPoint = this.$anchor.offset().top || this.points[0], 
     // bottomPoint = topPoint + this.anchorHeight || this.points[1], 
     winHeight = window.innerHeight; 

    if (this.options.stickTo === 'top') { 
     topPoint -= mTop; 
     bottomPoint -= (elemHeight + mTop); 
    } else if (this.options.stickTo === 'bottom') { 
     topPoint -= (winHeight - (elemHeight + mBtm)); 
     bottomPoint -= (winHeight - mBtm); 
    } else { 
     //this would be the stickTo: both option... tricky 
    } 

    this.topPoint = topPoint; 
    this.bottomPoint = bottomPoint; 

    if (cb && typeof cb === 'function') { cb(); } 
    } 

    /** 
    * Destroys the current sticky element. 
    * Resets the element to the top position first. 
    * Removes event listeners, JS-added css properties and classes, and unwraps the $element if the JS added the $container. 
    * @function 
    */ 
    destroy() { 
    this._removeSticky(true); 

    this.$element.removeClass(`${this.options.stickyClass} is-anchored is-at-top`) 
       .css({ 
        height: '', 
        top: '', 
        bottom: '', 
        'max-width': '' 
       }) 
       .off('resizeme.zf.trigger') 
       .off('mutateme.zf.trigger'); 
    if (this.$anchor && this.$anchor.length) { 
     this.$anchor.off('change.zf.sticky'); 
    } 
    $(window).off(this.scrollListener); 

    if (this.wasWrapped) { 
     this.$element.unwrap(); 
    } else { 
     this.$container.removeClass(this.options.containerClass) 
        .css({ 
         height: '' 
        }); 
    } 
    Foundation.unregisterPlugin(this); 
    } 
} 

Sticky.defaults = { 
    /** 
    * Customizable container template. Add your own classes for styling and sizing. 
    * @option 
    * @type {string} 
    * @default '&lt;div data-sticky-container&gt;&lt;/div&gt;' 
    */ 
    container: '<div data-sticky-container></div>', 
    /** 
    * Location in the view the element sticks to. Can be `'top'` or `'bottom'`. 
    * @option 
    * @type {string} 
    * @default 'top' 
    */ 
    stickTo: 'top', 
    /** 
    * If anchored to a single element, the id of that element. 
    * @option 
    * @type {string} 
    * @default '' 
    */ 
    anchor: '', 
    /** 
    * If using more than one element as anchor points, the id of the top anchor. 
    * @option 
    * @type {string} 
    * @default '' 
    */ 
    topAnchor: '', 
    /** 
    * If using more than one element as anchor points, the id of the bottom anchor. 
    * @option 
    * @type {string} 
    * @default '' 
    */ 
    btmAnchor: '', 
    /** 
    * Margin, in `em`'s to apply to the top of the element when it becomes sticky. 
    * @option 
    * @type {number} 
    * @default 1 
    */ 
    marginTop: 1, 
    /** 
    * Margin, in `em`'s to apply to the bottom of the element when it becomes sticky. 
    * @option 
    * @type {number} 
    * @default 1 
    */ 
    marginBottom: 1, 
    /** 
    * Breakpoint string that is the minimum screen size an element should become sticky. 
    * @option 
    * @type {string} 
    * @default 'medium' 
    */ 
    stickyOn: 'medium', 
    /** 
    * Class applied to sticky element, and removed on destruction. Foundation defaults to `sticky`. 
    * @option 
    * @type {string} 
    * @default 'sticky' 
    */ 
    stickyClass: 'sticky', 
    /** 
    * Class applied to sticky container. Foundation defaults to `sticky-container`. 
    * @option 
    * @type {string} 
    * @default 'sticky-container' 
    */ 
    containerClass: 'sticky-container', 
    /** 
    * Number of scroll events between the plugin's recalculating sticky points. Setting it to `0` will cause it to recalc every scroll event, setting it to `-1` will prevent recalc on scroll. 
    * @option 
    * @type {number} 
    * @default -1 
    */ 
    checkEvery: -1 
}; 

/** 
* Helper function to calculate em values 
* @param Number {em} - number of em's to calculate into pixels 
*/ 
function emCalc(em) { 
    return parseInt(window.getComputedStyle(document.body, null).fontSize, 10) * em; 
} 

// Window exports 
Foundation.plugin(Sticky, 'Sticky'); 

} 
+2

最初の関数は、ドキュメントの準備ができたときに呼び出されますが、何も渡されないので、$は未定義です。もう1つはすぐに実行されますが、これはおそらくあなたが望むものではありません。なぜあなたは明示的にjQueryを$として渡す必要がありますか? –

+0

文書の準備が整うと、またajaxのリロード後にinitialiseStickyの内部でコードを実行する必要があります。内部で書かれていないコードは、$、jQueryオブジェクトまたは何かを参照する際に "this"を使用します。そのため、渡す必要があります。私は$が未定義である理由を理解していない、私を許して、jqueryの私の理解はかなり基本的です –

+3

なぜgobally利用可能な関数にjqueryを渡す必要がありますか? – xDreamCoding

答えて

1

Javascriptがどのinner functionが親スコープを訪問することができますので、Closuresを実装しています。今

var foo = 'bar'; 

function baz() { 
    console.log(foo); // => baz 
} 

、あなたのinitialiseStickyはあなたがそれのでinitialiseStickyにjQueryの参照を渡す必要はありませんwindow.jQueryとしてグローバルスコープの内部機能WindowともjQueryがこの範囲であるであるため、既にそれにアクセスすることができます。

メモ$はちょうどjQueryのエイリアスです。

1

あなたのコード全体がたくさん乱されています。私はそれを取り除こうとします。

$(function() { 
    console.log('document ready- sticky'); 
    initialiseSticky($); 
}); 
$(document).ajaxComplete(function() { 
    console.log('ajax complete- sticky'); 
    initialiseSticky($); 
}); 

function initialiseSticky($) { 
//my code 
} 

これが有効な場合は試してください。注:私は$を渡すことが必要であるか分からない。

+0

信じられないかもしれませんが、実際これは私の最初の試行のようですが、私はなぜそれがdocument.readyのために働いたのかわかりません: 'jQuery(function($){ console.log 'document ready sticky'); initialiseSticky($); }); 'でも、まだajaxCompleteではうまくいかないでしょう。私は本当になぜそれがdocument.readyで動作するとして失われています... –

関連する問題