Могу ли я отключить эффект CSS: hover с помощью JavaScript?

99

Я пытаюсь запретить браузеру использовать :hoverэффект CSS через JavaScript.

Я установить aи a:hoverстили в моем CSS, потому что я хочу , эффект парения, если JS не доступен. Но если JS есть в наличии, я хочу , чтобы переписать мою CSS эффект при наведении с гладкой один (используя цвет JQuery плагин, например.)

Я пробовал это:

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

Тоже пробовал return false;, но не работает.

Вот пример моей проблемы: http://jsfiddle.net/4rEzz/ . Ссылка должна просто исчезнуть, но не стать серой.

Как упоминал fudgey, обходным путем было бы сбросить стили наведения с помощью, .css()но мне пришлось бы перезаписать каждое отдельное свойство, указанное в CSS (см. Здесь: http://jsfiddle.net/raPeX/1/ ). Я ищу универсальное решение.

Кто-нибудь знает как это сделать?

PS: Я не хочу перезаписывать каждый стиль, который я установил для наведения.

Мео
источник

Ответы:

136

Боюсь, не существует универсального решения на чистом JavaScript. JavaScript не может отключить само :hoverсостояние CSS .

Однако вы можете попробовать следующий альтернативный обходной путь. Если вы не против немного поработать в HTML и CSS, это избавит вас от необходимости сбрасывать каждое свойство CSS вручную с помощью 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
Мне это решение нравится больше, чем решения noscript, потому что оно работает, когда CSS полностью содержится во внешних файлах, а также работает во время загрузки страницы, если сначала загружается CSS, а JS загружается позже. Использование jQuery для «постепенного улучшения» часто приводит к тому, что страницы не работают должным образом, если вы нажимаете на материал до того, как он загрузился. Я часто это вижу даже с быстрым браузером по быстрой ссылке.
Mr. Shiny and New and 宇
@Г-н. Shiny and New: согласен, мне это тоже нравится больше, чем мое решение! Я не уверен, почему я не заметил элегантности этого раньше ...
Джош
3
«Мне это решение нравится больше, чем решения noscript, потому что оно работает, когда CSS полностью содержится во внешних файлах» - так же как и <noscript>решение. Вы просто вставляете <link>теги в свой <noscript>, а не <style>теги. Мое решение позволяет хранить все в одном файле таблицы стилей, а не в нескольких файлах.
Пол Д. Уэйт
это не совсем то, что я искал, но я думаю, что это решение - лучший компромисс! Спасибо всем вам
meo
вы также можете скопировать тот же стиль с другим именем и с помощью jquery выбрать все элементы с этим классом, удалить класс и заменить его классом копирования.
chepe263
14

Используйте второй класс, которому назначен только наведение:

HTML

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

CSS

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

Теперь вы можете использовать Jquery для удаления класса, например, если элемент был нажат:

JQUERY

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

Надеюсь, этот ответ будет вам полезен.

Кай Ноак
источник
3
плюс 1. это не ортодоксально, но решает проблему довольно возвышенным образом.
Джим Толлан
11

Вы можете управлять таблицами стилей и правилами самих таблиц стилей с помощью 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);

Сделав атрибуты! Important и сделав это самым последним определением CSS, следует переопределить любое предыдущее определение, если только одно не является более конкретным. В этом случае вам, возможно, придется вставить больше правил.

Стивен П.
источник
1
Или вы можете поместить все правила noscript в одну таблицу стилей, а затем отключить таблицу стилей из javascript.
Шон Хоган
2
Или поместите <link>тег таблицы стилей noscript внутри <noscript>элемента? Это сработает, правда?
Пол Д. Уэйт
1
Или удалите «оскорбительное» правило: developer.mozilla.org/en/DOM/stylesheet.deleteRule
RoToRa
1
Даже IE5 может это сделать. Его метод называется по-другому, но он должен работать: msdn.microsoft.com/en-us/library/ms531195%28v=vs.85%29.aspx . Я не проверял другие браузеры, но полагаю, что все современные браузеры реализуют стандарт.
RoToRa
В Firefox я получаюError: The operation is insecure.
Alex W
11

Это похоже на ответ aSeptik, но как насчет этого подхода? Оберните CSS-код, который вы хотите отключить с помощью JavaScript, в <noscript>тегах. Таким образом, если javaScript отключен, :hoverбудет использоваться CSS , иначе будет использоваться эффект JavaScript.

Пример:

<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

Я использовал not()оператор CSS и addClass()функцию jQuery . Вот пример, когда вы нажимаете на элемент списка, он больше не зависает:

Например:

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

Я бы использовал CSS, чтобы событие: hover не меняло внешний вид ссылки.

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

Этот простой CSS означает, что ссылки всегда будут черными без подчеркивания. Я не могу сказать из вопроса, является ли изменение внешнего вида единственным, что вы хотите контролировать.

Кристофер Альтман
источник
хорошо, что есть эффект: hover, если JS недоступен на клиенте. Но если это так, мне нужно его перезаписать. Я установил класс: hover в своем CSS, просто хочу его отключить.
meo
@meo: вы не можете отключить псевдо-классы CSS, но вы можете переопределить их, установив для всех стилей ссылок одинаковый внешний вид / параметры. И этот ответ, и мой ответ делают это, но по-разному.
Mottie
3

Я бы рекомендовал заменить все :hoverсвойства на, :activeкогда вы обнаружите, что устройство поддерживает сенсорный ввод . Просто вызовите эту функцию, когда вы сделаете это как 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');
          }
        }
      }
    }
  }
}
Шобхит Шарма
источник
У меня отлично работает. Спасибо!
Inversion
1

Попробуйте просто установить цвет ссылки:

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

Изменить: или еще лучше, используйте CSS, как предложил Кристофер

Мотти
источник
jsfiddle.net/raPeX я привел пример. Это работает, но это глупо. мне нужно было бы получить каждое значение CSS и добавить их как стиль? Должен быть способ получше. Я не хочу этого делать. но +1 за подсказку
meo
Привет, Мео, нет, мой код выше был нацелен на конкретную ссылку, так как я думал, что это то, что тебе нужно. Вы могли бы обобщить это больше, просто используя aвместо этого, ul#mainFilter aесли это то, что вы имеете в виду, или вы говорите, что каждая ссылка на странице имеет другой цвет?
Mottie
Я обновил вашу демонстрацию с комментариями, чтобы показать вам, что я имею в виду: jsfiddle.net/raPeX/2
Mottie
Я уже получил это, спасибо. Но проблема в том, что при наведении курсора меняется не только цвет, иногда это фон, граница, иногда даже высота строки. Вот почему мне было бы проще просто предотвратить наведение, чтобы перезаписать каждый эффект наведения.
meo
Частичный патч для этой идеи: вы можете создать css правило, которое выбирает для a.jsOverride:hoverэтого, переопределяющее все характеристики css, поэтому js просто нужно будет добавить этот jsOverrideкласс ко всем ссылкам при загрузке страницы ...
Grossvogel
1

На самом деле, другим способом решения этой проблемы может быть перезапись CSS с помощью insertRule.

Это дает возможность вставлять правила CSS в существующую / новую таблицу стилей. В моем конкретном примере это будет выглядеть так:

//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
);

Демо с моим 4-летним оригинальным примером: http://jsfiddle.net/raPeX/21/

Мео
источник