Могу ли я отключить эффект 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/

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.