Dapatkah saya menonaktifkan CSS: efek hover melalui JavaScript?

99

Saya mencoba untuk mencegah browser menggunakan :hoverefek CSS, melalui JavaScript.

Saya telah mengatur gaya adan a:hoverdi CSS saya, karena saya ingin efek hover, jika JS tidak tersedia. Tetapi jika JS adalah tersedia, saya ingin menimpa efek hover CSS saya dengan halus satu (menggunakan warna jQuery plugin untuk contoh.)

Saya mencoba ini:

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

Saya juga mencobanya return false;, tetapi tidak berhasil.

Berikut adalah contoh masalah saya: http://jsfiddle.net/4rEzz/ . Tautan seharusnya memudar tanpa menjadi abu-abu.

Seperti yang disebutkan oleh fudgey, solusinya adalah menyetel ulang gaya hover menggunakan .css()tetapi saya harus menimpa setiap properti, yang ditentukan dalam CSS (lihat di sini: http://jsfiddle.net/raPeX/1/ ). Saya mencari solusi umum.

Apakah ada yang tahu bagaimana melakukan ini?

PS: Saya tidak ingin menimpa setiap gaya yang telah saya atur untuk hover.

meo
sumber

Jawaban:

136

Sayangnya, tidak ada solusi umum JavaScript murni. JavaScript tidak dapat mematikan status CSS :hoveritu sendiri.

Anda dapat mencoba solusi alternatif berikut. Jika Anda tidak keberatan mengotak-atik HTML dan CSS sedikit, Anda tidak perlu menyetel ulang setiap properti CSS secara manual melalui 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');
)
Paul D. Waite
sumber
5
Saya menyukai solusi ini lebih baik daripada solusi noscript karena ini berfungsi ketika CSS seluruhnya terdapat dalam file eksternal, dan juga berfungsi selama pemuatan halaman, jika CSS dimuat terlebih dahulu tetapi JS tidak dimuat hingga nanti. Menggunakan jQuery untuk "meningkatkan secara progresif" hal-hal sering kali menghasilkan halaman yang tidak berfungsi dengan baik jika Anda mengklik sesuatu sebelum selesai memuat. Bahkan dengan browser cepat pada tautan cepat saya sering melihat ini.
Tuan Shiny dan Baru 安 宇
@Bapak. Shiny and New: Saya setuju, saya juga menyukai ini lebih baik daripada solusi saya! Saya tidak yakin mengapa saya tidak memperhatikan keanggunan yang satu ini sebelumnya ...
Josh
3
“Saya menyukai solusi ini lebih baik daripada solusi noscript karena ini berfungsi ketika CSS seluruhnya terkandung dalam file eksternal” - begitu pula <noscript>solusinya. Anda hanya meletakkan <link>tag di dalam Anda <noscript>, bukan di <style>tag. Solusi saya memungkinkan Anda untuk menyimpan semuanya di dalam satu file stylesheet daripada beberapa file.
Paul D. Waite
itu tidak persis apa yang saya cari tetapi saya pikir solusi ini adalah kompromi terbaik! Terima kasih untuk kalian semua
meo
Anda juga dapat menyalin gaya yang sama dengan nama yang berbeda dan menggunakan jquery pilih semua elemen dengan kelas itu dan hapus kelas dan ganti dengan kelas salin.
chepe263
14

Gunakan kelas kedua yang hanya memiliki hover yang ditetapkan:

HTML

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

CSS

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

Sekarang Anda dapat menggunakan Jquery untuk menghapus kelas, misalnya jika elemen telah diklik:

JQUERY

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

Semoga jawaban ini bermanfaat.

Kai Noack
sumber
3
plus 1. ini tidak ortodoks, tetapi memecahkan masalah dengan cara yang cukup luhur.
jim tollan
11

Anda dapat memanipulasi stylesheet dan aturan stylesheet itu sendiri dengan 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);

Menjadikan atribut! Penting dan menjadikan ini definisi CSS terakhir harus menggantikan definisi sebelumnya, kecuali ada yang ditargetkan secara lebih spesifik. Anda mungkin harus memasukkan lebih banyak aturan dalam kasus itu.

Stephen P.
sumber
1
Atau Anda bisa meletakkan semua aturan noscript dalam satu stylesheet dan kemudian menonaktifkan stylesheet dari javascript.
Sean Hogan
2
Atau letakkan tag stylesheet noscript Anda <link>di dalam <noscript>elemen? Itu akan berhasil, bukan?
Paul D. Waite
1
Atau hapus aturan "menyinggung": developer.mozilla.org/en/DOM/stylesheet.deleteRule
RoToRa
1
Bahkan IE5 bisa melakukannya. Metodenya disebut berbeda, tetapi seharusnya berfungsi: msdn.microsoft.com/en-us/library/ms531195%28v=vs.85%29.aspx . Saya belum memeriksa browser lain, tetapi saya kira semua browser modern menerapkan standar.
RoToRa
Di Firefox saya mendapatkanError: The operation is insecure.
Alex W
11

Ini mirip dengan jawaban aSeptik, tapi bagaimana dengan pendekatan ini? Bungkus kode CSS yang ingin Anda nonaktifkan menggunakan JavaScript dalam <noscript>tag. Dengan begitu, jika javaScript tidak aktif, CSS :hoverakan digunakan, jika tidak, efek JavaScript akan digunakan.

Contoh:

<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>
Josh
sumber
4

Saya menggunakan not()operator CSS dan addClass()fungsi jQuery . Berikut ini contohnya, saat Anda mengklik item daftar, item tidak akan melayang lagi:

Sebagai contoh:

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');
});
ColdTuna
sumber
3

Saya akan menggunakan CSS untuk mencegah: acara hover mengubah tampilan tautan.

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

CSS sederhana ini berarti bahwa tautan akan selalu berwarna hitam dan tidak bergaris bawah. Saya tidak tahu dari pertanyaan apakah perubahan dalam penampilan adalah satu-satunya hal yang ingin Anda kendalikan.

Christopher Altman
sumber
ada baiknya ada: efek hover jika JS tidak tersedia pada klien. Tetapi jika saya perlu menimpanya. Saya telah menetapkan: hover class di css saya, hanya ingin menonaktifkannya.
meo
@meo: Anda tidak dapat menonaktifkan kelas psuedo CSS, tetapi Anda dapat menggantinya dengan menyetel semua gaya tautan agar memiliki tampilan / parameter yang sama. Baik jawaban ini maupun jawaban saya melakukan ini, hanya dengan cara yang berbeda.
Mottie
3

Saya akan merekomendasikan untuk mengganti semua :hoverproperti :activeketika Anda mendeteksi bahwa perangkat mendukung sentuhan. Panggil saja fungsi ini saat Anda melakukannya 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');
          }
        }
      }
    }
  }
}
Shobhit Sharma
sumber
Bekerja dengan baik untuk saya. Terima kasih!
Pembalikan
1

Coba atur saja warna link:

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

Edit: atau lebih baik lagi, gunakan CSS, seperti yang disarankan Christopher

Mottie
sumber
jsfiddle.net/raPeX saya telah membuat contoh. Itu berhasil tetapi agak bodoh untuk melakukan itu. saya harus mengambil setiap nilai CSS dan menambahkannya sebagai gaya? Pasti ada cara yang lebih baik. Saya tidak ingin melakukan itu. tapi +1 untuk petunjuknya
meo
Hai Meo, tidak, tidak, kode saya di atas menargetkan tautan tertentu karena saya pikir Anda menginginkannya. Anda dapat menggeneralisasikannya lebih banyak dengan hanya menggunakan adaripada ul#mainFilter ajika itu yang Anda maksud, atau apakah Anda mengatakan setiap link pada halaman memiliki warna yang berbeda?
Mottie
Saya telah memperbarui demo Anda, dengan komentar, untuk menunjukkan kepada Anda apa yang saya maksud: jsfiddle.net/raPeX/2
Mottie
ive sudah mendapatkannya terima kasih. Tapi masalahnya, tidak hanya ada warna yang berubah pada hover saya, terkadang backgroundnya menjadi, border, terkadang bahkan tinggi line. Itulah mengapa akan lebih mudah bagi saya untuk mencegah hover, den menimpa setiap efek hover.
meo
Tambalan parsial untuk ide ini: Anda dapat membuat css aturan yang memilih untuk a.jsOverride:hovermenimpa semua karakteristik css, jadi js hanya perlu menambahkan jsOverridekelas itu ke semua tautan saat halaman dimuat ...
grossvogel
1

Sebenarnya cara lain untuk mengatasinya adalah dengan menimpa CSS dengan insertRule.

Ini memberi kemampuan untuk memasukkan aturan CSS ke stylesheet yang ada / baru. Dalam contoh konkret saya akan terlihat seperti ini:

//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 dengan contoh asli saya yang berumur 4 tahun: http://jsfiddle.net/raPeX/21/

meo
sumber