Sự cố di chuột iPad / iPhone khiến người dùng nhấp đúp vào liên kết


125

Tôi có một số trang web tôi đã xây dựng cách đây nhiều lần, sử dụng các sự kiện chuột jquery ... Tôi vừa có một chiếc ipad và tôi nhận thấy rằng tất cả các sự kiện chuột được dịch trong các nhấp chuột ... vì vậy, ví dụ tôi phải thực hiện hai lần nhấp thay vì một lần nhấp .. (di chuột đầu tiên, hơn lần nhấp thực tế)

Có một cách giải quyết sẵn sàng để giải quyết điều này? có lẽ một lệnh jquery tôi shoudl đã sử dụng thay vì mouseover / out vv .. cảm ơn!


1
sự kiện của bạn bị ràng buộc với những gì? ví dụ: các sự kiện onclick sẽ hoạt động tốt ... onmouseover, onmouseout và CSS: hover là những sự kiện hơi khó xử lý vì không có "hover" có sẵn cho màn hình cảm ứng. Bạn có một mẫu mã?
scunliffe

Một điều tôi khuyên bạn nên làm là suy nghĩ lại về giao diện của bạn nếu có thể. tương tác trên ipad / iphone không phản ánh chính xác như trên máy tính và có lẽ là một điều khôn ngoan để làm cho trang web của bạn cảm thấy như nó được viết cho ipad / iphone / các thiết bị cảm ứng khác có cơ chế cảm ứng đa điểm tương tự. Chỉ là một ý nghĩ.
giật

Tôi đồng ý với "giật". Đây là một câu hỏi kỳ lạ, tôi không nghĩ rằng giải pháp ở đây là một "cách giải quyết" cá nhân. Tôi nghĩ việc dịch "chuột di chuột" trên trình duyệt máy tính để bàn thành "chạm ngón tay" trên trình duyệt màn hình cảm ứng có ý nghĩa. Nếu bạn đồng ý với bản dịch đó, nhưng muốn một lần nhấn thay vì hai lần, thì có lẽ tôi sẽ thực hiện phát hiện tính năng cho các sự kiện iPad (ví dụ: "chạm vào") và thay đổi trình xử lý sự kiện của bạn. Có thể trích xuất mã của bạn vào một loại chức năng jquery "chạm hoặc nhấp" để kích hoạt khác nhau dựa trên các tính năng, nhưng dường như cụ thể đối với trang web / ứng dụng của bạn đối với tôi.
Andy Atkinson

1
Tôi thực sự coi bản dịch này là một tính năng. Nếu bạn đã thiết lập các sự kiện di chuột, chắc chắn đã có một số tiện ích để xem chúng. Một lần nhấn cho thấy một phần tử được di chuột, một lần nhấn thứ hai theo liên kết "phía sau" di chuột.
Aaron

Câu trả lời:


205

Chưa thử nghiệm đầy đủ nhưng vì iOS kích hoạt các sự kiện chạm, điều này có thể hoạt động, giả sử bạn đang ở trong cài đặt jQuery.

$('a').on('click touchend', function(e) {
    var el = $(this);
    var link = el.attr('href');
    window.location = link;
});

Ý tưởng là Mobile WebKit kích hoạt một touchendsự kiện ở cuối một vòi để chúng tôi lắng nghe và sau đó chuyển hướng trình duyệt ngay khi một touchendsự kiện được kích hoạt trên một liên kết.


17
Tiền thưởng của tôi đâu? : P
cduruk

2
Kiên nhẫn, Padwan. SO cho biết phải mất 24 giờ để có hiệu lực.
Andrew Hedges

2
Kể từ jQuery 1.7, .onđược ưa thích hơn .live. Sau khi đọc câu trả lời này, tôi thấy rằng việc thay đổi mã của tôi để $('a').on('click touchend', function(e) {...})hoạt động tuyệt vời.
Blazemonger

23
Vâng, điều này giải quyết vấn đề ban đầu, nhưng tạo ra một vấn đề mới: Khi vuốt qua được nhấp. Đây không phải là một giải pháp.
luksak

9
Điều này có sai sót của nó. Nếu bạn nhấp vào một liên kết với target="_blank"nó sẽ mở trong cùng một cửa sổ VÀ trong một cửa sổ mới.
rybo111

37

Không hoàn toàn rõ ràng câu hỏi của bạn là gì, nhưng nếu bạn chỉ muốn loại bỏ nhấp đúp, trong khi vẫn giữ hiệu ứng di chuột cho chuột, lời khuyên của tôi là:

  • Thêm hiệu ứng di chuột vào touchstartmouseenter.
  • Di di chuột hiệu ứng trên mouseleave, touchmoveclick.

Lý lịch

Để mô phỏng chuột, các trình duyệt như Webkit mobile sẽ kích hoạt các sự kiện sau nếu người dùng chạm và thả ngón tay trên màn hình cảm ứng (như iPad) (nguồn: Touch And Mouse trên html5rocks.com):

  1. touchstart
  2. touchmove
  3. touchend
  4. Độ trễ 300ms, trong đó trình duyệt đảm bảo đây là một lần chạm chứ không phải một lần chạm hai lần
  5. mouseover
  6. mouseenter
    • Lưu ý : Nếu một mouseover, mouseenterhoặc mousemovesự kiện làm thay đổi nội dung trang, sự kiện sau đây không bao giờ bị sa thải.
  7. mousemove
  8. mousedown
  9. mouseup
  10. click

Dường như không thể chỉ đơn giản là nói với webbrowser bỏ qua các sự kiện chuột.

Tệ hơn nữa, nếu sự kiện rê chuột thay đổi nội dung trang, sự kiện nhấp chuột sẽ không bao giờ được kích hoạt, như được giải thích trên Hướng dẫn nội dung web Safari - Xử lý sự kiện , đặc biệt là hình 6.4 trong Sự kiện một ngón tay . Chính xác "thay đổi nội dung" là gì, sẽ phụ thuộc vào trình duyệt và phiên bản. Tôi đã thấy rằng đối với iOS 7.0, thay đổi màu nền không phải là (hoặc không còn nữa?) Thay đổi nội dung.

Giải pháp giải thích

Tóm lại:

  • Thêm hiệu ứng di chuột vào touchstartmouseenter.
  • Di di chuột hiệu ứng trên mouseleave, touchmoveclick.

Lưu ý rằng không có hành động trên touchend!

Điều này rõ ràng hoạt động cho các sự kiện chuột: mouseentermouseleave(các phiên bản cải tiến mouseovermouseout) được bắn ra, đồng thời thêm và xóa di chuột.

Nếu người dùng thực sự clicksa liên kết, hiệu ứng di chuột cũng bị loại bỏ. Điều này đảm bảo rằng nó được gỡ bỏ nếu người dùng nhấn nút quay lại trong trình duyệt web.

Điều này cũng hoạt động cho các sự kiện cảm ứng: trên touchstarthiệu ứng di chuột được thêm vào. Đó là '' 'không' '' bị xóa trên touchend. Nó được thêm vào một lần nữa mouseentervà vì điều này gây ra không có thay đổi nội dung (nó đã được thêm vào), clicksự kiện cũng được kích hoạt và liên kết được theo dõi mà không cần người dùng nhấp lại!

Độ trễ 300ms mà trình duyệt có giữa một touchstartsự kiện và clickthực sự được sử dụng tốt vì hiệu ứng di chuột sẽ được hiển thị trong thời gian ngắn này.

Nếu người dùng quyết định hủy nhấp chuột, một động tác của ngón tay sẽ làm như vậy như bình thường. Thông thường, đây là một vấn đề vì không có mouseleavesự kiện nào được kích hoạt và hiệu ứng di chuột vẫn được giữ nguyên. Rất may, điều này có thể dễ dàng được khắc phục bằng cách loại bỏ hiệu ứng di chuột trên touchmove.

Đó là nó!

Lưu ý rằng có thể xóa độ trễ 300ms, ví dụ như sử dụng thư viện FastClick , nhưng điều này nằm ngoài phạm vi của câu hỏi này.

Các giải pháp thay thế

Tôi đã tìm thấy các vấn đề sau với các lựa chọn thay thế sau:

  • phát hiện trình duyệt: Rất dễ bị lỗi. Giả sử rằng một thiết bị có chuột hoặc cảm ứng, trong khi sự kết hợp của cả hai sẽ ngày càng trở nên phổ biến hơn khi cảm ứng hiển thị phổ biến.
  • Phát hiện phương tiện CSS: Giải pháp duy nhất chỉ CSS mà tôi biết. Vẫn dễ bị lỗi và vẫn cho rằng một thiết bị có chuột hoặc chạm, trong khi cả hai đều có thể.
  • Giả lập sự kiện nhấp chuột trong touchend: Điều này sẽ theo liên kết không chính xác, ngay cả khi người dùng chỉ muốn cuộn hoặc thu phóng, mà không có ý định thực sự nhấp vào liên kết.
  • Sử dụng một biến để triệt tiêu các sự kiện chuột: Điều này đặt một biến trong touchendđó được sử dụng làm điều kiện if trong các sự kiện chuột tiếp theo để ngăn chặn các thay đổi trạng thái tại thời điểm đó. Biến được đặt lại trong sự kiện nhấp chuột. Đây là một giải pháp tốt nếu bạn thực sự không muốn có hiệu ứng di chuột trên các giao diện cảm ứng. Thật không may, điều này không hoạt động nếu touchendbị bắn vì một lý do khác và không có sự kiện nhấp nào được kích hoạt (ví dụ: người dùng cuộn hoặc thu phóng) và sau đó đang cố gắng theo liên kết bằng chuột (tức là trên thiết bị có cả giao diện chuột và cảm ứng ).

Đọc thêm

Xem thêm sự cố nhấp chuột đôi iPad / iPhoneTắt hiệu ứng di chuột trên trình duyệt di động .


2
có vẻ như là lời giải thích tốt nhất cho những người muốn giải pháp vấn đề chính xác hơn. Thanx
kẻ phản bội

Cảm ơn đặc biệt về thông tin về màu nền cho> iOS7. Tôi đã dành một chút thời gian để cố gắng tìm ra khi nào nó bắt đầu làm việc.
nhân viên

20

Dường như có một giải pháp CSS sau tất cả. Lý do Safari chờ đợi lần chạm thứ hai là vì hình nền (hoặc thành phần) mà bạn thường chỉ định trong sự kiện: hover. Nếu không có gì để hiển thị - bạn sẽ không gặp vấn đề gì. Giải pháp là nhắm mục tiêu nền tảng iOS với tệp CSS thứ cấp (hoặc kiểu trong trường hợp tiếp cận JS) ghi đè: nền di chuột để kế thừa ví dụ và giữ ẩn các yếu tố bạn sẽ hiển thị trên chuột:

Dưới đây là ví dụ về CSS và HTML - một khối sản phẩm có nhãn được gắn dấu sao trên chuột:

HTML:

<a href="#" class="s"><span class="s-star"></span>Some text here</a>

CSS:

.s {
   background: url(some-image.png) no-repeat 0 0;

}
.s:hover {
   background: url(some-image-r.png) no-repeat 0 0;
}

.s-star {
   background: url(star.png) no-repeat 0 0;
   height: 56px;
   position: absolute;
   width: 72px;
   display:none;
}

.s:hover .s-star {
   display:block;
}

Giải pháp (CSS thứ cấp):

/* CSS */
/* Keep hovers the same or hidden */
.s:hover {
   background:inherit;
}
.s:hover .s-star {
   display:none;
}


Câu trả lời này hướng đến hình ảnh nền nhưng bạn có giải pháp nào cho những thay đổi độ mờ đơn giản không? Giải pháp này không hoạt động cho việc này.
Ian S

5

Không cần phải làm quá phức tạp.

$('a').on('touchend', function() {
    $(this).click();
});

5

Những gì làm việc cho tôi là những gì người khác ở đây đã nói:

Không hiển thị / ẩn các thành phần trên hover hoặc mousemove (đó là sự kiện trong trường hợp của tôi).

Dưới đây là những gì Apple nói ( https://developer.apple.com/l Library / content / document / AppleAppluggest / Reference / SeariWebContent / HandlingEvents / HandlingEvents.html ):

Một yếu tố có thể nhấp là một liên kết, thành phần biểu mẫu, khu vực bản đồ hình ảnh hoặc bất kỳ yếu tố nào khác với mousemove, mousedown, mouseup hoặc trình xử lý onclick

Nếu người dùng khai thác một yếu tố có thể nhấp, các sự kiện sẽ đến theo thứ tự này: mouseover, mousemove, mousedown, mouseup và nhấp chuột. Ngoài ra, nếu nội dung của trang thay đổi trên sự kiện mousemove, không có sự kiện tiếp theo nào trong chuỗi được gửi. Hành vi này cho phép người dùng khai thác nội dung mới.

Vì vậy, bạn có thể sử dụng giải pháp của @ woop: phát hiện userAgent, kiểm tra xem nó và thiết bị iOS và sau đó liên kết sự kiện. Tôi đã kết thúc bằng cách sử dụng kỹ thuật này bởi vì nó phù hợp với nhu cầu của tôi và nó có ý nghĩa hơn không ràng buộc các sự kiện di chuột khi bạn không muốn nó.

Nhưng ... nếu bạn không muốn gây rối với userAgents và vẫn ẩn / hiển thị các thành phần trên hover / mousemove, tôi phát hiện ra bạn có thể làm như vậy bằng cách sử dụng javascript gốc, như thế này:

$("body").on("mouseover", function() {
       document.getElementsByTagName("my-class")[0].style.display = 'block'; //show element
       document.querySelector(".my-selector div").style.display = 'none'; // hide element
});

Điều này sẽ hoạt động trên phiên bản Máy tính để bàn và sẽ không làm gì trên phiên bản di động.

Và để tương thích hơn một chút ...

$("body").on("mouseover", function() {
   if (document.getElementsByTagName && document.querySelector) { // check compatibility
       document.getElementsByTagName("my-class")[0].style.display = 'block'; //show element
       document.querySelector(".my-selector div").style.display = 'none'; // hide element
    } else {
        $(".my-class").show();
        $(".my-selector div").hide();
    }
});

1
Đó là bit "nếu nội dung của trang thay đổi trên sự kiện mousemove, không có sự kiện tiếp theo nào trong chuỗi được gửi" thực sự đã làm điều đó cho tôi. Tôi đã có một trang trong đó các liên kết tiêu đề sẽ yêu cầu một lần chạm hai lần trong đó các nút trong nội dung (với tất cả các chuyển đổi css3 hạnh phúc trên em) sẽ chỉ cần một lần nhấn. Xuất hiện rằng các liên kết tiêu đề có yếu tố giả đi từ opacity: 0 đến opacity: 1 trên hover. Loại bỏ hiệu ứng đó ngay lập tức giải quyết vấn đề và tôi tìm thấy một cách giải quyết CSS để vẫn có được giao diện tôi muốn.
Haak giả

3

Giải pháp của cduruk khá hiệu quả, nhưng gây ra sự cố trên một số phần của trang web của tôi. Vì tôi đã sử dụng jQuery để thêm lớp di chuột CSS, nên giải pháp đơn giản nhất là không thêm lớp di chuột CSS trên thiết bị di động (hay chính xác hơn là CHỈ thêm nó khi KHÔNG trên thiết bị di động).

Đây là ý tưởng chung:

var device = navigator.userAgent.toLowerCase();
var ios = device.match(/(iphone|ipod|ipad)/);

if (!(ios)) {
    $(".portfolio-style").hover(
        function(){
            $(this).stop().animate({opacity: 1}, 100);
            $(this).addClass("portfolio-red-text");
        },
        function(){
            $(this).stop().animate({opacity: 0.85}, 100);
            $(this).removeClass("portfolio-red-text");
        }
    );
}

* mã giảm cho mục đích minh họa


1
Đây rõ ràng là câu trả lời. Các "giải pháp" khác không khắc phục được sự cố. Safari safari rõ ràng là thiếu sót khi nghĩ rằng chúng ta muốn di chuột trước. Các hệ điều hành khác có các tính năng di chuột thực tế khi bạn di chuột qua một mục.
Gói Joshua

Đây là điều duy nhất làm việc cho tôi. Cảm ơn bạn rất nhiều!
tx291

2

Tôi nghĩ sẽ là khôn ngoan khi thử mouseenterthay thế mouseover. Đó là những gì được sử dụng nội bộ khi ràng buộc .hover(fn,fn)và nói chung là những gì bạn muốn.


1

Tôi đã có những vấn đề sau với các giải pháp hiện có, và tìm thấy một cái gì đó dường như giải quyết tất cả chúng. Điều này giả định rằng bạn đang nhắm đến một thứ gì đó trên trình duyệt chéo, thiết bị chéo và không muốn đánh hơi thiết bị.

Những vấn đề này giải quyết

Chỉ sử dụng touchstarthoặc touchend:

  • Làm cho sự kiện phát sinh khi mọi người đang cố cuộn qua nội dung và tình cờ thấy ngón tay của họ lướt qua yếu tố này khi họ bắt đầu vuốt - kích hoạt hành động bất ngờ.
  • Có thể gây ra sự kiện này trên longpress , tương tự như nhấp chuột phải trên máy tính để bàn. Ví dụ: nếu sự kiện nhấp chuột của bạn chuyển đến URL X và người dùng nhấn giữ để mở X trong một tab mới, người dùng sẽ bối rối khi thấy X mở trong cả hai tab. Trên một số trình duyệt (ví dụ iPhone), nó thậm chí có thể ngăn menu nhấn dài xuất hiện.

Kích hoạt mouseovercác sự kiện trên touchstartmouseouttrên touchmovecó hậu quả ít nghiêm trọng hơn, nhưng không can thiệp vào hành vi thông thường của trình duyệt, ví dụ:

  • Một báo chí dài sẽ kích hoạt di chuột không bao giờ kết thúc.
  • Nhiều trình duyệt Android coi vị trí của ngón tay touchstartgiống như một mouseover, đó là mouseouted trên tiếp theo touchstart. Do đó, một cách để xem nội dung di chuột trong Android là chạm vào vùng quan tâm và ngọ nguậy ngón tay của bạn, cuộn nhẹ trang. Đối xử touchmovenhư mouseoutphá vỡ điều này.

Giải pháp

Về lý thuyết, bạn chỉ có thể thêm một cờ với touchmove, nhưng iPhone kích hoạt cảm ứng ngay cả khi không có chuyển động. Về lý thuyết, bạn chỉ có thể so sánh touchstarttouchendsự kiện pageXpageY nhưng trên iPhone, không có touchend pageXhoặcpageY .

Vì vậy, không may để bao gồm tất cả các cơ sở, nó kết thúc phức tạp hơn một chút.

$el.on('touchstart', function(e){
    $el.data('tstartE', e);
    if(event.originalEvent.targetTouches){
        // store values, not reference, since touch obj will change
        var touch = e.originalEvent.targetTouches[0];
        $el.data('tstartT',{ clientX: touch.clientX, clientY: touch.clientY } );
    }
});
$el.on('touchmove', function(e){
    if(event.originalEvent.targetTouches){
        $el.data('tstartM', event.originalEvent.targetTouches[0]);
    }
});

$el.on('click touchend', function(e){
    var oldE = $el.data('tstartE');
    if( oldE && oldE.timeStamp + 1000 < e.timeStamp ) {
        $el.data('tstartE',false);
        return;
    }
    if( $el.data('iosTouchM') && $el.data('tstartT') ){
        var start = $el.data('tstartT'), end = $el.data('tstartM');
        if( start.clientX != end.clientX || start.clientY != end.clientY ){
            $el.data('tstartT', false);
            $el.data('tstartM', false);
            $el.data('tstartE',false);
            return;
        }
    }
    $el.data('tstartE',false);

Về lý thuyết, có nhiều cách để có được thời gian chính xác được sử dụng cho một lần nhấn thay vì chỉ sử dụng 1000 như một xấp xỉ, nhưng trong thực tế, điều đó không đơn giản và tốt nhất là sử dụng proxy hợp lý .


1

Câu trả lời của MacFreak cực kỳ hữu ích với tôi. Đây là một số mã thực hành trong trường hợp nó giúp bạn.

VẤN ĐỀ - áp dụng touchend có nghĩa là mỗi khi bạn di chuyển ngón tay qua một yếu tố, nó sẽ phản hồi như thể bạn đã nhấn nó, ngay cả khi bạn chỉ cố gắng cuộn qua.

Tôi đang tạo một hiệu ứng với jQuery để làm mờ một dòng dưới một số nút để "làm nổi bật" nút được di chuột. Tôi không muốn điều này có nghĩa là bạn phải nhấn nút hai lần trên các thiết bị cảm ứng để theo liên kết.

Dưới đây là các nút:

<a class="menu_button" href="#">
    <div class="menu_underline"></div>
</a>

Tôi muốn div "menu_underline" mờ dần khi di chuột và mờ dần khi di chuột ra. NHƯNG tôi muốn các thiết bị cảm ứng có thể theo liên kết chỉ bằng một cú nhấp chứ không phải hai.

GIẢI PHÁP - Đây là jQuery để làm cho nó hoạt động:

//Mouse Enter
$('.menu_button').bind('touchstart mouseenter', function(){
    $(this).find(".menu_underline").fadeIn();
});

//Mouse Out   
$('.menu_button').bind('mouseleave touchmove click', function(){
    $(this).find(".menu_underline").fadeOut();
});

Rất cám ơn sự giúp đỡ của bạn trên MacFreak này.


1

Tôi chỉ phát hiện ra rằng nó hoạt động nếu bạn thêm một trình nghe trống, đừng hỏi tôi tại sao, nhưng tôi đã thử nó trên iPhone và iPad với iOS 9.3.2 và nó hoạt động tốt.

if(/iPad|iPhone|iPod/.test(navigator.userAgent) && !window.MSStream){
    var elements = document.getElementsByTagName('a');
    for(var i = 0; i < elements.length; i++){
        elements[i].addEventListener('touchend',function(){});
    }
}

1

Tôi "nghĩ" rằng các liên kết của bạn không có sự kiện onmouseover, trong đó 1 tap kích hoạt onmouseover và chạm hai lần kích hoạt liên kết. nhưng idk. Tôi không có iPad. Tôi nghĩ rằng bạn phải sử dụng các sự kiện cử chỉ / chạm.

https://developer.apple.com/documentation/webkitjs


0

Tôi đã có cùng một vấn đề nhưng không phải trên một thiết bị cảm ứng. Sự kiện kích hoạt mỗi khi bạn nhấp vào. Có một cái gì đó về hàng đợi sự kiện hoặc như vậy.

Tuy nhiên, giải pháp của tôi là như thế này: Khi nhấp vào sự kiện (hoặc chạm?) Bạn đặt hẹn giờ. Nếu liên kết được nhấp lại trong X ms, bạn chỉ cần trả về false.

Để đặt cho mỗi bộ định thời phần tử, bạn có thể sử dụng $.data().

Điều này cũng có thể khắc phục sự cố @Ferdy được mô tả ở trên.


Bạn có thể đăng những gì mã này trông như thế nào? Tôi đang gặp vấn đề về sự kiện nhấp chuột này được kích hoạt hai lần.
ưa thích

0

Nếu bạn sử dụng Modernizr, rất dễ sử dụng Modernizr.touch như đã đề cập trước đó.

Tuy nhiên, tôi thích sử dụng kết hợp Modernizr.touch và thử nghiệm tác nhân người dùng, để an toàn.

var deviceAgent = navigator.userAgent.toLowerCase();

var isTouchDevice = Modernizr.touch || 
(deviceAgent.match(/(iphone|ipod|ipad)/) ||
deviceAgent.match(/(android)/)  || 
deviceAgent.match(/(iemobile)/) || 
deviceAgent.match(/iphone/i) || 
deviceAgent.match(/ipad/i) || 
deviceAgent.match(/ipod/i) || 
deviceAgent.match(/blackberry/i) || 
deviceAgent.match(/bada/i));

function Tipsy(element, options) {
    this.$element = $(element);
    this.options = options;
    this.enabled = !isTouchDevice;
    this.fixTitle();
};

Nếu bạn không sử dụng Modernizr, bạn chỉ cần thay thế Modernizr.touchchức năng trên bằng('ontouchstart' in document.documentElement)

Cũng lưu ý rằng việc kiểm tra tác nhân người dùng iemobile sẽ cung cấp cho bạn phạm vi rộng hơn của các thiết bị di động Microsoft được phát hiện so với Windows Phone.


0

Bạn có thể sử dụng click touchend,

thí dụ:

$('a').on('click touchend', function() {
    var linkToAffect = $(this);
    var linkToAffectHref = linkToAffect.attr('href');
    window.location = linkToAffectHref;
});

Ví dụ trên sẽ ảnh hưởng đến tất cả các liên kết trên các thiết bị cảm ứng.

Nếu bạn chỉ muốn nhắm mục tiêu các liên kết cụ thể, bạn có thể thực hiện việc này bằng cách đặt một lớp trên chúng, tức là:

HTML:

<a href="example.html" class="prevent-extra-click">Prevent extra click on touch device</a>

Câu hỏi:

$('a.prevent-extra-click').on('click touchend', function() {
    var linkToAffect = $(this);
    var linkToAffectHref = linkToAffect.attr('href');
    window.location = linkToAffectHref;
});

Chúc mừng

Jeroen


0

Tôi đã gặp một tình huống tương tự khi tôi có các sự kiện liên kết với trạng thái mouseenter / mouseleave / click của một phần tử, nhưng trên iPhone, người dùng phải nhấp đúp vào phần tử để kích hoạt sự kiện mouseenter trước, sau đó lại kích hoạt sự kiện click .

Tôi đã giải quyết vấn đề này bằng một phương thức tương tự như trên, nhưng tôi đã sử dụng plugin jQuery $ .browser (cho jQuery 1.9>) và thêm một sự kiện .trigger vào sự kiện ràng buộc của mouseenter, như sau:

// mouseenter event
$('.element').on( "mouseenter", function() {
    // insert mouseenter events below

    // double click fix for iOS and mouseenter events
    if ($.browser.iphone || $.browser.ipad) $(this).trigger('click');
});
// mouseleave event
$('.element').on( "mouseleave", function() { 
    // insert mouseout events below
});
// onclick event
$('.element').on( "click", function() {
    // insert click events below
});

.Trigger ngăn không cần nhấp đúp vào phần tử bằng cách bắn trình xử lý sự kiện .click trên mouseenter (hoặc nhấp ban đầu) của phần tử khi được xem trên iPhone hoặc iPad. Có thể không phải là giải pháp tao nhã nhất, nhưng nó hoạt động rất tốt trong trường hợp của tôi và sử dụng một plugin mà tôi đã có, và yêu cầu tôi thêm một dòng mã để các sự kiện hiện có của tôi hoạt động trong các thiết bị này.

Bạn có thể tải plugin jQuery $ .browser tại đây: https://github.com/gabceb/jquery-browser-plugin


0

Chỉ là một cải tiến để tránh chuyển hướng khi bạn trượt ngón tay trên một liên kết do nhầm lẫn.

// tablet "one touch (click)" X "hover" > link redirection
$('a').on('touchmove touchend', function(e) {

    // if touchmove>touchend, set the data() for this element to true. then leave touchmove & let touchend fail(data=true) redirection
    if (e.type == 'touchmove') {
        $.data(this, "touchmove_cancel_redirection", true );
        return;
    }

    // if it's a simple touchend, data() for this element doesn't exist.
    if (e.type == 'touchend' && !$.data(this, "touchmove_cancel_redirection")) {
        var el = $(this);
        var link = el.attr('href');
        window.location = link;
    }

    // if touchmove>touchend, to be redirected on a future simple touchend for this element
    $.data(this, "touchmove_cancel_redirection", false );
});

0

Với cảm hứng từ MacFreak, tôi kết hợp một thứ gì đó phù hợp với mình.

Phương pháp js này ngăn không cho di chuột dính vào ipad và ngăn việc nhấp đăng ký là hai lần nhấp trong một số trường hợp. Trong CSS, nếu bạn có bất kỳ: hover các lớp psudo trong css của bạn, hãy thay đổi chúng thành .hover Ví dụ .some-class: hover thành .some-class.hover

Kiểm tra mã này trên ipad để xem phương thức di chuột của css và js hoạt động khác nhau như thế nào (chỉ trong hiệu ứng di chuột). Nút CSS không có cảnh báo nhấp chuột ưa thích. http://jsfiddle.net/bensontrent/ctgr6stm/

function clicker(id, doStuff) {
  id.on('touchstart', function(e) {
    id.addClass('hover');
  }).on('touchmove', function(e) {
    id.removeClass('hover');
  }).mouseenter(function(e) {
    id.addClass('hover');
  }).mouseleave(function(e) {
    id.removeClass('hover');
  }).click(function(e) {
    id.removeClass('hover');
    //It's clicked. Do Something
    doStuff(id);
  });
}

function doStuff(id) {
  //Do Stuff
  $('#clicked-alert').fadeIn(function() {
    $(this).fadeOut();
  });
}
clicker($('#unique-id'), doStuff);
button {
  display: block;
  margin: 20px;
  padding: 10px;
  -webkit-appearance: none;
  touch-action: manipulation;
}
.hover {
  background: yellow;
}
.btn:active {
  background: red;
}
.cssonly:hover {
  background: yellow;
}
.cssonly:active {
  background: red;
}
#clicked-alert {
  display: none;
}
<button id="unique-id" class="btn">JS Hover for Mobile devices<span id="clicked-alert"> Clicked</span>

</button>
<button class="cssonly">CSS Only Button</button>
<br>This js method prevents hover from sticking on an ipad, and prevents the click registering as two clicks. In CSS, if you have any :hover in your css, change them to .hover For example .some-class:hover to .some-class.hover


0

Để các liên kết hoạt động mà không ngắt cuộn cảm ứng, tôi đã giải quyết vấn đề này bằng sự kiện "chạm" của jQuery Mobile:

    $('a').not('nav.navbar a').on("tap", function () {
        var link = $(this).attr('href');
        if (typeof link !== 'undefined') {
            window.location = link;
        }
    });

0

Tôi đã quá muộn, tôi biết nhưng đây là một trong những cách giải quyết dễ dàng nhất mà tôi đã tìm thấy:

    $('body').on('touchstart','*',function(){   //listen to touch
        var jQueryElement=$(this);  
        var element = jQueryElement.get(0); // find tapped HTML element
        if(!element.click){
            var eventObj = document.createEvent('MouseEvents');
            eventObj.initEvent('click',true,true);
            element.dispatchEvent(eventObj);
        }
    });

Điều này không chỉ hoạt động cho các liên kết (thẻ neo) mà còn cho các yếu tố khác. Hi vọng điêu nay co ich.


0

Đoạn trích ngắn này dường như hoạt động. Kích hoạt sự kiện nhấp khi liên kết khai thác:

  $('a').on('touchstart', function() {
    $(this).trigger('click');
  });

0

Không có từ câu trả lời khác làm việc cho tôi. Ứng dụng của tôi có rất nhiều người nghe sự kiện, hộp kiểm riêng và các liên kết có người nghe và liên kết mà không có người nghe.

Tôi sử dụng cái này:

var selector = "label, a, button";
var timer;
var startX;
var startY;
$(document).on("click", selector, function (e) {
    if ($(this).data("touched") === true) {
        e.stopImmediatePropagation();
        return false;
    }
    return;
}).on("touchend", selector, function (e) {
    if (Math.abs(startX - e.originalEvent.changedTouches[0].screenX) > 10 || Math.abs(startY - e.originalEvent.changedTouches[0].screenY) > 10)
        // user action is not a tap
        return;
    var $this = $(this);
    // Visit: http://stackoverflow.com/questions/1694595/can-i-call-jquery-click-to-follow-an-a-link-if-i-havent-bound-an-event-hand/12801548#12801548
    this.click();
    // prevents double click
    $this.data("touched", true);
    if (timer)
        clearTimeout(timer);
    setTimeout(function () {
        $this.data("touched", false);
    }, 400);
    e.stopImmediatePropagation();
    return false;
}).on("touchstart", function (e) {
    startX = e.originalEvent.changedTouches[0].screenX;
    startY = e.originalEvent.changedTouches[0].screenY;
});

0

Điều này làm việc cho tôi khi bạn có thả xuống jquery ui

if (navigator.userAgent.match(/(iPod|iPhone|iPad)/)) {
      $('.ui-autocomplete').off('menufocus hover mouseover');
}

0

Tránh thay đổi kiểu "hiển thị" bên trong sự kiện hover css. Tôi đã có "display: block" ở trạng thái di chuột. Sau khi loại bỏ ios đi trên lins bằng một lần chạm. Nhân tiện, có vẻ như các bản cập nhật iOS mới nhất đã sửa "tính năng" này


0

Cách đơn giản nhất để giải quyết nhấp đúp chuột vào IPad là gói css của bạn cho hiệu ứng di chuột trong truy vấn phương tiện @media (pointer: fine):

@media (pointer: fine) {
  a span {
    display: none;
  }
  a:hover span {
    display: inline-block;
  }
}

CSS được gói trong truy vấn phương tiện này sẽ chỉ áp dụng trên máy tính để bàn.

Giải thích về giải pháp này có tại đây https://css-tricks.com/annoying-mobile-double-tap-link-su/


-1

Bạn có thể kiểm tra navigator.userAgentnhư thế này:

if(!navigator.userAgent.match(/iPhone/i) || !navigator.userAgent.match(/iPad/i)) {
    //bind your mouseovers...
}

nhưng bạn sẽ phải kiểm tra blackberries, droids, các thiết bị màn hình cảm ứng khác. Bạn cũng có thể liên kết chuột chỉ khi userAgent chứa Mozilla, IE, Webkit hoặc Opera, nhưng bạn vẫn cần sàng lọc một số thiết bị vì Droid, ví dụ, báo cáo chuỗi userAgent của nó là:

Mozilla/5.0 (Linux; U; Android 2.0.1; en-us; Droid Build/ESD56) AppleWebKit/530.17 (KHTML, like Gecko) Version/4.0 Mobile Safari/530.17

Chuỗi của iPhone cũng tương tự. Nếu bạn chỉ màn hình cho iPhone, iPod, iPad, Android và Blackberry, bạn có thể nhận được phần lớn thiết bị cầm tay, nhưng không phải tất cả chúng.


Tôi nghĩ, bây giờ, để không bị điên, điều tốt nhất nên làm có thể chỉ là một kịch bản bỏ qua các sự kiện di chuột..như tôi đoán câu trả lời đầu tiên là tốt ... và vâng bạn đúng vậy..tôi nên nghĩ về tất cả các thiết bị khác ... tôi ước Jquery hoặc một số plugin có loại tính năng dection này ..!
Francesco

wurfl.sourceforge.net Đây có thể là câu trả lời của bạn. Đây là một cơ sở dữ liệu của các thiết bị không dây. Sẽ không đơn giản như một plugin jQuery, nhưng bạn luôn có thể viết một plugin! Ngoài ra còn có tera-wurfl.com sử dụng cơ sở dữ liệu thay vì tệp xml. Chưa thực hiện nhiều công việc đào bới nhưng có thể có một phiên bản được lưu trữ ngoài đó vì vậy bạn không phải lo lắng về việc cập nhật tệp wurfl hoặc cơ sở dữ liệu tera-wurfl.
jasongetsdown

1
Tôi có thiếu điều gì không hay là câu hỏi KHÔNG về việc phát hiện iPad, mà là về cách xử lý một hành vi cụ thể trên iPad?
Andrew Hedges

5
UA đánh hơi? Cách 90: P
Macha

-1

Chỉ cần tạo một truy vấn phương tiện CSS loại trừ máy tính bảng và thiết bị di động và đặt di chuột vào đó. Bạn không thực sự cần jQuery hoặc JavaScript cho việc này.

@media screen and (min-device-width:1024px) {
    your-element:hover {
        /* Do whatever here */
    }
}

Và hãy chắc chắn để thêm phần này vào đầu html của bạn để đảm bảo rằng nó tính toán với các pixel thực tế chứ không phải độ phân giải.

<meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=no" />
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.