2015-05-06 7 views
9

Daniel F Pupius पर स्क्रॉल के रूप में समस्या का वर्णन किया:Ember.js इतिहास पर पुस्तक बहाल, रीसेट लिंक

साइटों बहुत से यह गलत हो जाते हैं और यह वास्तव में कष्टप्रद है। जब उपयोगकर्ता ब्राउज़र के आगे या पीछे बटन का उपयोग करके नेविगेट करता है तो स्क्रॉल स्थिति वही होनी चाहिए जैसा कि पिछली बार वे पृष्ठ पर थे। यह कभी-कभी फेसबुक पर सही तरीके से काम करता है लेकिन कभी-कभी नहीं करता है। Google+ हमेशा आपकी स्क्रॉल स्थिति खो देता प्रतीत होता है।

तो नए पृष्ठ पर ब्राउज़ करते समय पृष्ठ के शीर्ष पर स्क्रॉल को रीसेट करने के बारे में पहले से ही कई प्रश्न हैं। Ember.js के भी shows how to hook into Route.activate कुकबुक:

export default Ember.Mixin.create({ 
    activate: function() { 
    this._super(); 
    window.scrollTo(0,0); 
    } 
}); 

हालांकि यह केवल हल समस्या को आधा। जब उपयोगकर्ता बैक/फॉरवर्ड बटन का उपयोग करता है, तो स्क्रॉल स्थिति पुनर्स्थापित नहीं की जाएगी, लेकिन बस रीसेट करें।

Ember.Controller उदाहरण के अंदर स्क्रॉल स्थिति को संग्रहीत करके कई को हल करने में बहुत सारे प्रयास हैं, उदाहरण के लिए इस article में। हालांकि यह केवल आंशिक समाधान है। यदि नियंत्रक को कई बार उपयोग किया जाता है, तो केवल एक ही स्क्रॉल स्थिति संरक्षित की जाएगी।

पुरानी स्क्रॉल स्थिति को पुनर्स्थापित करने का डिफ़ॉल्ट ब्राउज़र कार्यान्वयन कैसे संरक्षित किया जा सकता है? इस प्रकार, कुछ भी नहीं करें अगर Route.activate एचटीएमएल 5 इतिहास राज्य परिवर्तन से ट्रिगर किया गया था?

उत्तर

14

मैंने अभी इस समस्या को अपने स्वयं के ऐप में हल कर लिया है।

आप केवल स्थानों यह जरूरत है कि में इसका इस्तेमाल करने के लिए, बस एक mixin का उपयोग करना चाहते हैं: mixins/remember-scroll.js में फिर

ember g mixin remember-scroll

, के साथ बदलें:

import Ember from 'ember'; 

export default Ember.Mixin.create({ 

    scrollSelector: window, 

    activate: function() { 
    this._super.apply(this, arguments); 
    var self = this; 
    if(this.get('lastScroll')){ 

     Ember.run.next(function(){ 
     Ember.$(self.scrollSelector).scrollTop(self.get('lastScroll')); 
     }); 

    } else { 
     Ember.$(this.scrollSelector).scrollTop(0); 
    } 
    }, 

    deactivate: function() { 
    this._super.apply(this, arguments); 
    this.set('lastScroll',Ember.$(this.scrollSelector).scrollTop()); 
    }, 

}); 

आप यह स्वचालित रूप से चाहते हैं सभी मार्गों में मिश्रित, फिर निम्नलिखित करें।

एम्बर सीएलआई में, एक नया प्रारंभिक बनाएं।

ember g initializer remember-scroll

फिर initializers/remember-scroll.js में, इस के साथ कोड की जगह:

import Ember from "ember"; 

var rememberScroll = Ember.Mixin.create({ 

    scrollSelector: window, 

    activate: function() { 
    this._super.apply(this, arguments); 
    var self = this; 
    if(this.get('lastScroll')){ 

     Ember.run.next(function(){ 
      Ember.$(self.scrollSelector).scrollTop(self.get('lastScroll')); 
     }); 

    } else { 
     Ember.$(this.scrollSelector).scrollTop(0); 
    } 
    }, 

    deactivate: function() { 
    this._super.apply(this, arguments); 
    this.set('lastScroll',Ember.$(this.scrollSelector).scrollTop()); 
    }, 

}); 

export function initialize(/* container, application */) { 
    Ember.Route.reopen(rememberScroll); 
} 

export default { 
    name: 'remember-scroll', 
    initialize: initialize 
}; 

आप उपरोक्त पहले mixin निकाल सकते हैं आप प्रारंभकर्ता संस्करण का उपयोग कर रहे हैं।

इससे आपके सभी मार्गों को आखिरी स्क्रॉल स्थिति याद रखने का कारण बनना चाहिए (यदि आप पहले वहां रहे हैं), और वहां लौटने पर इसे लागू करें।

हालांकि मैं इसे सभी मार्गों में डालने के खिलाफ अनुशंसा करता हूं, क्योंकि उपयोगकर्ता पिछले स्क्रॉल स्थिति में वापस आने की उम्मीद नहीं कर सकते हैं, यदि वे वहां मौजूद थे, तो पर्याप्त समय बीत चुका है।

+0

मुझे लगता है कि नियंत्रक को दो बार दौरा किया गया था, तो मुझे दो अलग-अलग स्क्रॉल स्थितियों को याद नहीं होगा? – bouke

+0

यह मिश्रण मार्ग पर लागू होता है, नियंत्रक नहीं। जब आप मार्ग छोड़ते हैं तो स्क्रॉल स्थिति को याद किया जाता है ('निष्क्रिय करें' अनुभाग देखें), फिर वापस आने पर इसे पुनर्स्थापित करता है। – JeremyTM

3

मुझे आमतौर पर प्रभावी होने के लिए the solution by JeremyTM here मिला है। हालांकि, मेरे अनुभव में deactivate विधि का उपयोग करके मूल्य पर असंगतता lastScroll पर संक्रमण पर होती है जबकि मार्ग willTransition क्रिया विधि का उपयोग लगातार सेट व्यवहार की ओर जाता है।

import Ember from 'ember'; 

export default Ember.Mixin.create({ 
    activate: function() { 
    this._super.apply(this, arguments); 
    var self = this; 

    if(this.get('lastScroll')){ 
     Ember.run.next(function(){ 
     Ember.$(window).scrollTop(self.get('lastScroll')); 
     }); 
    } else { 
     Ember.$(window).scrollTop(0); 
    } 
    }, 

    actions: { 
    willTransition: function() { 
     this._super.apply(this, arguments); 
     this.set('lastScroll', Ember.$(window).scrollTop()); 
    } 
    } 
}); 

रूप में अच्छी तरह कि यह अभी भी मुझ में है कि यह सभी लिंक पर स्क्रॉल रीसेट नहीं है समस्या का आंशिक समाधान के रूप में हमलों नोट:

यहाँ उसकी mixin को संशोधन कि मेरे लिए बेहतर काम करता है क्लिक (ब्राउज़र नेविगेशन/इतिहास परिवर्तन के विपरीत)। यह पहले लिंक पर ऐसा करता है जो एक मार्ग लोड करता है, लेकिन उस रूट के बाद के सभी लिंक क्लिक पिछले स्क्रॉल स्थिति को भी लोड करेंगे, जिससे उपयोगकर्ता के पिछले दृश्य व्यवहार के संदर्भ में मार्ग लोड करने के लिए उपयोगकर्ता की इच्छित कार्रवाई को पहचानने में असफल रहा है (एक रीसेट स्क्रॉल स्थिति के साथ उर्फ)।

1

स्क्रॉल इतिहास पुनर्स्थापना क्षमताओं के साथ स्क्रॉल रीसेट करने के लिए इस एम्बर एडन ember-router-scroll स्थापित करें। यह ब्राउज़र के इतिहास स्थान API का उपयोग करता है, इसलिए यह बॉक्स के बाहर काम करता है।