Hammer.js 中文教程(有 demo)

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Hammer.js 中文教程(有 demo)相关的知识,希望对你有一定的参考价值。

参考技术A 安卓触屏上,tap 和 click 可以同时触发,但是 click 会有 300ms 左右的延时

show demo

在指定的 DOM 区域内,一个手指轻拍或点击时触发该事件(类似 PC 端的 click),该事件最大点击时间为 250ms,如果超过 250ms 则按 press 事件处理

在指定的 DOM 区域内,这个事件相当于 PC 端的 Click 事件,不能包含任何的移动,最小按压时间为 500ms,常用于我们在手机上用的复制粘贴等功能

该事件事分别对以下事件进行监听并处理

在指定的 DOM 区域内,一个手指放下并移动事件,即触屏中的拖动事件

该事件事分别对以下事件进行监听并处理

在指定的 DOM 区域内,一个手指快速的在触屏上滑动,即平时用到最多的滑动事件

该事件事分别对以下事件进行监听并处理

在指定的 DOM 区域内,两个手指(默认为两个手指,多指触控需要单独设置)或多个手指相对(越来越近)移动或相向(越来越远)移动时事件

该事件事分别对以下事件进行监听并处理

在指定的 DOM 区域内,当两个手指或更多手指呈圆型旋转时触发

该事件事分别对以下事件进行监听并处理

hammer.js 提供了 tap , doubletap , press , horizontal pan , swipe 和多点触控的 pinch , rotate ,默认情况下 pinch 与 rotate 是禁用的,因为它们会阻塞元素,可以通过以下命令来启用。

默认的 pan 仅支持水平方向,可以选择启用全部方向,swipe 也可以启用垂直方向

建议使用 viewport meta 禁用双击/缩放功能,更多的控制网页,支持触摸操作的浏览器不需要这样做

hammer.js 能够通过配置选项 domEvents: true 触发 DOM 事件,它会使你的方法 stopPropagation(),所以可以使用事件委托,hammer.js 不会解除绑定的事件

垂直 pan 用于滚动页面,一些(旧)浏览器不会触发这个事件,所以 hammer.js 无法识别

Windows Phone 上的 IE10 和 IE11 在点击某个元素时会突出显示一个小点,添加这个 meta 来删除

hammer.js 会设置 user-select 来提高 PC 的平移体验,如果需要文本选择,需要在创建实例前执行此操作

该点击事件也被称为 “幽灵点击”(ghost click)

构造函数为 Hammer(htmlElement, [options]),options 将与默认选项 Hammer.defaults 合并

其值可为 compute, auto, pan-y, pan-x, none,默认选项会基于识别器为你选择一个正确值

默认禁用 DOM 事件,如果需要使用事件委托,需将其设为 true

接受一个布尔值,或返回布尔值的函数

改善交互事件操作的系列 css 属性

调用 Hammer() 的时候就安装了默认的识别器,如果建立一个新的 Manager,这些将被跳过

识别器的状态

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

【中文标题】如何在特定视口上设置触摸手势/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 中文教程(有 demo)的主要内容,如果未能解决你的问题,请参考以下文章

hammer.js学习

hammer.js初探

HTML5 使用 Hammer.js 拖动事件在 div 上拖放元素

使用 Hammer.js 捏缩放

hammer.js中文文档

使用 Hammer.js 时移动 Safari 崩溃