लंबवत स्क्रॉल करते समय क्षैतिज स्क्रॉल न करें (और इसके विपरीत)


17

मेरे पास overflow-xऔर overflow-yसेट के साथ एक सूची है auto। इसके अलावा, मैंने गति स्क्रॉल सेट किया है, इसलिए मोबाइल में टच स्क्रॉलिंग अच्छा काम करती है webkit-overflow-scrolling: true

हालाँकि, समस्या यह है कि मैं लंबवत स्क्रॉल करते समय क्षैतिज स्क्रॉल को अक्षम करने का तरीका नहीं जान सकता। यह वास्तव में खराब उपयोगकर्ता अनुभव की ओर जाता है, क्योंकि ऊपर बाईं ओर या ऊपर दाईं ओर स्वाइप करने से तालिका तिरछे स्क्रॉल होगी। जब उपयोगकर्ता लंबवत स्क्रॉल कर रहा होता है, तो मैं बिल्कुल भी क्षैतिज रूप से स्क्रॉल नहीं करना चाहता जब तक कि उपयोगकर्ता ने लंबवत स्क्रॉल करना बंद न कर दिया हो।

मैंने निम्नलिखित कोशिश की है:

जे एस:

offsetX: number;
offsetY: number;
isScrollingHorizontally = false;
isScrollingVertically = false;

//Detect the scrolling events
ngOnInit() {
    this.scrollListener = this.renderer.listen(
      this.taskRows.nativeElement,
      'scroll',
      evt => {
        this.didScroll();
      }
    );

    fromEvent(this.taskRows.nativeElement, 'scroll')
      .pipe(
        debounceTime(100),
        takeUntil(this.destroy$)
      )
      .subscribe(() => {
        this.endScroll();
    });
}

didScroll() {
    if ((this.taskRows.nativeElement.scrollLeft != this.offsetX) && (!this.isScrollingHorizontally)){
        console.log("Scrolling horizontally")
        this.isScrollingHorizontally = true;
        this.isScrollingVertically = false;
        this.changeDetectorRef.markForCheck();
    }else if ((this.taskRows.nativeElement.scrollTop != this.offsetY) && (!this.isScrollingVertically)) {
        console.log("Scrolling Vertically")
        this.isScrollingHorizontally = false;
        this.isScrollingVertically = true;
        this.changeDetectorRef.markForCheck();
    }
}

endScroll() {
    console.log("Ended scroll")
    this.isScrollingVertically = false;
    this.isScrollingHorizontally = false;
    this.changeDetectorRef.markForCheck();
}

HTML:

<div
    class="cu-dashboard-table__scroll"
    [class.cu-dashboard-table__scroll_disable-x]="isScrollingVertically"
    [class.cu-dashboard-table__scroll_disable-y]="isScrollingHorizontally"
>

सीएसएस:

&__scroll {
  display: flex;
  width: 100%;
  height: 100%;
  overflow-y: auto;
  overflow-x: auto;
  will-change: transform;
  -webkit-overflow-scrolling: touch;

  &_disable-x {
     overflow-x: hidden;
  }

  &_disable-y {
    overflow-y: hidden;
  }
}

लेकिन हर मैं सेट overflow-xया overflow-yकरने के लिए hiddenजब उसके स्क्रॉल किया गया है, स्क्रॉल गड़बड़ और शीर्ष करने के लिए वापस चला जाएगा। मैंने यह भी देखा है कि webkit-overflow-scrolling: trueयही कारण है कि ऐसा होता है, जब मैं इसे हटाता हूं, तो व्यवहार बंद हो जाता है, लेकिन मुझे मोबाइल उपकरणों में गति के लिए इसकी आवश्यकता है।

लंबवत स्क्रॉल करते समय मैं क्षैतिज स्क्रॉल को कैसे अक्षम करूं?


मुझे नहीं पता कि स्क्रॉलिंग समस्या को कैसे ठीक किया जाए। शायद एक कदम पीछे ले जाएं और दो में से एक कुल्हाड़ियों को वैसे भी स्क्रॉल करने से रोकने की कोशिश करें? ऑफ-टॉपिक: टेबल्स वास्तव में छोटे स्क्रीन के लिए नहीं हैं।
जोप कोकेलकोर्न

आपके कोड में एक गायब कर्ली ब्रैकेट है। यदि आप इसे स्निपेट के रूप में जोड़ते हैं, तो आपको कंसोल में एक त्रुटि संदेश दिखाई देगा।
रज़वान ज़म्फिर

बस एक बेवकूफ विचार है। स्क्रॉल करने के लिए दो स्लाइडर्स या कस्टम स्लाइडर का उपयोग क्यों नहीं करते?
थॉमस लुडविग

संबंधित अवधारणा: stackoverflow.com/questions/24594653/…
जेम्स डन

जवाबों:


4

इसे इस्तेमाल करे

HTML
<div
  class="cu-dashboard-table__scroll-vertical"
>
  <div
    class="cu-dashboard-table__scroll-horizontal"
  >
    <!-- Scroll content here -->
  </div>
</div>


CSS
&__scroll {
  &-horizontal {
    overflow-x: auto;
    width: 100%;
    -webkit-overflow-scrolling: touch;
  }

  &-vertical {
    overflow-y: auto;
    height: 100%;
    -webkit-overflow-scrolling: touch;
  }
}

स्क्रॉल करने के लिए एक div का उपयोग करने के बजाय, आप दो का उपयोग क्यों नहीं करते? X के लिए एक और Y के लिए एक है


1
महान विचार! बीमार इसे एक शॉट दें।
जोश ओ'कॉनर

1
योग्य, मुझे कहना होगा कि यह एक सरल विचार है।
frodo2975

15

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

यदि आपके पास एकल-अक्ष स्क्रॉलिंग होनी चाहिए, तो एक संभावित समाधान हो सकता है कि स्क्रॉल स्थिति का ट्रैक स्वयं के माध्यम से touchstartऔर touchmoveघटनाओं के माध्यम से रखें । यदि आप अपने ड्रैग थ्रेशोल्ड को ब्राउज़र से कम सेट करते हैं, तो आप कथित डायन से बचने के लिए स्क्रॉल करने से पहले अपना सीएसएस सामान करने में सक्षम हो सकते हैं। इसके अलावा, भले ही यह अभी भी गड़बड़ हो, आपके पास स्पर्श प्रारंभ और स्पर्श का वर्तमान स्थान है। इनमें से, यदि आप अपनी div की आरंभिक स्क्रॉल स्थिति को रिकॉर्ड करते हैं, तो आप मैन्युअल रूप से div को सही स्थान पर स्क्रॉल कर सकते हैं, यदि आप के लिए यह शीर्ष पर जा रहे हैं तो उसका प्रतिकार करें। एक संभव एल्गोरिथ्म इस तरह दिख सकता है:

// Touchstart handler
if (scrollState === ScrollState.Default) {
    // Record position and id of touch
    touchStart = touch.location
    touchStartId = touch.id.
    scrollState = ScrollState.Touching

    // If you have to manually scroll the div, first store its starting scroll position:
    containerTop = $('.myContainer').scrollTop();
    containerLeft = $('.myContainer').scrollLeft();
}

// Touchmove handler - If the user has dragged beyond a distance threshold,
// do the css classes swap.
if (touch.id === touchStartId && distance(touchStart, touch.location > threshold) {
    scrollState = ScrollState.Scrolling;
    swapCssClasses();

    // If you have to manually scroll the div to prevent jump:
    $('.myContainer').scrollTop(containerTop + (touch.location.y - touchStart.y));
    // Do the same for horizontal scroll.
}

// Then, listen for debounced scroll events, like you're already doing,
// to reset your state back to default.

दूसरा विचार: अपने स्क्रॉल हैंडलर में, css क्लासेस को बदलने के बजाय, उस div की स्क्रॉल स्थिति को सीधे उस अक्ष पर सेट करें जिसे आप लॉक करना चाहते हैं। IE, यदि आप क्षैतिज रूप से स्क्रॉल कर रहे हैं, तो हमेशा स्क्रॉलटॉप को इसके शुरुआती मूल्य पर सेट करें। यह भी स्क्रॉल रद्द कर सकता है, निश्चित नहीं। आपको यह देखने की कोशिश करनी होगी कि क्या यह काम करता है।


मैंने यह कोशिश की, लेकिन यह सुपर उछल रहा था और प्रदर्शन भयानक था।
जोश ओ'कॉनर

3

इसे हल करने के लिए कई तरीके हैं। कुछ अच्छे विचार यहां प्रस्तुत हैं।

हालाँकि, जैसा कि अन्य लोगों ने कहा है, पर भरोसा करना (या बचने की कोशिश करना) बहुआयामी स्क्रॉल एक बुरा यूएक्स गंध है - यूएक्स का संकेत एक समस्या है। मुझे नहीं लगता कि यह एक वैध देव मुद्दा है। बेहतर होगा कि आप एक कदम पीछे ले जाएं और जो आप पूरा करने की कोशिश कर रहे हैं उसका पुनर्मूल्यांकन करें। समस्याओं में से एक यह हो सकता है कि UI को अधिक उपयोगी बनाने के प्रयास में, आप उपयोगकर्ताओं को भ्रमित करेंगे। यहाँ वर्णित प्रयोज्यता से भ्रम की स्थिति पैदा होगी।

मैं क्षैतिज रूप से स्क्रॉल क्यों नहीं कर सकता?

जब मैं लंबवत स्क्रॉल करना बंद करता हूं, तभी मैं क्षैतिज रूप से स्क्रॉल कर सकता हूं?

ये कुछ प्रश्न हैं जो पूछे जा सकते हैं (अश्रव्य)।

यदि आप ऊर्ध्वाधर डेटा सूची की अतिरिक्त जानकारी के लिए केवल तब ही उपयोग करने की कोशिश कर रहे हैं जब उपयोगकर्ता ने पंक्ति का चयन किया हो, तो यह संभवत: बेहतर होगा कि डिफ़ॉल्ट रूप से केवल स्क्रॉल करने योग्य लंबवत रूप से एक फ्लैट सूची हो, और केवल ऊर्ध्वाधर टॉगल करें जानकारी जब "पंक्ति" का चयन / सक्रिय किया गया है। विवरणों को समाप्‍त करने पर आप समतल वर्टिकल सूची में वापस आ जाएंगे।

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


3

तीन कंटेनरों का उपयोग करने की आवश्यकता है।
पहले कंटेनर में मैं ऊर्ध्वाधर स्क्रॉलिंग को सक्षम करता हूं और क्षैतिज रूप से अस्वीकार करता हूं।
दूसरे में, इसके विपरीत, मैं क्षैतिज स्क्रॉलिंग को सक्षम करता हूं और ऊर्ध्वाधर को अस्वीकार करता हूं। उपयोग करना सुनिश्चित करें overflow-x: hidden;और overflow-y: hidden;, अन्यथा बाल कंटेनर वर्तमान कंटेनर से परे जा सकते हैं।
भी उपयोग करने की आवश्यकता है min-width: 100%; min-height: 100%;
तीसरे कंटेनर के लिए हमें उपयोग करने की आवश्यकता है display: inline-block;और फिर आंतरिक सामग्री इस कंटेनर को फैलाएगी और दो माता-पिता ब्लॉक पर संबंधित स्क्रॉल बार दिखाई देंगे।

एचटीएमएल

<div class="scroll-y">
  <div class="scroll-x">
    <div class="content-container">

      <!-- scrollable content here -->

    </div>
  </div>
</div>

सीएसएस

.scroll-y {
  position: absolute;
  overflow-x: hidden;
  overflow-y: auto;
  width: 100%;
  height: 100%;
  min-width: 100%;
  min-height: 100%;
}

.scroll-x {
  overflow-y: hidden;
  overflow-x: auto;
  width: auto;
  min-width: 100%;
  min-height: 100%;
}

.content-container {
  min-width: 100%;
  min-height: 100%;
  display: inline-block;
}

आप इसे आईफोन पर सफारी में यहां टेस्ट कर सकते हैं ।

सौभाग्य!! 😉


: उठे हुए हाथ:: उठे हुए हाथ:
cup_of

0

यह मजेदार लग रहा है;)

अगर यह उचित है तो मैं इसके बारे में बहस नहीं करूंगा।

मैंने इसे RxJS के साथ आज़माया:

  ngAfterViewInit() {
    const table = document.getElementById("table");

    const touchstart$ = fromEvent(table, "touchstart");
    const touchmove$ = fromEvent(table, "touchmove");
    const touchend$ = fromEvent(table, "touchend");

    touchstart$
      .pipe(
        switchMapTo(
          touchmove$.pipe(
            // tap(console.log),
            map((e: TouchEvent) => ({
              x: e.touches[0].clientX,
              y: e.touches[0].clientY
            })),
            bufferCount(4),
            map(calculateDirection),
            tap(direction => this.setScrollingStyles(direction)),
            takeUntil(touchend$)
          )
        )
      )
      .subscribe();
  }

हम हर 4 बफ़र touchemoveघटना और उसके बाद चार घटनाओं के निर्देशांक (के साथ कुछ अत्यधिक परिष्कृत गणना कर map(calculateDirection)) जो आउटपुट RIGHT, LEFT, UPयाDOWN और है कि मैं अक्षम खड़ी या horicontal स्क्रॉल करने की कोशिश पर आधारित है। क्रोम में मेरे एंड्रॉइड फोन पर यह काम करता है;)

Ivv ने थोड़ा खेल का मैदान बनाया , जिसे बढ़ाया जा सकता था, जिसे फिर से लिखा गया ...

चीयर्स क्रिस

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.