ฉันสามารถปิด CSS: hover effect ผ่าน 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 安宇

@นาย. Shiny and New: ฉันเห็นด้วยฉันชอบสิ่งนี้ดีกว่าวิธีแก้ปัญหาของฉันด้วย! ฉันไม่แน่ใจว่าทำไมฉันไม่สังเกตเห็นความสง่างามของสิ่งนี้มาก่อน ...

3
"ฉันชอบโซลูชันนี้ดีกว่าโซลูชัน noscript เพราะวิธีนี้ใช้ได้เมื่อ CSS อยู่ในไฟล์ภายนอกทั้งหมด" - <noscript>โซลูชันนี้ก็เช่นกัน คุณแค่ใส่<link>แท็กไว้ในแท็กของคุณ<noscript>แทน<style>แท็ก วิธีแก้ปัญหาของฉันช่วยให้คุณเก็บทุกอย่างไว้ในไฟล์สไตล์ชีทเดียวแทนที่จะเป็นไฟล์หลายไฟล์
Paul D. Waite

มันไม่ใช่สิ่งที่ฉันกำลังมองหา แต่ฉันคิดว่าวิธีนี้เป็นการประนีประนอมที่ดีที่สุด! ขอบคุณทุกท่าน
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. มันไม่ใช่ออร์โธดอกซ์ แต่ทำให้ปัญหาแตกเป็นเสี่ยง ๆ
jim tollan

11

คุณสามารถจัดการสไตล์ชีทและกฎสไตล์ชีทได้ด้วยตัวเองด้วยจาวาสคริปต์

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

ทำให้แอตทริบิวต์! มีความสำคัญและทำให้คำจำกัดความ CSS สุดท้ายควรแทนที่คำจำกัดความก่อนหน้าใด ๆ เว้นแต่จะมีการกำหนดเป้าหมายไว้เป็นพิเศษ คุณอาจต้องแทรกกฎเพิ่มเติมในกรณีนั้น


1
หรือคุณสามารถใส่กฎ noscript ทั้งหมดในสไตล์ชีตเดียวแล้วปิดใช้งานสไตล์ชีทจากจาวาสคริปต์
Sean Hogan

2
หรือใส่<link>แท็กสไตล์ชีทของคุณใน<noscript>องค์ประกอบ? ได้ผลใช่มั้ย?
Paul D.Waite

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 event เปลี่ยนรูปลักษณ์ของลิงค์

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

CSS แบบธรรมดานี้หมายความว่าลิงก์จะเป็นสีดำและไม่ขีดเส้นใต้ ฉันไม่สามารถบอกได้จากคำถามว่าการเปลี่ยนแปลงรูปลักษณ์เป็นสิ่งเดียวที่คุณต้องการควบคุมหรือไม่


เป็นการดีที่มีเอฟเฟกต์: โฮเวอร์หาก JS ไม่สามารถใช้ได้บนไคลเอนต์ แต่ถ้าเป็นฉันต้องเขียนทับ ฉันได้ตั้งค่าคลาส: hover ใน css ของฉันเพียงแค่ต้องการปิดการใช้งาน
แม้ว

@meo: คุณไม่สามารถปิดการใช้งานคลาส CSS psuedo ได้ แต่คุณสามารถลบล้างได้โดยตั้งค่ารูปแบบลิงก์ทั้งหมดให้มีลักษณะ / พารามิเตอร์เหมือนกัน ทั้งคำตอบนี้และคำตอบของฉันทำในรูปแบบที่แตกต่างกัน
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');
          }
        }
      }
    }
  }
}

ใช้งานได้ดีสำหรับฉัน ขอบคุณ!
ผกผัน

1

ลองตั้งค่าสีของลิงค์:

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

แก้ไข: หรือดีกว่านั้นให้ใช้ CSS ตามที่ Christopher แนะนำ


jsfiddle.net/raPeXฉันได้ทำตัวอย่าง มันได้ผล แต่มันโง่มากที่ทำแบบนั้น ฉันจะต้องดึงทุกค่า CSS และเพิ่มเป็นสไตล์? ต้องมีวิธีที่ดีกว่านี้ ฉันไม่อยากทำแบบนั้น แต่ +1 สำหรับคำใบ้
meo

สวัสดี Meo ไม่ไม่รหัสของฉันด้านบนกำหนดเป้าหมายไปที่ลิงก์เฉพาะเนื่องจากเป็นสิ่งที่ฉันคิดว่าคุณต้องการ คุณสามารถสรุปได้มากขึ้นโดยใช้aแทนul#mainFilter aว่านั่นคือสิ่งที่คุณหมายถึงหรือคุณกำลังบอกว่าทุกลิงก์ในหน้าเว็บเป็นสีที่ต่างกัน?
Mottie

ฉันได้อัปเดตการสาธิตของคุณพร้อมความคิดเห็นเพื่อแสดงให้คุณเห็นว่าฉันหมายถึงอะไร: jsfiddle.net/raPeX/2
Mottie

ive เข้าใจแล้วขอบคุณ แต่ปัญหาก็คือไม่มีแค่สีที่เปลี่ยนไปบนโฮเวอร์ของฉันบางครั้งมันก็เป็นพื้นหลังเป็นเส้นขอบบางครั้งก็เป็นความสูงของเส้น นั่นเป็นเหตุผลว่าทำไมมันจึงง่ายกว่าสำหรับฉันที่จะป้องกันไม่ให้โฮเวอร์เขียนทับเอฟเฟกต์โฮเวอร์ทุกรายการ
แม้ว

แพตช์บางส่วนสำหรับแนวคิดนี้: คุณสามารถสร้าง 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/

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.