jQuery - 更新脚本以支持触屏设备(滚动视图)

7

我一直在使用jQuery scroll view。这个脚本似乎不支持触屏操作,所以我花了大部分时间来尝试想出如何将触摸支持添加到脚本中。

我考虑过切换到jQuery拖动功能,但它似乎不能像上面的脚本那样工作。

请问有人能给我一些关于如何添加触摸支持的指导或提示吗?


你好,你不应该使用 .mousedown()、.mousemove() 等 jQuery 方法,而是应该使用 on() 方法:this.i.on({ 'mousedown touchstart': function(e){ self.startgrab(); this.xp = e.pageX; this.yp = e.pageY; return false; }, 'mousemove touchmove': function(e){ if (!self.isgrabbing) return true; self.scrollTo(this.xp - e.pageX, this.yp - e.pageY); this.xp = e.pageX; this.yp = e.pageY; return false; }, ... });此外,你不应该使用 userAgent 进行检测,而应该使用对象和特性检测。 - laruiss
Lauriss如果您能够扩展您的代码并提供一个可行的解决方案,那将是完美的。我使用了您上面提供的示例代码并完成了您留下的功能......问题是,脚本在触摸屏上仍然无法正常工作。即使在电脑上可以拖动,但我无法在触摸屏上拖动物品。我认为这与脚本早期设置的抓取事件有关,尽管我不确定。您怎么看? - Zach Nicodemous
你能提供一个在台式机/笔记本电脑上工作但在触摸设备上无法工作的示例吗? - laruiss
是的。请查看http://increstedbutte.com/ - 主要背景图像使用scrollview。在台式电脑/笔记本电脑上运行良好,但在触摸设备上无法正常工作(我已经在我的Galaxy S4和Google Nexus 7上尝试过)。 - Zach Nicodemous
如果您能帮助解决问题,我可以提供相应的赏金。 - Zach Nicodemous
5个回答

2
使用jquery.mouse2touch.min.js插件来模拟触摸事件的鼠标事件。

工作演示

注意:我看到您对原始插件jquery.scrollview.js进行了一些代码更改以添加触摸事件。请使用原始插件,$("#elment").mouse2touch()将鼠标事件处理程序行为应用于触摸事件。

应用此修复的步骤

以下是代码

<!DOCTYPE html>
<html>

<head>
  <link rel="stylesheet" href="//increstedbutte.com/wp-content/themes/crestedbutte/style.css" />
</head>

<body>
  <h1>Scroll Demo Plunker!</h1>
  <div id="map">
    <div id="spring" style="opacity: 1;">
      <img width="3800" height="1200" src="http://increstedbutte.com/wp-content/uploads/2013/07/crested-butte-town-map_spring-v2.jpg" class="attachment- wp-post-image" alt="Crested Butte Town Map - Spring">
    </div>
  </div>
  <script src="//cdnjs.cloudflare.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
  <script src="//jquery-scrollview.googlecode.com/svn-history/r2/trunk/jquery.scrollview.js"></script>
  <script src="//cdn.rawgit.com/vpanga/jquery.mouse2touch/master/src/jquery.mouse2touch.min.js"></script>
  <script>
    $(function() {
      $("#map").scrollview().mouse2touch();
    });
  </script>
</body>

</html>


添加了 jquery.mouse2touch.min.js 的 Github 源代码。 - Koti Panga
感谢您提供的可行解决方案!我已将您的问题标记为正确,并尝试授予您赏金,但是此选项已从我的屏幕上消失。我正在联系StackOverflow查询此事。 - Zach Nicodemous
1
@ZachNicodemous 非常欢迎,很高兴能帮到你。我们正在使用上述的mouse2touch插件来为许多应用程序提供良好的jQuery鼠标事件模拟触摸功能。还要感谢你对悬赏奖励的关注。 - Koti Panga
将参考文献 jquery.mouse2touch.js 更新至新的代码库。 - Koti Panga

2
只需添加一些触摸事件到鼠标事件的转换层,就像这样:

https://github.com/danielglyde/TouchIt

在您的代码中添加$("#yourElement").touchIt();调用,将转换该对象的每个触摸事件为鼠标事件,这样每个触摸开始都会被翻译成为一个鼠标按下事件等等,从而完美地工作。
但是请注意,如果您的可触摸表面太大,可能会阻止用户滚动页面。[ https://code.google.com/p/android/issues/detail?id=19827 ]

我不确定如何将此插件应用于现有的Scrollview脚本。你能给予建议吗? - Zach Nicodemous
@ZachNicodemous 只需将您的脚本保持不变,在页面头部添加TouchIt库的链接,并在页面上的某个脚本中添加 $("#yourElement").touchIt();(假设 <div id="yourElement"> 是应处理触摸事件的页面部分)。 - FrancescoMM

1
最近有人教我如何使用hammer.js来检测滑动触摸屏事件,通过这种方式,我可以修改任何以前不支持触摸移动事件的滑块框架的默认行为。或者有时可以使用它来分离交换层以显示某些情况下的不透明度控制。
我感觉它很容易与其他框架集成。

/**
 * requestAnimationFrame and cancel polyfill
 */
(function() {
  var lastTime = 0;
  var vendors = ['ms', 'moz', 'webkit', 'o'];
  for(var x = 0; x < vendors.length && !window.requestAnimationFrame; ++x) {
    window.requestAnimationFrame = window[vendors[x]+'RequestAnimationFrame'];
    window.cancelAnimationFrame =
      window[vendors[x]+'CancelAnimationFrame'] || window[vendors[x]+'CancelRequestAnimationFrame'];
  }
  
  if (!window.requestAnimationFrame)
    window.requestAnimationFrame = function(callback, element) {
      var currTime = new Date().getTime();
      var timeToCall = Math.max(0, 16 - (currTime - lastTime));
      var id = window.setTimeout(function() { callback(currTime + timeToCall); },
                                 timeToCall);
      lastTime = currTime + timeToCall;
      return id;
    };
  
  if (!window.cancelAnimationFrame)
    window.cancelAnimationFrame = function(id) {
      clearTimeout(id);
    };
}());


/**
    * super simple carousel
    * animation between panes happens with css transitions
    */
function Carousel(element)
{
  var self = this;
  element = $(element);
  
  var container = $(">ul", element);
  var panes = $(">ul>li", element);
  
  var pane_width = 0;
  var pane_height = 0;
  var pane_count = panes.length;
  
  var current_pane = 0;
  var carousel_bottom = 0;
  var carousel_top = 0;
  var carousel_head = 85;
  
  var is_expanded;
  
  var _ypos;
  
  
  /**
   * initial
   */
  this.init = function() {
    setPaneDimensions();
    
    $(window).on("load resize orientationchange", function() {
      setPaneDimensions();
      //updateOffset();
    })
  };      
      
  /**
   * set the pane dimensions and scale the container
   */
  function setPaneDimensions() {
    pane_width = element.width();
    panes.each(function() {
      $(this).width(pane_width);
    });
    container.width(pane_width*pane_count);
    
    // Set start point
    carousel_top = $(window).height() - carousel_head;       
    setContainerOffsetY(carousel_top);    
    is_expanded = false;
  };
      
      
  this.updatePaneDimensions = function() {
    var panes = $(">ul>li", element);
    var paneWidth = panes.first().width();
    
    var containerWidth = paneWidth*panes.length;
    
    $(container).css('width', containerWidth);            
    
    // update pane count
    pane_count = panes.length;  
    
    // reset current pane
    this.showPane(current_pane, false);        
  }
  
      
  /**
   * show pane by index
   * @param   {Number}    index
   */
  this.showPane = function(index, animate) {
    // between the bounds
    index = Math.max(0, Math.min(index, pane_count-1));
    current_pane = index;
    
    var offset = -((100/pane_count)*current_pane);
    
    setContainerOffset(offset, true);
  }                
    
  function setContainerOffset(percent, animate) {
    container.removeClass("animate");
    
    if(animate) {
      container.addClass("animate");
    }
    
    var px = ((pane_width * pane_count) / 100) * percent;
    
    if(Modernizr.csstransforms3d) {
      container.css("transform", "translate3d("+ percent +"%,0,0) scale3d(1,1,1)");                        
    }
    else if(Modernizr.csstransforms) {
      container.css("transform", "translate("+ percent +"%,0)");
    }
      else {
        var px = ((pane_width*pane_count) / 100) * percent;
        container.css("left", px+"px");
      }
  }

  function setContainerOffsetY(ypos, animate) {
        
    element.removeClass("animate");
    
    if (animate) {
      element.addClass("animate");
    }
    
    _ypos = ypos;
    
    if(Modernizr.csstransforms3d) {      
      element.css("transform", "translate3d(0," + ypos + "px,0) scale3d(1,1,1)");                              
    }
    else if(Modernizr.csstransforms) {
      element.css("transform", "translate(0," + ypos + "px)");
    } 
    else {
      element.css("top", ypos + "px");      
    }
  }
  
  this.next = function() { return this.showPane(current_pane+1, true); };
  this.prev = function() { return this.showPane(current_pane-1, true); };
  
  this.togglePane = function(expand) {
    
    // TODO: 'expand'
    
    if (!is_expanded) {
      // Expand
      self.expand();
    } else {
      // Collapse
      self.collapse();
    }
  }
  
  this.expand = function() {
    setContainerOffsetY(carousel_head, true);    
    is_expanded = true;
  }  
  
  this.collapse = function() {
    setContainerOffsetY(carousel_top, true);        
    is_expanded = false;
  }  
  
  this.throttledTogglePane = _.debounce(self.togglePane, 100);
  
  this.throttledShowPane = _.debounce(function() {
     self.expand();    
  }, 100);
  
  this.throttledHidePane = _.debounce(function() {
    self.collapse();
  }, 100);         
  
  function handleHammer(ev) { 
    
    // disable browser scrolling
    ev.gesture.preventDefault();
    
    switch(ev.type) {
      case 'dragright':
      case 'dragleft':
        // stick to the finger
        var pane_offset = -(100/pane_count) * current_pane;
        var drag_offset = ((100/pane_width) * ev.gesture.deltaX) / pane_count;
        
        // slow down at the first and last pane
        if((current_pane == 0  && ev.gesture.direction == Hammer.DIRECTION_RIGHT) ||
           (current_pane == pane_count-1 && ev.gesture.direction == Hammer.DIRECTION_LEFT)) {
          drag_offset *= .4;
        }
        
        setContainerOffset(drag_offset + pane_offset);
        break;
        
      case 'swipeleft':
        self.next();
        ev.gesture.stopDetect();
        break;
        
      case 'swiperight':
        self.prev();
        ev.gesture.stopDetect();
        break;
        
      case 'release':
        // Left & Right
        // more then 50% moved, navigate
        if(Math.abs(ev.gesture.deltaX) > pane_width/2) {
          if(ev.gesture.direction == 'right') {
            self.prev();
          } else {
            self.next();
          }                        
        }
        else {
          self.showPane(current_pane, true);                                                
        }
                
        if ((ev.gesture.direction == "up") || (ev.gesture.direction == "down")) {
          
          var windowHalf = ($(window).height() - (carousel_head * 2)) / 4;
          
          if(Math.abs(ev.gesture.deltaY) > windowHalf) {                      
            if (is_expanded) {
              self.collapse();
            } else {
              self.expand();               
            }            
          } 
          else { 
            if (is_expanded) {
              self.expand();              
            } else {
              self.collapse();                               
            }
          } 
        }        
        
        break;
        
      case 'tap':
        self.throttledTogglePane();
        ev.gesture.stopDetect();
        break;       
        
      case 'dragup':
        var drag_offset = carousel_top + ev.gesture.deltaY;
        
        if (is_expanded) {          
          drag_offset = carousel_head + ev.gesture.deltaY;
//           drag_offset *= .4;
        }

        setContainerOffsetY(drag_offset);
        break;
        
      case 'dragdown':        
        var drag_offset = carousel_head + ev.gesture.deltaY;  
        
        if (!is_expanded) {
          console.log('not expanded', carousel_top, ev.gesture.deltaY)
          drag_offset = carousel_top + ev.gesture.deltaY;
        }
        
        setContainerOffsetY(drag_offset);
        break;
       
      case 'swipeup':
        console.log('swipeup')
        self.throttledShowPane();
        ev.gesture.stopDetect();
        break;        
        
      case 'swipedown':
        console.log('swipedown')
        self.throttledHidePane();
        ev.gesture.stopDetect();
        break;
    }
  }
  
  element.hammer({ drag_lock_to_axis: true })
  .on("tap release dragleft dragright swipeleft swiperight dragup dragdown swipeup swipedown", handleHammer);  
}

var carousel = new Carousel("#carousel");
carousel.init();
html,
body {
  padding: 0;
  margin: 0;  
  overflow: hidden;
  height: 100%;
  
  /* via http://lea.verou.me/css3patterns/#seigaiha */
  background-color:#ddd;
  background-image: 
    radial-gradient(circle at 100% 150%, #ddd 24%, white 25%, white 28%, #ddd 29%, #ddd 36%, white 36%, white 40%, transparent 40%, transparent),
    radial-gradient(circle at 0    150%, #ddd 24%, white 25%, white 28%, #ddd 29%, #ddd 36%, white 36%, white 40%, transparent 40%, transparent),
    radial-gradient(circle at 50%  100%, white 10%, #ddd 11%, #ddd 23%, white 24%, white 30%, #ddd 31%, #ddd 43%, white 44%, white 50%, #ddd 51%, #ddd 63%, white 64%, white 71%, transparent 71%, transparent),
    radial-gradient(circle at 100% 50%, white 5%, #ddd 6%, #ddd 15%, white 16%, white 20%, #ddd 21%, #ddd 30%, white 31%, white 35%, #ddd 36%, #ddd 45%, white 46%, white 49%, transparent 50%, transparent),
    radial-gradient(circle at 0    50%, white 5%, #ddd 6%, #ddd 15%, white 16%, white 20%, #ddd 21%, #ddd 30%, white 31%, white 35%, #ddd 36%, #ddd 45%, white 46%, white 49%, transparent 50%, transparent); 
  background-size:100px 50px;  
}


#carousel, #carousel li {
  padding: 0;
  margin: 0;
  position: relative;            
}

#carousel {
/*   position: absolute;
  top: 0;
  left: 0; */
}

#carousel ul {
  padding: 0;
  margin: 0;
  position: relative;
}        

#carousel {            
/*   overflow: hidden; */
  width:100%;
  -webkit-backface-visibility: hidden;
  -webkit-transform: translate3d(0,0,0) scale3d(1,1,1);
  -webkit-transform-style: preserve-3d;
}

#carousel.animate {
  -webkit-transition: all .15s;
  -moz-transition: all .15s;
  -o-transition: all .15s;
  transition: all .15s;
}


#carousel ul.animate {
  -webkit-transition: all .3s;
  -moz-transition: all .3s;
  -o-transition: all .3s;
  transition: all .3s;
}

#carousel ul {
  transform: translate3d(0%,0,0) scale3d(1,1,1);
  -o-transform: translate3d(0%,0,0) scale3d(1,1,1);
  -ms-transform: translate3d(0%,0,0) scale3d(1,1,1);
  -moz-transform: translate3d(0%,0,0) scale3d(1,1,1);
  -webkit-transform: translate3d(0%,0,0) scale3d(1,1,1);
  overflow: hidden;
  -webkit-backface-visibility: hidden;
  -webkit-transform-style: preserve-3d;
}

#carousel ul {
  -webkit-box-shadow: 0 0 20px rgba(0,0,0,.2);
  box-shadow: 0 0 20px rgba(0,0,0,.2);
  position: relative;
}

#carousel li {
  float: left;
  overflow: hidden;
  -webkit-transform-style: preserve-3d;
  -webkit-transform: translate3d(0,0,0);
}

#carousel li {
  /*height: 85px;*/
  background: #fff;
  opacity: .8;
}

/* Sugar */

#carousel li h2 {
  color: #000;
  font-size: 30px;
  text-align: center;
/*  position: absolute;
  top: 40%;
  left: 0;
*/  
  width: 100%;
  height: 85px;
  text-shadow: -1px -1px 0 rgba(0,0,0,.2);
}

#carousel li p {
  padding: 0 20px;
}
<html>
<head>
    <title>Hammer.js Carousel</title>
    
    <meta name="viewport" content="user-scalable=no, width=device-width, initial-scale=1, maximum-scale=1">
</head>

<body>

    <div id="carousel">
        <ul>
          <li class="pane1">
            <h2>Swipe <small>left, right, up or down..</small></h2>
            <p>DIY Shoreditch chambray ugh American Apparel fingerstache. Literally keytar cardigan pour-over letterpress kogi, direct trade Brooklyn Blue Bottle tousled. Cred typewriter flexitarian street art bitters forage, Tonx pour-over aesthetic meh quinoa dreamcatcher Brooklyn. 90's master cleanse beard, letterpress stumptown messenger bag sustainable kogi banjo. Kogi mixtape artisan fashion axe Odd Future vegan. Dreamcatcher scenester you probably haven't heard of them, art party Williamsburg chillwave Etsy Helvetica photo booth ethical gluten-free pop-up Schlitz distillery pickled. Thundercats actually hoodie, Helvetica art party whatever YOLO bespoke pop-up Odd Future freegan Pitchfork Etsy literally.</p>
            <p>Roof party blog lo-fi banh mi mixtape fingerstache.  Deep v Neutra locavore kale chips.  Fap PBR meggings, master cleanse trust fund four loko semiotics pickled gastropub umami.  Etsy kale chips asymmetrical skateboard food truck.  Direct trade  American Apparel Blue Bottle lo-fi raw denim.  Pitchfork disrupt paleo vinyl food truck vegan, yr cardigan whatever lo-fi 3 wolf moon craft beer biodiesel literally mustache.  Hella scenester Neutra XOXO, YOLO iPhone raw denim swag Vice.</p><p>Plaid kitsch tofu, Cosby sweater Godard sriracha Thundercats kogi swag paleo hella hashtag cred beard.  Messenger bag jean shorts meh gastropub.  Banksy tattooed photo booth, viral Vice quinoa keytar fingerstache stumptown single-origin coffee chia.  +1 hella 8-bit sriracha ennui pork belly, Bushwick artisan Echo Park swag meh pour-over plaid quinoa fingerstache.  Before they sold out semiotics leggings stumptown, post-ironic XOXO actually brunch fanny pack food truck PBR iPhone chambray High Life.  Ugh selfies freegan quinoa, PBR Shoreditch sartorial Odd Future salvia pug keffiyeh ethnic blog.  Squid twee Brooklyn, banjo ugh salvia gluten-free.</p>
            <p>Roof party blog lo-fi banh mi mixtape fingerstache.  Deep v Neutra locavore kale chips.  Fap PBR meggings, master cleanse trust fund four loko semiotics pickled gastropub umami.  Etsy kale chips asymmetrical skateboard food truck.  Direct trade  American Apparel Blue Bottle lo-fi raw denim.  Pitchfork disrupt paleo vinyl food truck vegan, yr cardigan whatever lo-fi 3 wolf moon craft beer biodiesel literally mustache.  Hella scenester Neutra XOXO, YOLO iPhone raw denim swag Vice.</p><p>Plaid kitsch tofu, Cosby sweater Godard sriracha Thundercats kogi swag paleo hella hashtag cred beard.  Messenger bag jean shorts meh gastropub.  Banksy tattooed photo booth, viral Vice quinoa keytar fingerstache stumptown single-origin coffee chia.  +1 hella 8-bit sriracha ennui pork belly, Bushwick artisan Echo Park swag meh pour-over plaid quinoa fingerstache.  Before they sold out semiotics leggings stumptown, post-ironic XOXO actually brunch fanny pack food truck PBR iPhone chambray High Life.  Ugh selfies freegan quinoa, PBR Shoreditch sartorial Odd Future salvia pug keffiyeh ethnic blog.  Squid twee Brooklyn, banjo ugh salvia gluten-free.</p>
          </li>
          <li class="pane2">
            <h2>...or drag...</h2>
              <p>Occupy Thundercats sriracha, DIY Shoreditch chambray ugh American Apparel fingerstache. Literally keytar cardigan pour-over letterpress kogi, direct trade Brooklyn Blue Bottle tousled. Cred typewriter flexitarian street art bitters forage, Tonx pour-over aesthetic meh quinoa dreamcatcher Brooklyn. 90's master cleanse beard, letterpress stumptown messenger bag sustainable kogi banjo. Kogi mixtape artisan fashion axe Odd Future vegan. Dreamcatcher scenester you probably haven't heard of them, art party Williamsburg chillwave Etsy Helvetica photo booth ethical gluten-free pop-up Schlitz distillery pickled. Thundercats actually hoodie, Helvetica art party whatever YOLO bespoke pop-up Odd Future freegan Pitchfork Etsy literally.</p>
              <p>Roof party blog lo-fi banh mi mixtape fingerstache.  Deep v Neutra locavore kale chips.  Fap PBR meggings, master cleanse trust fund four loko semiotics pickled gastropub umami.  Etsy kale chips asymmetrical skateboard food truck.  Direct trade  American Apparel Blue Bottle lo-fi raw denim.  Pitchfork disrupt paleo vinyl food truck vegan, yr cardigan whatever lo-fi 3 wolf moon craft beer biodiesel literally mustache.  Hella scenester Neutra XOXO, YOLO iPhone raw denim swag Vice.</p><p>Plaid kitsch tofu, Cosby sweater Godard sriracha Thundercats kogi swag paleo hella hashtag cred beard.  Messenger bag jean shorts meh gastropub.  Banksy tattooed photo booth, viral Vice quinoa keytar fingerstache stumptown single-origin coffee chia.  +1 hella 8-bit sriracha ennui pork belly, Bushwick artisan Echo Park swag meh pour-over plaid quinoa fingerstache.  Before they sold out semiotics leggings stumptown, post-ironic XOXO actually brunch fanny pack food truck PBR iPhone chambray High Life.  Ugh selfies freegan quinoa, PBR Shoreditch sartorial Odd Future salvia pug keffiyeh ethnic blog.  Squid twee Brooklyn, banjo ugh salvia gluten-free.</p>
            <p>Roof party blog lo-fi banh mi mixtape fingerstache.  Deep v Neutra locavore kale chips.  Fap PBR meggings, master cleanse trust fund four loko semiotics pickled gastropub umami.  Etsy kale chips asymmetrical skateboard food truck.  Direct trade  American Apparel Blue Bottle lo-fi raw denim.  Pitchfork disrupt paleo vinyl food truck vegan, yr cardigan whatever lo-fi 3 wolf moon craft beer biodiesel literally mustache.  Hella scenester Neutra XOXO, YOLO iPhone raw denim swag Vice.</p>
          </li>
            <li class="pane3"><h2>...or swipe...</h2></li>
            <li class="pane4"><h2>..or drag...</h2></li>
            <li class="pane5"><h2>Dit is het einde!</h2></li>
        </ul>
    </div>

    <script src="//cdnjs.cloudflare.com/ajax/libs/jquery/1.9.0/jquery.min.js"></script>
    <script src="//cdnjs.cloudflare.com/ajax/libs/lodash.js/2.4.1/lodash.min.js"></script>
    <script src="//cdnjs.cloudflare.com/ajax/libs/hammer.js/1.0.6/hammer.min.js"></script>
    <script src="http://www.dfjs.co.uk/slider/jquery.hammer.min.js"></script>
    <script src="//cdnjs.cloudflare.com/ajax/libs/modernizr/2.7.1/modernizr.min.js"></script>

</body>
</html>


1
我遇到了同样的问题。首先,我尝试使用jQuery UI并尝试使用可拖动功能,但这不是我想要的。然后我发现了一个名为pep的很棒的插件。它具有与jQuery UI相同的选项,但工作效果更好,并且可以在移动设备上使用,并具有动力学拖动效果。
在这里,您可以检查该脚本并查看演示http://pep.briangonzalez.org/ 希望这能帮助您 :)

0

如果您要切换到其他jQuery滚动脚本,请查看此链接,其中比较了许多滚动脚本。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接