Tôi có thể tắt hiệu ứng CSS: hover qua JavaScript không?


99

Tôi đang cố gắng ngăn trình duyệt sử dụng :hoverhiệu ứng của CSS, thông qua JavaScript.

Tôi đã đặt kiểu aa:hoverkiểu trong CSS của mình, vì tôi muốn có hiệu ứng di chuột, nếu JS không có sẵn. Nhưng nếu JS có sẵn, tôi muốn ghi đè ảnh hưởng di chuột CSS của tôi với một mượt mà một (sử dụng màu jQuery plugin cho ví dụ.)

Tôi đã thử điều này:

$("ul#mainFilter a").hover(
     function(e){ e.preventDefault(); ...do my stuff... }, 
     function(e){ e.preventDefault(); ...do my stuff... });

Tôi cũng đã thử nó với return false;, nhưng nó không hoạt động.

Đây là một ví dụ về vấn đề của tôi: http://jsfiddle.net/4rEzz/ . Liên kết sẽ chỉ mờ đi mà không bị xám.

Như đã đề cập bởi fudgey, cách giải quyết sẽ là đặt lại các kiểu di chuột bằng cách sử dụng .css()nhưng tôi sẽ phải ghi đè mọi thuộc tính đơn lẻ, được chỉ định trong CSS (xem tại đây: http://jsfiddle.net/raPeX/1/ ). Tôi đang tìm kiếm một giải pháp chung.

Có ai biết cách để làm điều này không?

Tái bút: Tôi không muốn ghi đè lên mọi kiểu mà tôi đã đặt cho di chuột.

Câu trả lời:


136

Tôi e rằng không có một giải pháp chung chung cho JavaScript thuần túy. JavaScript không thể tự tắt :hovertrạng thái CSS .

Mặc dù vậy, bạn có thể thử giải pháp thay thế sau đây. Nếu bạn không bận tâm về việc sử dụng HTML và CSS của mình một chút, nó giúp bạn tiết kiệm việc phải đặt lại mọi thuộc tính CSS theo cách thủ công thông qua JavaScript.

HTML

<body class="nojQuery">

CSS

/* Limit the hover styles in your CSS so that they only apply when the nojQuery 
class is present */

body.nojQuery ul#mainFilter a:hover {
    /* CSS-only hover styles go here */
}

JavaScript

// When jQuery kicks in, remove the nojQuery class from the <body> element, thus
// making the CSS hover styles disappear.

$(function(){}
    $('body').removeClass('nojQuery');
)

5
Tôi thích giải pháp này hơn các giải pháp noscript vì nó hoạt động khi CSS được chứa hoàn toàn trong các tệp bên ngoài và nó cũng hoạt động trong quá trình tải trang, nếu CSS tải trước nhưng JS không tải cho đến sau. Việc sử dụng jQuery để "nâng cao dần dần" mọi thứ thường dẫn đến các trang không hoạt động tốt nếu bạn nhấp vào nội dung trước khi tải xong. Ngay cả với một trình duyệt nhanh trên một liên kết nhanh, tôi cũng thấy điều này rất nhiều.
Ông Shiny và Mới 安 宇

@Ông. Sáng bóng và Mới: Tôi đồng ý, tôi thích điều này hơn cả giải pháp của tôi! Tôi không chắc tại sao tôi không nhận thấy sự sang trọng của cái này trước đây ...
Josh

3
“Tôi thích giải pháp này hơn các giải pháp noscript vì nó hoạt động khi CSS được chứa hoàn toàn trong các tệp bên ngoài” - <noscript>giải pháp cũng vậy. Bạn chỉ cần đặt <link>thẻ bên trong của bạn <noscript>, thay vì <style>thẻ. Tuy nhiên, giải pháp của tôi cho phép bạn giữ mọi thứ bên trong một tệp biểu định kiểu thay vì nhiều tệp.
Paul D. Waite

nó không chính xác những gì tôi đang tìm kiếm nhưng tôi nghĩ giải pháp này là sự thỏa hiệp tốt nhất! Thx cho tất cả các bạn
meo

bạn cũng có thể sao chép cùng một kiểu với một tên khác và sử dụng jquery chọn tất cả các phần tử có lớp đó và xóa lớp đó và thay thế bằng lớp sao chép.
chepe263,

14

Sử dụng lớp thứ hai chỉ có chỉ định di chuột:

HTML

 <a class="myclass myclass_hover" href="#">My anchor</a>

CSS

 .myclass { 
   /* all anchor styles */
 }
 .myclass_hover:hover {
   /* example color */
   color:#00A;
 }

Bây giờ bạn có thể sử dụng Jquery để loại bỏ lớp, ví dụ: nếu phần tử đã được nhấp:

JQUERY

 $('.myclass').click( function(e) {
    e.preventDefault();
    $(this).removeClass('myclass_hover');
 });

Hy vọng câu trả lời này là hữu ích.


3
cộng 1. nó không chính thống, nhưng bẻ gãy vấn đề theo một cách khá cao siêu.
jim số điện thoại

11

Bạn có thể tự thao tác các biểu định kiểu và quy tắc biểu định kiểu bằng javascript

var sheetCount = document.styleSheets.length;
var lastSheet = document.styleSheets[sheetCount-1];
var ruleCount;
if (lastSheet.cssRules) { // Firefox uses 'cssRules'
    ruleCount = lastSheet.cssRules.length;
}
else if (lastSheet.rules) { / /IE uses 'rules'
    ruleCount = lastSheet.rules.length;
}
var newRule = "a:hover { text-decoration: none !important; color: #000 !important; }";
// insert as the last rule in the last sheet so it
// overrides (not overwrites) previous definitions
lastSheet.insertRule(newRule, ruleCount);

Việc làm cho các thuộc tính trở nên quan trọng và đặt đây là định nghĩa CSS cuối cùng sẽ ghi đè lên bất kỳ định nghĩa nào trước đó, trừ khi định nghĩa đó được nhắm mục tiêu cụ thể hơn. Bạn có thể phải chèn nhiều quy tắc hơn trong trường hợp đó.


1
Hoặc bạn có thể đặt tất cả các quy tắc noscript trong một biểu định kiểu và sau đó vô hiệu hóa biểu định kiểu khỏi javascript.
Sean Hogan

2
Hay đặt <link>thẻ biểu định kiểu noscript của bạn bên trong một <noscript>phần tử? Điều đó sẽ hoạt động, phải không?
Paul D. Waite

1
Hoặc xóa quy tắc "vi phạm": developer.mozilla.org/en/DOM/stylesheet.deleteRule
RoToRa

1
Ngay cả IE5 cũng có thể làm được. Phương thức này được gọi khác nhau, nhưng nó sẽ hoạt động: msdn.microsoft.com/en-us/library/ms531195%28v=vs.85%29.aspx . Tôi chưa kiểm tra các trình duyệt khác, nhưng tôi đoán tất cả các trình duyệt hiện đại đều triển khai tiêu chuẩn.
RoToRa

Trong Firefox tôi nhận đượcError: The operation is insecure.
Alex W

11

Điều này tương tự như câu trả lời của aSeptik, nhưng cách tiếp cận này thì sao? Bao bọc mã CSS mà bạn muốn tắt bằng JavaScript trong <noscript>thẻ. Bằng cách đó, nếu javaScript bị tắt, CSS :hoversẽ được sử dụng, nếu không, hiệu ứng JavaScript sẽ được sử dụng.

Thí dụ:

<noscript>
<style type="text/css">
ul#mainFilter a:hover {
  /* some CSS attributes here */
}
</style>
</noscript>
<script type="text/javascript">
$("ul#mainFilter a").hover(
     function(o){ /* ...do your stuff... */ }, 
     function(o){ /* ...do your stuff... */ });
</script>

4

Tôi đã sử dụng not()toán tử CSS và addClass()hàm của jQuery . Đây là một ví dụ, khi bạn nhấp vào một mục danh sách, nó sẽ không di chuột nữa:

Ví dụ:

HTML

<ul class="vegies">
    <li>Onion</li>
    <li>Potato</li>
    <li>Lettuce</li>
<ul>

CSS

.vegies li:not(.no-hover):hover { color: blue; }

jQuery

$('.vegies li').click( function(){
    $(this).addClass('no-hover');
});

3

Tôi sẽ sử dụng CSS để ngăn sự kiện: hover thay đổi giao diện của liên kết.

a{
  font:normal 12px/15px arial,verdana,sans-serif;
  color:#000;
  text-decoration:none;
}

CSS đơn giản này có nghĩa là các liên kết sẽ luôn có màu đen và không được gạch chân. Tôi không thể nói từ câu hỏi liệu sự thay đổi về ngoại hình có phải là điều duy nhất bạn muốn kiểm soát hay không.


tốt là có: hiệu ứng di chuột nếu JS không khả dụng trên máy khách. Nhưng nếu nó là tôi cần phải ghi đè nó. Tôi đã đặt một lớp: hover trong css của mình, tôi chỉ muốn vô hiệu hóa nó.
meo

@meo: Bạn không thể tắt các lớp CSS psuedo, nhưng bạn có thể ghi đè nó bằng cách đặt tất cả các kiểu liên kết có cùng giao diện / thông số. Cả câu trả lời này và câu trả lời của tôi đều làm được điều này, chỉ theo những cách khác nhau.
Mottie

3

Tôi khuyên bạn nên thay thế tất cả các :hoverthuộc tính :activekhi bạn phát hiện ra rằng thiết bị hỗ trợ cảm ứng. Chỉ gọi hàm này khi bạn làm như vậy touch().

function touch() {
  if ('ontouchstart' in document.documentElement) {
    for (var sheetI = document.styleSheets.length - 1; sheetI >= 0; sheetI--) {
      var sheet = document.styleSheets[sheetI];
      if (sheet.cssRules) {
        for (var ruleI = sheet.cssRules.length - 1; ruleI >= 0; ruleI--) {
          var rule = sheet.cssRules[ruleI];

          if (rule.selectorText) {
            rule.selectorText = rule.selectorText.replace(':hover', ':active');
          }
        }
      }
    }
  }
}

Làm việc tuyệt vời cho tôi. Cảm ơn!
Inversion

1

Hãy thử chỉ đặt màu liên kết:

$("ul#mainFilter a").css('color','#000');

Chỉnh sửa: hoặc tốt hơn, sử dụng CSS, như Christopher đã đề xuất


jsfiddle.net/raPeX Tôi đã làm một ví dụ. Nó hoạt động nhưng thật ngu ngốc khi làm điều đó. tôi sẽ phải truy xuất mọi giá trị CSS và thêm chúng dưới dạng kiểu? Phải có cách tốt hơn. Tôi không muốn làm điều đó. nhưng +1 cho gợi ý
meo

Xin chào Meo, không không, mã của tôi ở trên đang nhắm mục tiêu một liên kết cụ thể vì đó là những gì tôi nghĩ bạn muốn. Bạn có thể khái quát hóa nó nhiều hơn bằng cách chỉ sử dụng athay vì sử dụng ul#mainFilter anếu đó là ý của bạn, hoặc bạn đang nói mọi liên kết trên trang là một màu khác?
Mottie

Tôi đã cập nhật bản trình diễn của bạn, với các nhận xét, để cho bạn thấy ý tôi: jsfiddle.net/raPeX/2
Mottie

tôi đã hiểu rồi cảm ơn bạn. Nhưng vấn đề là, không chỉ có màu sắc thay đổi trên di chuột của tôi, đôi khi nền của nó, đường viền, đôi khi thậm chí cả chiều cao dòng. Đó là lý do tại sao tôi sẽ dễ dàng hơn nếu chỉ ngăn di chuột, den ghi đè mọi hiệu ứng di chuột.
meo

Vá một phần cho ý tưởng này: Bạn có thể tạo css một quy tắc mà chọn cho a.jsOverride:hoverghi đè rằng tất cả các đặc điểm css, vì vậy js chỉ sẽ phải thêm rằng jsOverridelớp cho tất cả các liên kết khi tải trang ...
grossvogel

1

Trên thực tế, một cách khác để giải quyết vấn đề này có thể là ghi đè CSS bằng insertRule.

Nó cung cấp khả năng đưa các quy tắc CSS vào một biểu định kiểu hiện có / mới. Trong ví dụ cụ thể của tôi, nó sẽ như thế này:

//creates a new `style` element in the document
var sheet = (function(){
  var style = document.createElement("style");
  // WebKit hack :(
  style.appendChild(document.createTextNode(""));
  // Add the <style> element to the page
  document.head.appendChild(style);
  return style.sheet;
})();

//add the actual rules to it
sheet.insertRule(
 "ul#mainFilter a:hover { color: #0000EE }" , 0
);

Demo với ví dụ gốc 4 tuổi của tôi: http://jsfiddle.net/raPeX/21/

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.