te')); return $arr; } /* 遍历用户所有主题 * @param $uid 用户ID * @param int $page 页数 * @param int $pagesize 每页记录条数 * @param bool $desc 排序方式 TRUE降序 FALSE升序 * @param string $key 返回的数组用那一列的值作为 key * @param array $col 查询哪些列 */ function thread_tid_find_by_uid($uid, $page = 1, $pagesize = 1000, $desc = TRUE, $key = 'tid', $col = array()) { if (empty($uid)) return array(); $orderby = TRUE == $desc ? -1 : 1; $arr = thread_tid__find($cond = array('uid' => $uid), array('tid' => $orderby), $page, $pagesize, $key, $col); return $arr; } // 遍历栏目下tid 支持数组 $fid = array(1,2,3) function thread_tid_find_by_fid($fid, $page = 1, $pagesize = 1000, $desc = TRUE) { if (empty($fid)) return array(); $orderby = TRUE == $desc ? -1 : 1; $arr = thread_tid__find($cond = array('fid' => $fid), array('tid' => $orderby), $page, $pagesize, 'tid', array('tid', 'verify_date')); return $arr; } function thread_tid_delete($tid) { if (empty($tid)) return FALSE; $r = thread_tid__delete(array('tid' => $tid)); return $r; } function thread_tid_count() { $n = thread_tid__count(); return $n; } // 统计用户主题数 大数量下严谨使用非主键统计 function thread_uid_count($uid) { $n = thread_tid__count(array('uid' => $uid)); return $n; } // 统计栏目主题数 大数量下严谨使用非主键统计 function thread_fid_count($fid) { $n = thread_tid__count(array('fid' => $fid)); return $n; } ?>javascript - Prevent click event after mousedown & mouseup event - Stack Overflow
最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - Prevent click event after mousedown & mouseup event - Stack Overflow

programmeradmin3浏览0评论

Is it possible with jQuery to prevent a click event on the same element from being executed, after a mousedown & mouseup event has just been fired.

Any help/examples would be appreciated.

Is it possible with jQuery to prevent a click event on the same element from being executed, after a mousedown & mouseup event has just been fired.

Any help/examples would be appreciated.

Share Improve this question asked May 24, 2012 at 23:24 ElliotElliot 2,2894 gold badges22 silver badges28 bronze badges 2
  • 1 I don't really get it, but a mousedown followed by a mouseup would be a click, and to just have a click work once, there's the one() method ? – adeneo Commented May 24, 2012 at 23:34
  • may this help you stackoverflow./questions/8875070/… – kongaraju Commented Sep 21, 2012 at 7:03
Add a ment  | 

5 Answers 5

Reset to default 3

No one seems to have answered this one yet, at least not in an elegant way, so I figure I'll share the solution I found by NewbeDev (source: https://newbedev./cancel-click-event-in-the-mouseup-event-handler )

The answer is to use the capture phase, so before the event gets triggered on your element, all of its parents receive it during what's called the "capture phase". Then after that the event is delivered to your element followed by its parents in what's called the "bubbling phase".

The solution here is to just cancel the event at the top during the capture phase so it never reaches your element for the bubbling phase.

My use case was for a slider, so the code I used worked out to something like this:

slider.addEventListener('mousedown', ev => {
    // we start sliding (details omitted)

    function captureClick(e) {
        // we cancel the event and stop it from going further.
        // preventDefault() on its own should be enough for most cases
        // Your handler can also check e.defaultPrevented to know if preventDefault() was called
        e.preventDefault();
        // e.stopPropagation();
    }

   window.addEventListener('click', captureClick, true);
   document.addEventListener('mouseup', e => {
       // cleanup - we wait an extra frame to remove our capture 
       //           in case the click event is delayed
       requestAnimationFrame(() => {
           window.removeEventListener('click', captureClick, true);
       });
   });
});

There's an awkward approach that is to disable the button when mousedown, and enable it after a short period, like 100ms. If the mouseup happens in this period, click won't be fired.

$('#btn').on('click', function() {
  alert('clicked')
});
$('#btn').on('mousedown', function() {
  var btn = $(this);
  btn.attr('disabled', 'disabled');
  setTimeout(function() { btn.removeAttr('disabled'); }, 100);
});
<script src="https://ajax.googleapis./ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<body>
<button id='btn'>Click me</button>
</body>

In Chrome and Internet Explorer, not Firefox though, detaching and reattaching the element at mousedown or mouseup will prevent the click event to be triggered. In Internet Explorer, this trick does not catch double-clicks though (in Chrome it does).

But I wouldn't rely on this strange behavior, who knows if it won't change at some point. Also, beware that detaching and reattaching can also have side-effects ont the children of the detached element (iframes reloading, file fields reset, ...).

There is a solution:

const COORDS = {
  xDown: null,
  xUp: null
}

const handleOnMouseDown = e => {
  e.preventDefault()
  COORDS.xUp = null
  COORDS.xDown = e.clientX
}

const handleMouseUp = e => {
  e.preventDefault()
  COORDS.xUp = e.clientX
}

const handleOnClick = e => {
  if (COORDS.xDown !== COORDS.xUp) {
    e.preventDefault()
    console.log('drag')
  } else {
    console.log('click')
  }
}

const el = document.getElementById('test')

el.addEventListener('mousedown', handleOnMouseDown)
el.addEventListener('mouseup', handleMouseUp)
el.addEventListener('click', handleOnClick)
#test {
  padding: 20px;
  display: block; 
  background: #ccc
}
<a href="#" id="test">Link</a>

Yes, it should be possible if you return false; in the mouseup handler, because the onclick is fired after a mousedown and a mouseup have occurred. This is possible in regular javascript, so it should work with jquery event handlers as well.

EDIT:

Returning a boolean value from an event handler should actually be enough for event consumption. However, as this is very flaky across browsers you should use the function for manually canceling event bubbling:

event.stopPropagation();

where event is the parameter your event handler receives.

发布评论

评论列表(0)

  1. 暂无评论