TOGOUTECH

javascript - 鼠标点击和触摸的不同行为 - 触摸屏功能错误,但使用鼠标

coder 2025-01-20 原文

Stackoverflow 对当前版本的帮助太大了,但目前我完全迷失了方向,因为我不知道如何解决一个问题。我将非常感谢您的任何建议。

我有带参数的产品容器。它们出现在鼠标上:悬停(用 css 完成)。问题是如果有人点击手机,它会触发两个事件:点击和鼠标悬停。但我需要移动设备的不同行为。所以我使用了 stackoverflow 的解决方案,在那里我可以检查浏览器是否知道 touchstart 事件。在有人使用可触摸屏幕但使用鼠标之前,它工作正常。因此,该用户将单击容器,参数将显示出来,而不会重定向到产品详细信息。但是鼠标行为是错误的。

我需要的是,如果有人点击图片,它会首先显示参数,第二次点击时它会重定向到产品详细信息(不同的行为仅在点击按钮时会自动将用户重定向到产品详细信息)。但是如果有人使用鼠标,我们有 :hover 效果,所以即使第一次点击图片也可以将用户重定向到产品详细信息页面。

当前的 javascript 代码已被注释,因此存在在台式机和移动设备上运行良好的解决方法。但它不适用于带有带鼠标的可触摸屏幕的混合设备。注释代码是我在使用 mouseenter/mouseleave 函数添加变通方法时考虑解决方案的方式。这不适用于移动设备,因为它们也会触发这些事件。 touchstart/touchend 事件也有同样的问题。

有人可以帮忙吗?

/*var usedMouse = false;

$('.products-grid .container:not(.over)').mouseenter(function() {
  usedMouse = true;
});*/

$('.products-grid .container:not(.over)').tap(function(e) {
  if (!!('ontouchstart' in window)/* && !usedMouse*/) {
    // location change if already hovered or tap target is button
    if ($(this).hasClass('over') || $(e.target).hasClass('button')) {
      $(this).addClass('detail'); // add detail - disable hover effect on actual container
      return true;
    }

    e.preventDefault();
    e.stopPropagation();

    $('.products-grid .container').removeClass('over'); // remove all over effects
    $(this).addClass('over'); // add over effect to actual container
    return false; // do nothing because script made over effect
  }
});

/*$('.products-grid .container:not(.over)').mouseleave(function() {
  usedMouse = false;
});*/
.products-grid {
  width: 100%;
  text-align: center;
}
.products-grid .row,
.std .products-grid .row {
  margin: 0 0 0 -22px;
  text-align: left;
}
.products-grid .row > .leftcolumn {
  float: left;
  -webkit-box-sizing: border-box;
  -moz-box-sizing: border-box;
  box-sizing: border-box;
  width: 33.33%;
  margin: 0;
  padding: 0 0 0 22px;
}
.products-grid .row .product-image {
  overflow: hidden;
  display: block;
  -webkit-box-sizing: border-box;
  -moz-box-sizing: border-box;
  box-sizing: border-box;
  width: 100%;
  height: auto;
  border: 1px solid #c9d5d8;
}
.products-grid .row .product-image img {
  display: block;
  width: 100% !important;
  height: auto !important;
  margin: 0;
}
.products-grid .clear,
.std .products-grid .clear {
  clear: both;
  margin: 0;
}
.products-grid .container {
  position: relative;
  margin: 0 0 50px;
}
.products-grid .options-wrapper {
  position: relative;
  overflow: hidden;
  width: 100%;
  margin: 0;
  padding-top: 5px;
}
.products-grid .parameters,
.products-grid .container.detail > .options-wrapper > .parameters,
.products-grid .container.detail:hover > .options-wrapper > .parameters {
  position: absolute;
  left: 0;
  right: 0;
  -webkit-transition: all 250ms linear;
  -moz-transition: all 250ms linear;
  -ms-transition: all 250ms linear;
  -o-transition: all 250ms linear;
  transition: all 250ms linear;
  -webkit-transform: translateX(-100%);
  -moz-transform: translateX(-100%);
  -ms-transform: translateX(-100%);
  -o-transform: translateX(-100%);
  transform: translateX(-100%);
  margin-top: -5px;
  padding-top: 66px;
  background: #eff9ff;
}
.products-grid .container:hover > .options-wrapper > .parameters,
.products-grid .container.over > .options-wrapper > .parameters {
  -webkit-transform: translateX(0%);
  -moz-transform: translateX(0%);
  -ms-transform: translateX(0%);
  -o-transform: translateX(0%);
  transform: translateX(0%);
}
.products-grid .parameters .size-wrapper {
  height: auto;
  border-bottom: 0 none;
}
.products-grid .parameters span {
  overflow: hidden;
  float: left;
  -webkit-box-sizing: border-box;
  -moz-box-sizing: border-box;
  box-sizing: border-box;
  width: 50%;
  height: 33px;
  border-bottom: 1px solid #bdccd4;
  padding-left: 10px;
  white-space: nowrap;
  font-size: 13px;
  color: #5f727c;
  line-height: 30px;
}
.products-grid .name-box,
.std .products-grid .name-box {
  position: relative;
  margin: 0;
}
.products-grid h3,
.std .products-grid h3 {
  overflow: hidden;
  height: 42px;
  margin: 15px 12px 18px;
  white-space: normal;
  font-size: 18px;
  font-weight: 700;
  color: #000;
  line-height: 21px;
}
.products-grid h3 a {
  text-decoration: none;
  font-weight: bold;
  color: #000;
}
.products-grid h3 a:hover {
  text-decoration: none;
}
.products-grid .description {
  overflow: hidden;
  height: 40px;
  margin: 0 12px 11px;
  font-size: 14px;
  font-weight: 400;
  color: #81929c;
  line-height: 20px;
}
.products-grid .description p {
  margin: 0;
  padding: 0;
}
.price_wrapper,
.std .price_wrapper {
    margin: 0;
    border-top: 1px solid #bdccd4;
    border-bottom: 1px solid #bdccd4;
    padding: 9px 8px 10px;
}
.price_wrapper:after {
    content: ' ';
    clear: both;
    display: block;
}
.price_wrapper .addToCart {
  float: right;
}
.price_wrapper a.button {
  float: right;
  width: 136px;
  height: 39px;
  background-color: #a5c82d;
  text-align: center;
  text-decoration: none;
  font-size: 14px;
  font-weight: 700;
  color: #fff;
  line-height: 39px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<script src="http://ajax.googleapis.com/ajax/libs/jquerymobile/1.4.5/jquery.mobile.min.js"></script>
<div class="products-grid">
  <div class="row">
    <div class="leftcolumn">
      <div class="container">
        <a class="product-image" href="#">
          <img src="http://dummyimage.com/316x210/eee/333333.png" alt="product name" title="Product Name">
        </a>
        <div class="options-wrapper">
          <div class="parameters">
            <div class="size-wrapper">
              <span class="height">Height 95.2 cm</span>
              <span class="width">Width 210.5 cm</span>
              <span class="length">Length 187.5 cm</span>
              <span class="color"></span>
            </div>
          </div>

          <div class="name-box">
            <h3 class="product-name"><a href="#" title="Product Name">Product Name</a></h3>
          </div>

          <div class="description">Description</div>
        </div>
        <div class="price_wrapper">
          <a class="button" href="#">Detail</a>
        </div>
      </div>
    </div>
  </div>
</div>

最佳答案

这个解决方案帮助我解决了我的问题(感谢@booboos):

    // mark as mobile clicked
    $('.products-grid .container:not(.over)').touchstart(function() {
        this.mobileClick = true;
    });

    // unmark mobile click
    $('.products-grid .container:not(.over)').touchmove(function() {
        this.mobileClick = false;
    });

    // if mobile click is unmarked - delete mark property
    $('.products-grid .container:not(.over)').touchend(function() {
        if (this.mobileClick === false)
            delete this.mobileClick;
    });

    // check if there was mobile click and create new behavior for screen taps
    $('.products-grid .container:not(.over)').tap(function(e) {

        if (typeof this.mobileClick === 'undefined')
            return true;

        e.preventDefault();

        if (this.mobileClick === true) {
            if ($(this).hasClass('over') || $(e.target).hasClass('button')) {
                $(this).addClass('detail'); // add detail - disable hover effect on actual container
                window.location.href = $(this).find('.button').attr('href');
            }

            $('.products-grid .container').removeClass('over'); // remove all over effects
            $(this).addClass('over'); // add over effect to actual container

            delete this.mobileClick;
        }
    });
  1. touchstart 在触摸的容器元素上创建属性 mobileClick
  2. touchmove 将禁用该属性
  3. 如果之前有touchmove事件,touchend事件只是删除属性
  4. 点击容器将检查元素上是否有事件的 mobileClick 属性,如果存在 - 脚本将首先将类“over”添加到容器元素,如果容器有 over 类,那么下次它会将用户重定向到 detail页。此事件最后还会删除 mobileClick 属性。所以我可以确定下一次触摸是真正的触摸。

关于javascript - 鼠标点击和触摸的不同行为 - 触摸屏功能错误,但使用鼠标,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39327330/

有关javascript - 鼠标点击和触摸的不同行为 - 触摸屏功能错误,但使用鼠标的更多相关文章

  1. javascript - 无法在 Express 中呈现 swig 模板 - 2

    所以我正在尝试使用consolidate.js渲染swigtemplates使用express,但是当我尝试从另一个模板“扩展”一个模板时出现以下错误:Error:ENOENT,nosuchfileordirectory'//one.html在我的app.js文件中,我将swig设置为我的渲染引擎(仅包括相关代码):varconsolidate=require('consolidate');app.set('viewengine','html');app.set('views',__dirname+'/views');app.engine('.html',consolidate.swi

  2. Javascript:构造函数中的回调 - 2

    我正在尝试为一个对象编写OOjavascript,该对象具有昂贵的初始化过程,完成后会回调一个函数。问题在于调用者需要在回调例程中使用同一对象的函数,而该对象尚不存在://ctorforfooobjectfunctionfoo(callback){//doslowinitializationhere..//callbackwhendonecallback();};foo.prototype=function(){return{//doStuffmethoddoStuff:function(){alert('stuffdone');}};}();//instantiatethefooob

  3. 接口测试CURL复制以及postman的Code功能 - 2

    1.复制CURL在需要抓取url的网址中打开F12进行调试,打开Network  右键点击选择copy下的curlbash 2.postman导入打开postman点击import打开后就是下面这个页面选择Rawtext在下方的Pasterawtext粘贴上你需要请求的curl粘贴后点击高亮continue按钮 点击后会有新弹窗再点击import 保存后可直接send发送 3.postmancode生成 看了很多postman里自动生成code的教程,非常动心,但是打开自己的postman却没找到那个传说中在cookies旁边的code按钮。新版postman的code按钮如下图所示选择自己想

  4. javascript - 如何将以毫秒为单位的日期转换为 iso 格式的 javascript? - 2

    这个问题在这里已经有了答案:关闭10年前。PossibleDuplicate:HowdoIoutputanISO-8601formattedstringinJavascript?如果我有一个以毫秒为单位表示日期的整数,将其转换为iso格式的语法是什么?

  5. javascript - 在 javascript/DOM 中存储文本内容的最快和/或最干净的方法是什么? - 2

    按照目前的情况,这个问题不适合我们的问答形式。我们希望答案得到事实、引用或专业知识的支持,但这个问题可能会引发辩论、争论、投票或扩展讨论。如果您觉得这个问题可以改进并可能重新打开,visitthehelpcenter指导。关闭10年前。我通常会看到版本1,但我从事的一些开源项目使用版本2,而我过去也使用过版本3。有没有人有更优雅的解决方案,也许是更具可扩展性的解决方案?版本1:vartext1='thisismyscript\'scontent';版本2:Thisismycontentvartext1=$('#text1').html();版本3:vartext1=$('#text1'

  6. javascript - 优化javascript代码以使用整数运算 - 2

    有一些算法可以“非常好”地解决问题,前提是“非常好”意味着最小化浮点算术运算的数量以支持整数算术。以Bresenham'slinealgorithm为例为了弄清楚要填充哪些像素以便在Canvas上画一条线:这个人几乎只用了一些简单的整数运算就使整个过程变得可行。这种事情在很多情况下显然是好的。但是,在javascript中需要大量float学运算的操作值得担心吗?我知道就语言规范而言,一切都几乎是十进制数。我想知道是否实际上尝试让事情尽可能接近整数是否值得——浏览器是否进行了优化以使其值得? 最佳答案 您可以在javascript中

  7. javascript - 使用 YoutubeAPI 播放 youtube 视频直到特定时间并暂停 - 2

    有没有办法使用YoutubeAPI播放视频直到视频中的某个点然后暂停? 最佳答案 我修改了YouTubePlayerAPIReferenceforiframeEmbeds中的代码在一定秒数后暂停播放。Demo代码通过等待onPlayerStateChange事件来工作。当事件触发时,它会检查事件以查看它是否是PLAYING事件。如果是,它会计算从当前时间(getCurrentTime()方法)到所需暂停点(硬编码为stopPlayAt变量)的剩余时间。它设置一个Javascript计时器来等待该差异,然后向API传递一个命令以暂停视

  8. 第十四篇,STM32的CAN总线通信 - 2

    1.CAN总线的概念    CAN指的是控制器局域网网络(Controller Area Network),由德国博世汽车电子厂商开发出来。    CAN使用差分信号,具有较强的抗干扰能力和传输稳定性    CAN属于多主通信,网络中所有的节点都可以作为主设备进行通信    CAN的网络扩展极其方便,CAN网络中扩展了新的通信单元,网络中旧的单元和硬件无需任何改变。    CAN具有较强的纠错能力,可以发现传输中出现的错误,并对错误节点进行隔离;所有的单元都可以检测错误;检测出错误的单元会立即同时通知其他所有单元;正在发送消息的单元一旦检测出错误,会强制结束当前的发送。被强制结束发送的单元会不

  9. javascript - Chosen.js - 是否可以限制所选项目的数量? - 2

    我有一个客户想要为用户提供从列表中最多选择5个附加选项的选项。我喜欢Chosen.js的概念,但如何限制选择?我想一种解决方案是使用onChange来计算所选的数字,然后禁用剩余的数字,但是有没有更简洁的解决方案? 最佳答案 Chosen提供了一个max_selected_options来允许你这样做:$(".chzn-select").chosen({max_selected_options:5}); 关于javascript-Chosen.js-是否可以限制所选项目的数量?,我们在S

  10. javascript - 定义 Javascript 对象时出现 IE8 错误? - 2

    我知道IE8很麻烦,但我从未见过它给我带来如此麻烦。我想要做的就是定义一个Javascript对象,它会导致错误,停止在页面上运行所有脚本。错误是“预期的标识符、字符串或数字”,表明问题发生在我在下面定义属性“类”的地方。我见过无数的脚本都是这样定义对象的,那么为什么IE8会吐槽这个呢?我将违规代码隔离到此。将它单独放在HTML页面的头部并在IE8中运行它会导致我看到的问题。varatts={class:"trigger"}; 最佳答案 通过用引号引起来定义使用适当的数据类型,"class"

随机推荐