如何在特定视口上设置触摸手势/hammer.js 处于活动状态?

Posted

技术标签:

【中文标题】如何在特定视口上设置触摸手势/hammer.js 处于活动状态?【英文标题】:How to set touch gestures / hammer.js active on a specific viewport? 【发布时间】:2018-10-09 16:59:09 【问题描述】:

我刚刚为我正在构建的网站构建了带有触摸事件的轮播滑块。目前试图弄清楚如何在特定视口上激活或禁用触摸事件(hammer)。基本上一旦它到达移动/平板电脑视口。 Hammer.js 将启动禁用滑块的点击控件

var activeSlide = 0;
    $('.faculty-carousel').attr('data-slide', '0');
    
    
    
    $('.tile-layout').on('click', function() 
        $('.faculty-items').each(function() 
            $(this).addClass('tile-view');
        )
    )
    
    
    $('.prev').on('click', function(e) 
        event.stopPropagation();
    
        var carouselWrapper     = $(this).closest('.faculty-carousel'),
            facultyProfilePanel = carouselWrapper.find('.faculty-items li'),
            facultyProfileCount = facultyProfilePanel.length,
            viewPortSize        = $(window).width(),
            carousel            = carouselWrapper.find('.faculty-items'),
            position            = 0,
            currentSlide        = parseInt(carouselWrapper.attr('data-slide'));
    
        // Check if data-slide attribute is greater than 0
        if (currentSlide > 0) 
            // Decremement current slide
            currentSlide--;
            // Assign CSS position to clicked slider
            var transformPercentage = -1 * currentSlide / facultyProfileCount * 100;
            carousel.css('transform', 'translateX(' + transformPercentage + '% )');
    
            // Update data-slide attribute
            carouselWrapper.attr('data-slide', currentSlide);
            activeSlide = currentSlide;
        
    );
    
    $('.next').on('click', function(e) 
        event.stopPropagation();
        // store variable relevent to clicked slider
    
        var carouselWrapper     = $(this).closest('.faculty-carousel'),
            facultyProfilePanel = carouselWrapper.find('.faculty-items li'),
            facultyProfileCount = facultyProfilePanel.length,
            viewPortSize   = $(window).width(),
            carousel = carouselWrapper.find('.faculty-items'),
            position = 0,
            currentSlide = parseInt(carouselWrapper.attr('data-slide'));
    
        // Check if dataslide is less than the total slides
        if (currentSlide < facultyProfileCount - 1) 
            // Increment current slide
            currentSlide++;
            // Assign CSS position to clicked slider
            var transformPercentage = -1 * currentSlide / facultyProfileCount * 100;
            carousel.css('transform', 'translateX(' + transformPercentage + '% )');
    
            // Update data-slide attribute
            carouselWrapper.attr('data-slide', currentSlide);
            activeSlide = currentSlide;
        
    )
    
    
    function touchCarousel() 
        $('.faculty-carousel .faculty-items').each(function() 
    
            // create a simple instance
            // by default, it only adds horizontal recognizers
    
            var direction,
                touchSlider = this,
                mc = new Hammer.Manager(this),
                itemLength = $(this).find('li').length,
                count = 0,
                slide = $(this),
                timer;
    
            var sliderWrapper = slide,
                slideItems = sliderWrapper.find('li'),
                //slider = sliderWrapper.find('li'),
                totalPanels = slideItems.length,
                currentSlide = parseInt(sliderWrapper.attr('data-slide'));
    
            // mc.on("panleft panright", function(ev) 
            //   direction = ev.type;
            // );
    
            mc.add(new Hammer.Pan(
                threshold: 0,
                pointers: 0
            ));
            
            mc.on('pan', function(e) 
                var percentage = 100 / totalPanels * e.deltaX / window.innerWidth;
                var transformPercentage = percentage - 100 / totalPanels * activeSlide;
                touchSlider.style.transform = 'translateX( ' + transformPercentage + '% )';
                var sliderWrapper = $(e.target).closest('.faculty-carousel')
    
    
                if (e.isFinal)  // NEW: this only runs on event end
    
                    var newSlide = activeSlide;
                    if (percentage < 0)
                        newSlide = activeSlide + 1;
                    else if (percentage > 0)
                        newSlide = activeSlide - 1;
                    goToSlide(newSlide, sliderWrapper);
                
            );
    
    
            var goToSlide = function(number, sliderWrapper) 
                if (number < 0)
                    activeSlide = 0;
                else if (number > totalPanels - 1)
                    activeSlide = totalPanels - 1
                else
                    activeSlide = number;
    
                sliderWrapper.attr('data-slide', activeSlide);
    
                touchSlider.classList.add('slide-animation');
                var percentage = -(100 / totalPanels) * activeSlide;
                touchSlider.style.transform = 'translateX( ' + percentage + '% )';
                timer = setTimeout(function() 
                    touchSlider.classList.remove('slide-animation');
                , 400);
    
            ;
        );
    
    
    
    function panelSizing() 
    
        // var activeSlide = 0;
        // $('.faculty-carousel').attr('data-slide', '0');
    
    
        var viewPortSize        = $(window).width(),
            carouselWrapper = $('.faculty-carousel')
        ;
        
        //Set Panel Size based on viewport
    
        if (viewPortSize <= 1920 ) 
            var profilePanelSize = viewPortSize / 5
        
    
    
        if (viewPortSize < 1024 ) 
            var profilePanelSize = viewPortSize / 4
        
    
        if (viewPortSize < 768 ) 
            var profilePanelSize = viewPortSize / 3
         
    
        if (viewPortSize < 480 ) 
            var profilePanelSize = viewPortSize
        
        
        carouselWrapper.each(function()
            var wrapper = $(this);
            // wrapper.attr('data-slide', '0');
    
            var facultyPanel = wrapper.find('.faculty-items li'),
            profileCount = facultyPanel.length,
            // activeSlide         = 0,
            carousel            = wrapper.find('.faculty-items');
    
            carousel.outerWidth( profilePanelSize * profileCount );
            facultyPanel.outerWidth(profilePanelSize);
            carousel.css('transform', 'translateX(' + 0 + '% )');
        );
    
    
    $('.tile-layout').on('click', function() 
        $('.faculty-items').each(function() 
            $(this).addClass('tile-view');
            $('.faculty-carousel .faculty-items').css('transform', 'translateX(' + 0 + '% )');
        )
    );
    
    $('.slider-layout').on('click', function() 
        $('.faculty-items').each(function() 
            $(this).removeClass('tile-view');
        )
    )
    
    
    $(document).ready(function() 
        panelSizing();
        touchCarousel()
    
    )
    
    $(window).on('resize', function()
        panelSizing();
        touchCarousel()
    
    )
html, body, div, span, applet, object, iframe,
    h1, h2, h3, h4, h5, h6, p, blockquote, pre,
    a, abbr, acronym, address, big, cite, code,
    del, dfn, em, img, ins, kbd, q, s, samp,
    small, strike, strong, sub, sup, tt, var,
    b, u, i, center,
    dl, dt, dd, ol, ul, li,
    fieldset, form, label, legend,
    table, caption, tbody, tfoot, thead, tr, th, td,
    article, aside, canvas, details, embed,
    figure, figcaption, footer, header, hgroup,
    menu, nav, output, ruby, section, summary,
    time, mark, audio, video 
      margin: 0;
      padding: 0;
      border: 0;
      font-size: 100%;
      font: inherit;
      vertical-align: baseline; 
    
    /* HTML5 display-role reset for older browsers */
    article, aside, details, figcaption, figure,
    footer, header, hgroup, menu, nav, section 
      display: block; 
    
    body 
      line-height: 1; 
    
    ol, ul 
      list-style: none; 
    
    blockquote, q 
      quotes: none; 
    
    blockquote:before, blockquote:after,
    q:before, q:after 
      content: '';
      content: none; 
    
    table 
      border-collapse: collapse;
      border-spacing: 0; 
    
    .faculty-items.tile-view 
      display: flex !important;
      flex-wrap: wrap !important;
      width: 100% !important; 
    
    .faculty-items li 
      height: 100px;
      display: inline-block;
      position: relative; 
      .faculty-items li > a 
        position: absolute;
        top: 0;
        width: 100%;
        height: 100%;
        user-drag: none;
        user-select: none;
        -moz-user-select: none;
        -webkit-user-drag: none;
        -webkit-user-select: none;
        -ms-user-select: none; 
    
    .faculty-items li:nth-child(odd) 
      background-color: grey; 
    
    .faculty-items li:nth-child(even), .faculty-items a:nth-child(even) 
      background-color: aqua; 
    
    .faculty-items 
      overflow: hidden;
      position: relative;
      right: 0;
      display: flex;
      -webkit-transition: transform 0.3s linear; 
    
    .faculty-carousel .controls 
      display: block; 
    
    /*# sourceMappingURL=style.css.map */
    <link rel="stylesheet" href="style.css" />
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/hammer.js/2.0.8/hammer.js"></script>
    
    

    
    <div class="faculty-carousel">
        <ul class="faculty-items">
            <li><a href="#">Item 1</a></li>
            <li><a href="#">Item 2</a></li>
            <li><a href="#">Item 3</a></li>
            <li><a href="#">Item 4</a></li>
            <li><a href="#">Item 5</a></li>
            <li><a href="#">Item 6</a></li>
            <li><a href="#">Item 7</a></li>
            <li><a href="#">Item 8</a></li>
            <li><a href="#">Item 9</a></li>
            <li><a href="#">Item 10</a></li>
        </ul>
    
        <div class="controls">
            <div class="prev">
            prev
            </div>
    
            <div class="next">
            next
            </div>
        </div>
    </div>

    

【问题讨论】:

您要么忘记提问,要么只是想在Stack Overflow 上宣布您目前正在尝试解决的问题。哪一个?请阅读How to Ask 并将您的示例设为minimal reproducible example。在这种情况下,最小意味着:删除所有不必要的代码以重现您的问题 【参考方案1】:

向您的 div 添加一个标识符(例如 class="hammerOn" 类)。 将您的hammerjs 脚本绑定到此标识符。 使用窗口调整大小功能检查窗口的当前大小。 如果窗口大小达到您不希望启用hammerjs的大小,请删除该类。

基本思路:

$( window ).resize(function() 
   if (($(window).width() < yourprefwidth) && ($(window).height() < yourprefheight)) 
       $('#yourdiv').removeClass('hammerOn');
    else 
       $('#yourdiv').addClass('hammerOn');
   
);

【讨论】:

【参考方案2】:

您可以为此使用 css,

添加一些阻止用户点击的属性,检查下面的sn-p:

var activeSlide = 0;
    $('.faculty-carousel').attr('data-slide', '0');
    
    
    
    $('.tile-layout').on('click', function() 
        $('.faculty-items').each(function() 
            $(this).addClass('tile-view');
        )
    )
    
    
    $('.prev').on('click', function(e) 
        event.stopPropagation();
    
        var carouselWrapper     = $(this).closest('.faculty-carousel'),
            facultyProfilePanel = carouselWrapper.find('.faculty-items li'),
            facultyProfileCount = facultyProfilePanel.length,
            viewPortSize        = $(window).width(),
            carousel            = carouselWrapper.find('.faculty-items'),
            position            = 0,
            currentSlide        = parseInt(carouselWrapper.attr('data-slide'));
    
        // Check if data-slide attribute is greater than 0
        if (currentSlide > 0) 
            // Decremement current slide
            currentSlide--;
            // Assign CSS position to clicked slider
            var transformPercentage = -1 * currentSlide / facultyProfileCount * 100;
            carousel.css('transform', 'translateX(' + transformPercentage + '% )');
    
            // Update data-slide attribute
            carouselWrapper.attr('data-slide', currentSlide);
            activeSlide = currentSlide;
        
    );
    
    $('.next').on('click', function(e) 
        event.stopPropagation();
        // store variable relevent to clicked slider
    
        var carouselWrapper     = $(this).closest('.faculty-carousel'),
            facultyProfilePanel = carouselWrapper.find('.faculty-items li'),
            facultyProfileCount = facultyProfilePanel.length,
            viewPortSize   = $(window).width(),
            carousel = carouselWrapper.find('.faculty-items'),
            position = 0,
            currentSlide = parseInt(carouselWrapper.attr('data-slide'));
    
        // Check if dataslide is less than the total slides
        if (currentSlide < facultyProfileCount - 1) 
            // Increment current slide
            currentSlide++;
            // Assign CSS position to clicked slider
            var transformPercentage = -1 * currentSlide / facultyProfileCount * 100;
            carousel.css('transform', 'translateX(' + transformPercentage + '% )');
    
            // Update data-slide attribute
            carouselWrapper.attr('data-slide', currentSlide);
            activeSlide = currentSlide;
        
    )
    
    
    function touchCarousel() 
        $('.faculty-carousel .faculty-items').each(function() 
    
            // create a simple instance
            // by default, it only adds horizontal recognizers
    
            var direction,
                touchSlider = this,
                mc = new Hammer.Manager(this),
                itemLength = $(this).find('li').length,
                count = 0,
                slide = $(this),
                timer;
    
            var sliderWrapper = slide,
                slideItems = sliderWrapper.find('li'),
                //slider = sliderWrapper.find('li'),
                totalPanels = slideItems.length,
                currentSlide = parseInt(sliderWrapper.attr('data-slide'));
    
            // mc.on("panleft panright", function(ev) 
            //   direction = ev.type;
            // );
    
            mc.add(new Hammer.Pan(
                threshold: 0,
                pointers: 0
            ));
            
            mc.on('pan', function(e) 
                var percentage = 100 / totalPanels * e.deltaX / window.innerWidth;
                var transformPercentage = percentage - 100 / totalPanels * activeSlide;
                touchSlider.style.transform = 'translateX( ' + transformPercentage + '% )';
                var sliderWrapper = $(e.target).closest('.faculty-carousel')
    
    
                if (e.isFinal)  // NEW: this only runs on event end
    
                    var newSlide = activeSlide;
                    if (percentage < 0)
                        newSlide = activeSlide + 1;
                    else if (percentage > 0)
                        newSlide = activeSlide - 1;
                    goToSlide(newSlide, sliderWrapper);
                
            );
    
    
            var goToSlide = function(number, sliderWrapper) 
                if (number < 0)
                    activeSlide = 0;
                else if (number > totalPanels - 1)
                    activeSlide = totalPanels - 1
                else
                    activeSlide = number;
    
                sliderWrapper.attr('data-slide', activeSlide);
    
                touchSlider.classList.add('slide-animation');
                var percentage = -(100 / totalPanels) * activeSlide;
                touchSlider.style.transform = 'translateX( ' + percentage + '% )';
                timer = setTimeout(function() 
                    touchSlider.classList.remove('slide-animation');
                , 400);
    
            ;
        );
    
    
    
    function panelSizing() 
    
        // var activeSlide = 0;
        // $('.faculty-carousel').attr('data-slide', '0');
    
    
        var viewPortSize        = $(window).width(),
            carouselWrapper = $('.faculty-carousel')
        ;
        
        //Set Panel Size based on viewport
    
        if (viewPortSize <= 1920 ) 
            var profilePanelSize = viewPortSize / 5
        
    
    
        if (viewPortSize < 1024 ) 
            var profilePanelSize = viewPortSize / 4
        
    
        if (viewPortSize < 768 ) 
            var profilePanelSize = viewPortSize / 3
         
    
        if (viewPortSize < 480 ) 
            var profilePanelSize = viewPortSize
        
        
        carouselWrapper.each(function()
            var wrapper = $(this);
            // wrapper.attr('data-slide', '0');
    
            var facultyPanel = wrapper.find('.faculty-items li'),
            profileCount = facultyPanel.length,
            // activeSlide         = 0,
            carousel            = wrapper.find('.faculty-items');
    
            carousel.outerWidth( profilePanelSize * profileCount );
            facultyPanel.outerWidth(profilePanelSize);
            carousel.css('transform', 'translateX(' + 0 + '% )');
        );
    
    
    $('.tile-layout').on('click', function() 
        $('.faculty-items').each(function() 
            $(this).addClass('tile-view');
            $('.faculty-carousel .faculty-items').css('transform', 'translateX(' + 0 + '% )');
        )
    );
    
    $('.slider-layout').on('click', function() 
        $('.faculty-items').each(function() 
            $(this).removeClass('tile-view');
        )
    )
    
    
    $(document).ready(function() 
        panelSizing();
        touchCarousel()
    
    )
    
    $(window).on('resize', function()
        panelSizing();
        touchCarousel()
    
    )
html, body, div, span, applet, object, iframe,
    h1, h2, h3, h4, h5, h6, p, blockquote, pre,
    a, abbr, acronym, address, big, cite, code,
    del, dfn, em, img, ins, kbd, q, s, samp,
    small, strike, strong, sub, sup, tt, var,
    b, u, i, center,
    dl, dt, dd, ol, ul, li,
    fieldset, form, label, legend,
    table, caption, tbody, tfoot, thead, tr, th, td,
    article, aside, canvas, details, embed,
    figure, figcaption, footer, header, hgroup,
    menu, nav, output, ruby, section, summary,
    time, mark, audio, video 
      margin: 0;
      padding: 0;
      border: 0;
      font-size: 100%;
      font: inherit;
      vertical-align: baseline; 
    
    /* HTML5 display-role reset for older browsers */
    article, aside, details, figcaption, figure,
    footer, header, hgroup, menu, nav, section 
      display: block; 
    
    body 
      line-height: 1; 
    
    ol, ul 
      list-style: none; 
    
    blockquote, q 
      quotes: none; 
    
    blockquote:before, blockquote:after,
    q:before, q:after 
      content: '';
      content: none; 
    
    table 
      border-collapse: collapse;
      border-spacing: 0; 
    
    .faculty-items.tile-view 
      display: flex !important;
      flex-wrap: wrap !important;
      width: 100% !important; 
    
    .faculty-items li 
      height: 100px;
      display: inline-block;
      position: relative; 
      .faculty-items li > a 
        position: absolute;
        top: 0;
        width: 100%;
        height: 100%;
        user-drag: none;
        user-select: none;
        -moz-user-select: none;
        -webkit-user-drag: none;
        -webkit-user-select: none;
        -ms-user-select: none; 
    
    .faculty-items li:nth-child(odd) 
      background-color: grey; 
    
    .faculty-items li:nth-child(even), .faculty-items a:nth-child(even) 
      background-color: aqua; 
    
    .faculty-items 
      overflow: hidden;
      position: relative;
      right: 0;
      display: flex;
      -webkit-transition: transform 0.3s linear; 
    
    .faculty-carousel .controls 
      display: block; 
    
    /*# sourceMappingURL=style.css.map */

/* BELOW PROPERTIES WILL PREVENT USER TOCH AND THE BUTTONS TO BE CLICKED OR TOCHED AT SPECIFIC VIEWPORT */

@media (max-width: 767px) 
    .faculty-items 
      user-select: none;
      pointer-events: none;
     
     .faculty-carousel .controls 
      user-select: none;
      pointer-events: none;
     
<link rel="stylesheet" href="style.css" />
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/hammer.js/2.0.8/hammer.js"></script>
    
    

    
    <div class="faculty-carousel">
        <ul class="faculty-items">
            <li><a href="#">Item 1</a></li>
            <li><a href="#">Item 2</a></li>
            <li><a href="#">Item 3</a></li>
            <li><a href="#">Item 4</a></li>
            <li><a href="#">Item 5</a></li>
            <li><a href="#">Item 6</a></li>
            <li><a href="#">Item 7</a></li>
            <li><a href="#">Item 8</a></li>
            <li><a href="#">Item 9</a></li>
            <li><a href="#">Item 10</a></li>
        </ul>
    
        <div class="controls">
            <div class="prev">
            prev
            </div>
    
            <div class="next">
            next
            </div>
        </div>
    </div>

【讨论】:

以上是关于如何在特定视口上设置触摸手势/hammer.js 处于活动状态?的主要内容,如果未能解决你的问题,请参考以下文章

使用 Hammer.js 时移动 Safari 崩溃

Hammer.js 在 Angular 中向左滑动手势动画

移动端手势事件 hammer.JS插件

flutter web中如何区分手指触摸手势和鼠标指针手势?

Hammer.js分析——manager.js

使用jquery.hammer.js时如何返回X和Y坐标