我如何做一个真正的自适应滑块(轮播)

美好的一天,亲爱的读者和作家!


今天,我将告诉您该项目如何面对制造自适应滑块的任务,以及它的结果


关于这篇文章及其目的


我之所以写这篇文章不是因为我希望社区对此问题做出回应,而是因为解决该文章的问题对于我来说理解Web滑块的适应性似乎至关重要。 如果有人已经编写了此类组件,请做出回应并分享类似的经验


关于发生了什么以及使用了哪些工具的一点


在React应用程序中,您需要制作一个轮播(以下将使用此名称),该轮播的元素可以在任何大小的屏幕上和谐地显示。 有几个限制:


  1. 元素的最大宽度为150像素
  2. 使用的工具-React Owl Carousel
  3. 轮播容器的最大尺寸为1190像素
  4. 对于不同的屏幕(影响容器的可见部分的宽度)和边距(元素之间至少5个像素),还有填充属性的指示符
  5. 轮播应该循环进行
    以及不影响本文主题的其他条件

旋转木马力学的离题


许多轮播(React Owl Carousel也不例外)使用特殊的活动类来显示,该类描述了当前在屏幕上显示的元素。


要在屏幕上显示无限循环,必须复制第一个元素和最后一个元素(配音的机制和问题是另一篇文章的主题)。


属性由特殊对象描述,我们会对响应对象感兴趣,该对象负责重新分配属性。


在描述解决方案的过程中,有关工作机制的其余数据将很清楚。


第一个问题


最初,一切都进行得很顺利-元素本身已被编写和样式化,阐明了整个轮播的基本属性。 设置属性{loop:true}时出现问题


旋转木马循环不足


滚动到列表的末尾时,轮播中仍保留有可用空间,并且有一段时间正在滚动浏览。


原因是元素的最大宽度,与元素的数量不一致。 一个具体的示例是容器的宽度1190 px,元素数设置为3。


换句话说,轮播期望3个元素可以延伸到1190像素,并且它们不能超过150像素。


增加项目数


问题的角度不同:如果每个容器中的元素太多,它们的宽度就会变得太小(并且里面有内容!)如果我设置min-width属性,则在某些屏幕尺寸上,元素会彼此爬行,而忽略了边距,这违反了条件。


我们总结了适应性条件


  1. 屏幕上的元素数量应小于屏幕尺寸与
    元素的最小宽度-否则即使最小宽度的元素也无法显示在屏幕上。
  2. 屏幕尺寸与估计的元素数之比不应超过最大的估计长度,否则会出现循环问题。
  3. 任何屏幕尺寸(从330px到1190px)都必须满足上述条件。

我们以程序员的身份解决问题


如果您依次解决问题,很明显您必须放弃一些东西,在我的情况下,这是元素的最小宽度。


元件的最小宽度应该是多少,以便满足所有容器筛网的适应性条件?


//       const getBackTrace = (minScreen = 300, maxElementWidth = 150) => { let backTrace = {} for (let minElementWidth = maxElementWidth; minElementWidth > 0; minElementWidth--){ //            //     backTrace for(let screen = minScreen; screen <= 1100; screen++){ let elementCount = screen / minElementWidth | 0 if((screen / elementCount) > maxElementWidth){ backTrace[minElementWidth] = screen break } } } for(let key in backTrace){ //        ,      if (backTrace[key - 1] == undefined){ backTrace.result = key - 1 return backTrace } } } // getBackTrace(300, 150).result = 100 

100px的结果不适合我,因为它不允许我适合元素中的所有内容。 因此,我们继续进行搜索,直到找到合适的值并寻找其他需要牺牲的地方。


还记得字幕吗? 要搜索,编写一个函数


 const getMinScreen = (minWidth = 300, maxWidth = 767, maxElementWidth = 150) => { let research = [] //  ,          // getBackTrace,       for(let min = minWidth; min < maxWidth; min++){ let { result } = getBackTrace(min, maxElementWidth) research.push({result, min}) } //          "  "  return research .reduce((acc, curr, idx, arr) => { let obj = {} let {min, result} = curr obj[min] = result if(idx == 0) return obj if(arr[idx-1].result == result){ return {...acc} } else { return {...acc, ...obj} } }, {}) } /* Returned object {300: 100, 303: 101, 306: 102, 309: 103, 312: 104, 315: 105, 318: 106, 321: 107, 324: 108, 327: 109, 330: 110, 333: 111, 336: 112, 452: 113, 456: 114, 460: 115, 464: 116, 468: 117, 472: 118, 476: 119, 480: 120}   480    */ 

考虑到获得的对象,您可以看到从336px过渡到452px的过程有了很大的跳跃。
我做出了一个坚决决定将适应性限制为36px的决定。


我们描述自适应对象


看来问题已解决,但是这样的解决方案仅证明对于336px以上的屏幕可能符合条件,但未描述该方法。 但是有一些不同的条件限制了我对具有适应性属性的对象的生产
我自己接受了无损失的最小宽度元素可以是107 px(改变边距值)的经验,我得出以下指标:


萤幕保证金最小宽度
336+5107
468+10107
763+15112

剩下的唯一事情就是将接收到的数据收集到一个堆中并实现自适应对象:


 getResponsiveOwlItems = () => { let responsive = {}; responsive[0] = {items: 2, nav: false} // 112 = 107 (minimal div) + 5 (margins) let itemMinWidthReference = 112; const getOneWidth = deviceWidth => deviceWidth / itemMinWidthReference | 0 // 1190 - container width for(let i = itemMinWidthReference * 3 + 20; i <= 1190; i += itemMinWidthReference){ // .container padding > 768 90px + padding 90(.container) // .container padding < 768 40px + padding -40(.container) // +20px stagePadding let padding = i > 767 ? 200 : 20 if(i > (468 + padding)) { itemMinWidthReference = 117 } if(i > (767 + padding)) { itemMinWidthReference = 127 } let items = getOneWidth(i - padding) let nav = i > 700 ? true : false let margin = 5; if (i > 468){ margin = 10 } if (i > 767){ margin = 15 } responsive[i.toString()] = {items, nav, margin} //      itemMinWidthReference i = i - (i % itemMinWidthReference) + 1 } return responsive; } 

在发布之日,一切看起来都很合理,而且我无法在轮播中重现错误-一切都可能按预期运行。


感谢您的关注,等待您的评论和评论!

Source: https://habr.com/ru/post/zh-CN461525/


All Articles