การเลือกและจัดการองค์ประกอบหลอก CSS เช่น :: before and :: หลังจากใช้ jQuery


943

มีวิธีการเลือก / จัดการองค์ประกอบหลอก CSS เช่น::beforeและ::after(และรุ่นเก่าที่มีเซมิโคลอนหนึ่งอัน) โดยใช้ jQuery หรือไม่?

ตัวอย่างเช่นสไตล์ชีทของฉันมีกฎต่อไปนี้:

.span::after{ content:'foo' }

ฉันจะเปลี่ยน 'foo' เป็น 'bar' โดยใช้ jQuery ได้อย่างไร


4
ฉันทำบางสิ่งบางอย่างที่เหมาะกับคุณ: gist.github.com/yckart/5563717
yckart

1
ฉันเกลียดความคิดเห็นดังกล่าวใน stackoverflow ที่ฉันกำลังจะเขียน (ที่ commenter ถามว่าทำไมคุณไม่ทำแบบตรงกันข้ามทั้งหมด ) แต่: ณ จุดหนึ่งควรตระหนักถึงปัญหาการออกแบบโค้ดและแทนที่องค์ประกอบหลอกด้วย ช่วงหรือบางสิ่งบางอย่าง ฉันเดาว่าคุณรู้ว่าฉันกำลังชี้ไปที่อะไร
zsitro

1
คำตอบที่ได้รับการยอมรับเป็นเลิศ แม้ว่าคุณจะพยายามบรรลุจุดต่าง ๆ ดังต่อไปนี้คำตอบจะไม่ทำงาน: 1. เปลี่ยนรูปแบบของ: ก่อนโดย JS 2. เปลี่ยนเนื้อหาของ: ก่อนโดย JS โปรดดูคำตอบของฉันหากคุณต้องการ
ผู้เรียน


@Learner ตอนนี้มีคำตอบสำหรับสิ่งเหล่านี้ทั้งหมด: stackoverflow.com/a/49618941/8620333
Temani Afif

คำตอบ:


694

คุณสามารถส่งเนื้อหาไปยังองค์ประกอบหลอกด้วยแอตทริบิวต์ data แล้วใช้ jQuery เพื่อจัดการกับสิ่งนั้น:

ใน HTML:

<span>foo</span>

ใน jQuery:

$('span').hover(function(){
    $(this).attr('data-content','bar');
});

ใน CSS:

span:after {
    content: attr(data-content) ' any other text you may want';
}

หากคุณต้องการป้องกัน 'ข้อความอื่น' ไม่ให้ปรากฏคุณสามารถรวมสิ่งนี้กับโซลูชันของ seucolega ดังนี้:

ใน HTML:

<span>foo</span>

ใน jQuery:

$('span').hover(function(){
    $(this).addClass('change').attr('data-content','bar');
});

ใน CSS:

span.change:after {
    content: attr(data-content) ' any other text you may want';
}

2
คุณมีลิงค์ในข้อมูลจำเพาะสำหรับการใช้attrฟังก์ชันนั้นกับcontentคุณสมบัติหรือไม่? ฉันประหลาดใจฉันไม่เคยได้ยินเรื่องนี้ ...
เควิน Peno

95
+1 สำหรับattr()แต่แย่มากที่ฉันไม่สามารถใช้กับคุณสมบัติอื่น ๆcontentได้ การสาธิต
Maksim Vi

28
นั่นเป็นเพราะยังไม่มีเบราว์เซอร์ใดที่มีการใช้งานattr()เกินกว่า CSS2 ในขณะที่ CSS2 นั้นattr()ถูกกำหนดไว้สำหรับcontentคุณสมบัติเท่านั้น
BoltClock

10
อัปเดตลิงก์สำหรับการอ้างอิงแอททริบิว: w3.org/TR/css3-values/#attr-notation


477

คุณคิดว่านี่เป็นคำถามง่าย ๆ ที่จะตอบทุกสิ่งที่ jQuery สามารถทำได้ น่าเสียดายที่ปัญหาเกิดขึ้นจากปัญหาทางเทคนิค: css: after และ: ก่อนกฎไม่ได้เป็นส่วนหนึ่งของ DOMดังนั้นจึงไม่สามารถแก้ไขได้โดยใช้วิธี DOM ของ jQuery

มีมีวิธีการที่จะจัดการกับองค์ประกอบเหล่านี้โดยใช้ JavaScript และ / หรือวิธีการแก้ปัญหา CSS; สิ่งที่คุณใช้ขึ้นอยู่กับข้อกำหนดที่แน่นอนของคุณ


ฉันจะเริ่มต้นด้วยสิ่งที่ถือว่าเป็นวิธี "ดีที่สุด" อย่างกว้างขวาง:

1) เพิ่ม / ลบคลาสที่กำหนดไว้ล่วงหน้า

ในวิธีการนี้คุณได้สร้างคลาสใน CSS ของคุณด้วยสไตล์ที่แตกต่าง:afterหรือ:beforeไม่ วางคลาส "ใหม่" นี้ในภายหลังในสไตล์ชีทของคุณเพื่อให้แน่ใจว่ามีการแทนที่:

p:before {
    content: "foo";
}
p.special:before {
    content: "bar";
}

จากนั้นคุณสามารถเพิ่มหรือลบคลาสนี้โดยใช้ jQuery (หรือวานิลลา JavaScript):

$('p').on('click', function() {
    $(this).toggleClass('special');
});

  • จุดเด่น:ใช้งานง่ายด้วย jQuery; เปลี่ยนแปลงอย่างรวดเร็วหลายรูปแบบในครั้งเดียว บังคับให้แยกข้อกังวลออกจากกัน (แยก CSS และ JS ออกจาก HTML)
  • จุดด้อย: CSS จะต้องเขียนไว้ล่วงหน้าดังนั้นเนื้อหาของ:beforeหรือ:afterไม่ไดนามิกทั้งหมด

2) เพิ่มสไตล์ใหม่ไปยังสไตล์ชีทของเอกสารโดยตรง

เป็นไปได้ที่จะใช้ JavaScript เพื่อเพิ่มสไตล์โดยตรงไปที่สไตล์ชีทเอกสารรวมถึง:afterและ:beforeสไตล์ jQuery ไม่มีทางลัดที่สะดวก แต่โชคดีที่ JS ไม่ซับซ้อน:

var str = "bar";
document.styleSheets[0].addRule('p.special:before','content: "'+str+'";');

.addRule()และ.insertRule()วิธีการที่เกี่ยวข้องได้รับการสนับสนุนอย่างดีพอสมควรในปัจจุบัน

ในรูปแบบที่หลากหลายคุณยังสามารถใช้ jQuery เพื่อเพิ่มสไตล์ชีทใหม่ทั้งหมดลงในเอกสารได้ แต่โค้ดที่จำเป็นนั้นไม่ได้สะอาดกว่า:

var str = "bar";
$('<style>p.special:before{content:"'+str+'"}</style>').appendTo('head');

หากเรากำลังพูดถึง "การจัดการ" ค่าต่าง ๆ ไม่เพียง แต่เพิ่มเข้าไปในค่านั้นเรายังสามารถอ่านค่าที่มีอยู่:afterหรือ:beforeสไตล์โดยใช้วิธีการอื่น:

var str = window.getComputedStyle(document.querySelector('p'), ':before') 
           .getPropertyValue('content');

เราสามารถแทนที่document.querySelector('p')ด้วย$('p')[0]เมื่อใช้ jQuery สำหรับรหัสที่สั้นกว่าเล็กน้อย

  • จุดเด่น:สตริงใด ๆ สามารถแทรกลงในสไตล์แบบไดนามิก
  • ข้อด้อย:รูปแบบดั้งเดิมจะไม่เปลี่ยนแปลง แต่ถูกแทนที่เท่านั้น การใช้ซ้ำ (ab) สามารถทำให้ DOM เติบโตขึ้นโดยพลการขนาดใหญ่

3) แก้ไขแอตทริบิวต์ DOM อื่น

คุณยังสามารถใช้attr()ใน CSSเพื่ออ่านแอตทริบิวต์ DOM เฉพาะ ( หากเบราว์เซอร์รองรับ:beforeก็รองรับattr()เช่นกัน ) ด้วยการรวมสิ่งนี้เข้ากับcontent:CSS ที่เตรียมไว้อย่างรอบคอบเราสามารถเปลี่ยนเนื้อหา (แต่ไม่ใช่คุณสมบัติอื่น ๆเช่นขอบหรือสี) ของ:beforeและ:afterแบบไดนามิก:

p:before {
    content: attr(data-before);
    color: red;
    cursor: pointer;
}

JS:

$('p').on('click', function () {
    $(this).attr('data-before','bar');
});

สิ่งนี้สามารถนำมารวมกับเทคนิคที่สองได้หาก CSS ไม่สามารถเตรียมพร้อมล่วงหน้า:

var str = "bar";

document.styleSheets[0].addRule('p:before', 'content: attr(data-before);');

$('p').on('click', function () {
    $(this).attr('data-before', str);
});

  • จุดเด่น:ไม่ได้สร้างสไตล์พิเศษอย่างไม่มีที่สิ้นสุด
  • ข้อด้อย: attrใน CSS สามารถใช้กับสตริงเนื้อหาเท่านั้นไม่ใช่ URL หรือสี RGB

2
ฉันพยายามกำหนดค่า glyphicon แบบไดนามิก (เช่นผ่านค่าเลขฐานสิบหก) ใน :: หลัง psedo เนื้อหา: องค์ประกอบ (เช่นเนื้อหา: "\ e043";) ดูเหมือนจะไม่ได้ผลสำหรับฉันดังนั้นฉันคิดว่ามันไม่ได้ผลกับค่าเลขฐานสิบหกสำหรับ glyphicons เช่นกัน?
user2101068

@ user2101068 คุณควรโพสต์นั้นเป็นคำถามใหม่ ฉันต้องเห็นรหัสทั้งหมดที่คุณใช้
Blazemonger

Blazemonger ขอขอบคุณสำหรับการตอบกลับอย่างรวดเร็ว .. น่าเสียดายที่มีรหัสค่อนข้างน้อยและต้องใช้ความพยายามเล็กน้อยในการตัดรหัสที่เกี่ยวข้องออก ฉันใช้เวลากว่า 12+ ชั่วโมงในการพยายามทำงานนี้และนี่เป็นความพยายามครั้งสุดท้ายของฉันในการทำงาน ฉันต้องลดความสูญเสียของฉัน ฉันหวังว่าคุณอาจจะสามารถตรวจสอบสมมติฐานของฉันอีกครั้ง: ค่าฐานสิบหกเมื่อใช้เทคนิคที่คุณอธิบายไว้ใน # 3 ข้างต้น (ก่อนโค้ดขนาดสั้น) ฉันสามารถแทรกสตริงเลขฐานสิบหกในองค์ประกอบเนื้อหา แต่จะแสดงข้อความสำหรับค่าฐานสิบหก glyphicon มากกว่า glyphicon จริง ความประทับใจโดยไม่เห็นรหัสทั้งหมดหรือไม่
2101068

1
@ user2101068 อย่าใช้สตริงฐานสิบหก คัดลอกและวางอักขระ Unicode จริงลงในแอตทริบิวต์ HTML แทน jsfiddle.net/mblase75/Lcsjkc5y
Blazemonger

เกี่ยวกับโซลูชัน 2 & 3 จริง ๆ แล้วคุณสามารถป้องกันไม่ให้สไตล์ชีทเติบโต (เกิน) หากคุณใช้: document.styleSheets [0] .insertRule (กฎ, ดัชนี) จากนั้นใช้ดัชนีนี้คุณสามารถลบกฎเมื่อไม่ต้องการ: เอกสาร styleSheets [0] .deleteRule (ดัชนี)
Picard

158

แม้ว่าเบราว์เซอร์จะแสดงผลผ่าน CSS เหมือนกับราวกับว่าเป็นองค์ประกอบ DOM จริงอื่น ๆ องค์ประกอบหลอกตัวเองไม่ได้เป็นส่วนหนึ่งของ DOM เนื่องจากองค์ประกอบปลอมตามชื่อที่แสดงไม่ใช่องค์ประกอบจริงดังนั้นคุณจึงไม่สามารถ เลือกและจัดการกับ jQuery โดยตรง (หรือAPI ของ JavaScript ใด ๆสำหรับเรื่องนั้นไม่ใช่แม้แต่Selectors API ) นี้นำไปใช้ใด ๆ หลอกองค์ประกอบที่มีรูปแบบที่คุณกำลังพยายามที่จะปรับเปลี่ยนด้วยสคริปต์และไม่เพียงและ::before::after

คุณสามารถเข้าถึงสไตล์องค์ประกอบแบบหลอกได้โดยตรงที่รันไทม์ผ่าน CSSOM (คิดว่าwindow.getComputedStyle()) ซึ่ง jQuery ไม่ได้รับการเปิดเผย.css()ซึ่งเป็นวิธีการที่ไม่สนับสนุนองค์ประกอบแบบหลอก

คุณสามารถหาวิธีอื่น ๆ รอบ ๆ ได้เสมอตัวอย่างเช่น:

  • การใช้สไตล์กับองค์ประกอบหลอกของคลาสหนึ่งคลาสหรือมากกว่านั้นจากนั้นสลับระหว่างคลาส (ดูคำตอบของ seucolegaสำหรับตัวอย่างอย่างรวดเร็ว) - นี่เป็นวิธีที่ใช้สำนวนง่าย ๆ เนื่องจากมันใช้ตัวเลือกอย่างง่าย แยกความแตกต่างระหว่างองค์ประกอบและสถานะองค์ประกอบวิธีที่พวกเขาตั้งใจจะใช้

  • จัดการสไตล์ที่ใช้กับองค์ประกอบหลอกกล่าวโดยการเปลี่ยนสไตล์ชีทของเอกสารซึ่งเป็นแฮ็คมากกว่า


78

คุณไม่สามารถเลือกองค์ประกอบหลอกใน jQuery เพราะไม่ได้เป็นส่วนหนึ่งของ DOM แต่คุณสามารถเพิ่มคลาสเฉพาะให้กับองค์ประกอบพ่อและควบคุมองค์ประกอบปลอมใน CSS

ตัวอย่าง

ใน jQuery:

<script type="text/javascript">
    $('span').addClass('change');
</script>

ใน CSS:

span.change:after { content: 'bar' }

48

นอกจากนี้เรายังสามารถพึ่งพาคุณสมบัติที่กำหนดเอง (ตัวแปร CSS หรือที่รู้จักกัน)เพื่อจัดการองค์ประกอบแบบหลอก เราสามารถอ่านข้อกำหนดที่:

คุณสมบัติที่กำหนดเองเป็นคุณสมบัติทั่วไปดังนั้นจึงสามารถประกาศในองค์ประกอบใด ๆ ได้รับการแก้ไขด้วยกฎการสืบทอดและกฎการเรียงซ้อน สามารถสร้างเงื่อนไขด้วย @media และกฎเงื่อนไขอื่น ๆ สามารถใช้ในแอตทริบิวต์สไตล์ของ HTMLสามารถอ่านหรือตั้งค่าได้ ใช้ CSSOMเป็นต้น

เมื่อพิจารณาถึงสิ่งนี้ความคิดคือการกำหนดคุณสมบัติที่กำหนดเองภายในองค์ประกอบและองค์ประกอบแบบหลอกจะสืบทอดมัน ดังนั้นเราสามารถปรับเปลี่ยนได้อย่างง่ายดาย

1) การใช้สไตล์อินไลน์ :

.box:before {
  content:var(--content,"I am a before element");
  color:var(--color, red);
  font-size:25px;
}
<div class="box"></div>
<div class="box" style="--color:blue;--content:'I am a blue element'"></div>
<div class="box" style="--color:black"></div>
<div class="box" style="--color:#f0f;--content:'another element'"></div>

2) การใช้ CSS และคลาส

.box:before {
  content:var(--content,"I am a before element");
  color:var(--color, red);
  font-size:25px;
}

.blue {
  --color:blue;
  --content:'I am a blue element';
}
.black {
  --color:black;
}
<div class="box"></div>
<div class="box black" ></div>
<div class="box blue"></div>

3) การใช้ javascript

document.querySelectorAll('.box')[0].style.setProperty("--color", "blue");
document.querySelectorAll('.box')[1].style.setProperty("--content", "'I am another element'");
.box:before {
  content:var(--content,"I am a before element");
  color:var(--color, red);
  font-size:25px;
}
<div class="box"></div>
<div class="box"></div>

4) การใช้ jQuery

$('.box').eq(0).css("--color", "blue");
/* the css() function with custom properties works only with a jQuery vesion >= 3.x
   with older version we can use style attribute to set the value. Simply pay
   attention if you already have inline style defined! 
*/
$('.box').eq(1).attr("style","--color:#f0f");
.box:before {
  content:"I am a before element";
  color:var(--color, red);
  font-size:25px;
}
<script src="https://code.jquery.com/jquery-3.3.1.min.js"></script>
<div class="box"></div>
<div class="box"></div>
<div class="box"></div>


นอกจากนี้ยังสามารถใช้กับค่าที่ซับซ้อนได้:

.box {
  --c:"content";
  --b:linear-gradient(red,blue);
  --s:20px;
  --p:0 15px;
}

.box:before {
  content: var(--c);
  background:var(--b);
  color:#fff;
  font-size: calc(2 * var(--s) + 5px);
  padding:var(--p);
}
<div class="box"></div>

คุณอาจสังเกตเห็นว่าฉันกำลังพิจารณาไวยากรณ์var(--c,value)ที่valueเป็นค่าเริ่มต้นและเรียกว่าค่าทางเลือก

จากสเปคเดียวกันเราสามารถอ่าน:

ค่าของคุณสมบัติที่กำหนดเองสามารถทดแทนเป็นค่าของคุณสมบัติอื่นด้วยฟังก์ชั่น var () ไวยากรณ์ของ var () คือ:

var() = var( <custom-property-name> [, <declaration-value> ]? )

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

และหลังจากนั้น:

ในการแทนที่ var () ในค่าของคุณสมบัติ:

  1. หากคุณสมบัติที่กำหนดเองที่ตั้งชื่อโดยอาร์กิวเมนต์แรกของvar()ฟังก์ชันคือ animation-tainted และvar()ฟังก์ชันกำลังถูกใช้ในคุณสมบัติ animation หรือหนึ่งใน longhands ของมันให้ถือว่าคุณสมบัติที่กำหนดเองนั้นมีค่าเริ่มต้นสำหรับอัลกอริทึมที่เหลือ
  2. หากค่าของคุณสมบัติที่กำหนดเองที่ตั้งชื่อโดยอาร์กิวเมนต์แรกของvar()ฟังก์ชันเป็นอะไรก็ได้ยกเว้นค่าเริ่มต้นให้แทนที่var()ฟังก์ชันด้วยค่าของคุณสมบัติที่กำหนดเองที่เกี่ยวข้อง
  3. มิฉะนั้นหากvar()ฟังก์ชันมีค่าทางเลือกเป็นอาร์กิวเมนต์ตัวที่สองให้แทนที่var()ฟังก์ชันด้วยค่าทางเลือก หากมีvar()การอ้างอิงใด ๆในทางเลือกให้แทนที่ด้วย
  4. มิฉะนั้นคุณสมบัติที่มีvar()ฟังก์ชันไม่ถูกต้องในเวลาที่คำนวณ

หากเราไม่ได้ตั้งค่าคุณสมบัติที่กำหนดเองหรือเราตั้งค่าเป็นinitialหรือมันมีค่าที่ไม่ถูกต้องจะใช้ค่าทางเลือก การใช้initialจะมีประโยชน์ในกรณีที่เราต้องการรีเซ็ตคุณสมบัติที่กำหนดเองเป็นค่าเริ่มต้น

ที่เกี่ยวข้อง

วิธีการเก็บค่าสืบทอดในคุณสมบัติที่กำหนดเอง CSS (ตัวแปร aka หรือ CSS)?

CSS คุณสมบัติที่กำหนดเอง (ตัวแปร) สำหรับรูปแบบกล่อง


โปรดทราบว่าตัวแปร CSS อาจไม่พร้อมใช้งานในเบราว์เซอร์ทั้งหมดที่คุณพิจารณาว่าเกี่ยวข้อง (เช่น IE 11): https://caniuse.com/#feat=css-variables


@ akalata ใช่รหัสต้องใช้ jQuery เวอร์ชัน 3.x .. ฉันเพิ่มรายละเอียดและทางเลือกอื่นด้วย jQuery;)
Temani Afif

สิ่งนี้จะทำงานใน IE 11 ได้อย่างไร
connexo

1
@connexo ชอบคุณลักษณะที่ดีและทันสมัย ​​.. มันไม่ได้รับการสนับสนุนและจะไม่สามารถทำงานได้caniuse.com/#feat=css-variables
Temani Afif

Ofc ฉันรู้ว่าและเนื่องจาก IE 11 ยังมีความเกี่ยวข้องฉันจึงพลาดข้อมูลส่วนนั้นในส่วนเกริ่นนำของคำตอบของคุณ
connexo

1
คำตอบนี้เป็นแบบฝึกหัดในเชิงลึกเกี่ยวกับการเชื่อมโยงและการดัดแปลงองค์ประกอบหลอกด้วย JavaScript โดยใช้ตัวแปร CSS ขอบคุณมากสำหรับเวลาและการแบ่งปันเทคนิคที่มีค่ามากนี้
LebCit

37

ในสิ่งที่คริสเตียนแนะนำคุณก็สามารถทำได้เช่นกัน:

$('head').append("<style>.span::after{ content:'bar' }</style>");

2
ที่นี่ควรเพิ่ม id-attribute ดังนั้นองค์ประกอบสามารถเลือกและลบก่อนที่จะมีการเพิ่มองค์ประกอบใหม่ หากไม่สามารถมีสไตล์ที่ไม่จำเป็นเกิดขึ้นได้
KS

24

นี่คือวิธีการเข้าถึง: after และ: before properties style, ที่กำหนดใน css:

// Get the color value of .element:before
var color = window.getComputedStyle(
    document.querySelector('.element'), ':before'
).getPropertyValue('color');

// Get the content value of .element:before
var content = window.getComputedStyle(
    document.querySelector('.element'), ':before'
).getPropertyValue('content');

11

หากคุณต้องการจัดการ :: before หรือ :: หลังจากองค์ประกอบ sudo ทั้งหมดผ่าน CSS คุณสามารถทำได้ JS ดูด้านล่าง;

jQuery('head').append('<style id="mystyle" type="text/css"> /* your styles here */ </style>');

สังเกตว่า<style>องค์ประกอบมี ID ซึ่งคุณสามารถใช้เพื่อลบออกและผนวกเข้ากับองค์ประกอบนั้นอีกครั้งหากสไตล์ของคุณเปลี่ยนแบบไดนามิก

ด้วยวิธีนี้องค์ประกอบของคุณมีสไตล์อย่างที่คุณต้องการผ่าน CSS ด้วยความช่วยเหลือของ JS


6

วิธีหนึ่งที่ทำงานได้ แต่ไม่มีประสิทธิภาพมากคือการเพิ่มกฎลงในเอกสารด้วยเนื้อหาใหม่และอ้างอิงกับคลาส ขึ้นอยู่กับสิ่งที่จำเป็นชั้นเรียนอาจต้องมีรหัสเฉพาะสำหรับแต่ละค่าในเนื้อหา

$("<style type='text/css'>span.id-after:after{content:bar;}</style>").appendTo($("head"));
$('span').addClass('id-after');

5

นี่คือ HTML:

<div class="icon">
  <span class="play">
    ::before
  </span>
</div>

คำนวณสไตล์ใน 'before' เดิม content: "VERIFY TO WATCH";

นี่คือ jQuery สองบรรทัดของฉันซึ่งใช้แนวคิดในการเพิ่มคลาสพิเศษเพื่ออ้างอิงองค์ประกอบนี้โดยเฉพาะจากนั้นจึงเพิ่มแท็กสไตล์ (ด้วยแท็ก! แท็กสำคัญ) เพื่อเปลี่ยน CSS ของค่าเนื้อหาขององค์ประกอบ sudo:

$("span.play:eq(0)").addClass('G');

$('body').append("<style>.G:before{content:'NewText' !important}</style>");


5

ขอบคุณทุกคน! ฉันจัดการเพื่อทำสิ่งที่ฉันต้องการ: D http://jsfiddle.net/Tfc9j/42/ ที่นี่มาดู

ฉันต้องการให้ความทึบของ div ภายนอกนั้นแตกต่างจาก opacity ของ div ภายในและการเปลี่ยนแปลงนั้นด้วยการคลิกที่ไหนสักแห่ง;) ขอบคุณ!

   $('#ena').on('click', function () {
        $('head').append("<style>#ena:before { opacity:0.3; }</style>");
    });

$('#duop').on('click', function (e) {

        $('head').append("<style>#ena:before { opacity:0.8; }</style>");

     e.stopPropagation(); 
    });

#ena{
    width:300px;
    height:300px;
    border:1px black solid;
    position:relative;
}
#duo{
    opacity:1;
    position:absolute;
    top:50px;
  width:300px;
    height:100px;
      background-color:white;
}
#ena:before {
    content: attr(data-before);
    color: white;
    cursor: pointer;
    position: absolute;
    background-color:red;
    opacity:0.9;
    width:100%;
    height:100%;
}


<div id="ena">
    <div id="duo">
        <p>ena p</p>
        <p id="duop">duoyyyyyyyyyyyyyy p</p>

    </div>   


</div>

ไม่ลองappendใช้htmlป้องกันดีที่สุด
KingRider

1
ระวัง: ที่นี่คุณกำลังผนวกแท็กสไตล์ไว้ที่ส่วนหัวทุกครั้งที่มีการจัดการคลิกหนึ่งครั้ง ฉันต้องการโค้ดวิธีลบอันเก่าก่อนที่จะเพิ่มอันใหม่
pupitetris

3

คุณอาจสร้างคุณสมบัติปลอมหรือใช้คุณสมบัติที่มีอยู่และสืบทอดในสไตล์ชีทขององค์ประกอบหลอก

var switched = false;

// Enable color switching
setInterval(function () {
    var color = switched ? 'red' : 'darkred';
    var element = document.getElementById('arrow');
    element.style.backgroundColor = color;
    
    // Managing pseudo-element's css
    // using inheritance.
    element.style.borderLeftColor = color;
    
    switched = !switched;
}, 1000);
.arrow {
    /* SET FICTIONAL PROPERTY */
    border-left-color:red;
    
    background-color:red;
    width:1em;
    height:1em;
    display:inline-block;
    position:relative;
}
.arrow:after {
    border-top:1em solid transparent;
    border-right:1em solid transparent;
    border-bottom:1em solid transparent;
    border-left:1em solid transparent;
    
    /* INHERIT PROPERTY */
    border-left-color:inherit;
    
    content:"";
    width:0;
    height:0;
    position:absolute;
    left:100%;
    top:-50%;
}
<span id="arrow" class="arrow"></span>

ดูเหมือนว่าจะไม่ทำงานสำหรับคุณสมบัติ "เนื้อหา" :(


3

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

css = {
before: function(elem,attr){ 

if($("#cust_style") !== undefined){ 
$("body").append("<style> " + elem + ":before {"  + attr +  "} </style>"); 
} else {
 $("#cust_style").remove();
$("body").append("<style> " + elem + ":before {"  + attr +  "} </style>"); 
}

}, after: function(elem,attr){
if($("#cust_style") !== undefined){ 
$("body").append("<style> " + elem + ":after {"  + attr +  "} </style>"); 

} else { $("#cust_style").remove();
$("body").append("<style> " + elem + ":after {"  + attr +  "} </style>"); 
}
}
}

ในปัจจุบันเพิ่มของ a / หรือผนวกองค์ประกอบสไตล์ซึ่งมีแอตทริบิวต์ที่จำเป็นของคุณซึ่งจะมีผลต่อองค์ประกอบเป้าหมายหลังจากองค์ประกอบ Pseudo

สิ่งนี้สามารถใช้เป็น

css.after("someElement"," content: 'Test'; position: 'absolute'; ") // editing / adding styles to :after

และ

css.before( ... ); // to affect the before pseudo element.

as after: และ before: องค์ประกอบเทียมไม่สามารถเข้าถึงได้โดยตรงผ่าน DOM ปัจจุบันยังไม่สามารถแก้ไขค่าเฉพาะของ css ได้อย่างอิสระ

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

ดังนั้นการทดลองของคุณเองกับสิ่งนี้และอื่น ๆ !

ขอแสดงความนับถือ - Adarsh ​​Hegde


3

ฉันมักจะเพิ่มฟังก์ชั่นของตัวเองซึ่งดูเหมือนนี้

function setPseudoElContent(selector, value) {    
    document.styleSheets[0].addRule(selector, 'content: "' + value + '";');
}

setPseudoElContent('.class::after', 'Hello World!');

หรือใช้ประโยชน์จากคุณสมบัติของ ES6:

const setPseudoElContent = (selector, value) => {    
    document.styleSheets[0].addRule(selector, `content: "${value}";`);
}

setPseudoElContent('.class::after', 'Hello World!');

2

เหตุใดจึงต้องเพิ่มคลาสหรือคุณลักษณะเมื่อคุณสามารถผนวก a styleto head

$('head').append('<style>.span:after{ content:'changed content' }</style>')

2

มีคำตอบมากมายที่นี่ แต่ไม่มีคำตอบที่ช่วยจัดการ css ของ:beforeหรือ:afterไม่ใช่ที่ยอมรับ

นี่คือวิธีที่ฉันเสนอให้ทำ สมมติว่า HTML ของคุณเป็นเช่นนี้:

<div id="something">Test</div>

และจากนั้นคุณกำลังตั้งค่า: ก่อนหน้านี้ใน CSS และออกแบบมันเช่น

#something:before{
   content:"1st";
   font-size:20px;
   color:red;
}
#something{
  content:'1st';
}

โปรดสังเกตว่าฉันได้ตั้งค่าcontentคุณสมบัติไว้ในองค์ประกอบด้วยเพื่อให้คุณสามารถนำออกได้อย่างง่ายดายในภายหลัง ตอนนี้มีbuttonคลิกที่คุณต้องการเปลี่ยนสีของ: ก่อนเป็นสีเขียวและขนาดแบบอักษรเป็น 30px คุณสามารถบรรลุสิ่งต่อไปนี้:

กำหนด CSS ตามสไตล์ที่คุณต้องการในบางคลาส.activeS:

.activeS:before{
   color:green !important;
   font-size:30px !important;
 }

ตอนนี้คุณสามารถเปลี่ยน: ก่อนสไตล์ได้โดยเพิ่มคลาสใน: ก่อนองค์ประกอบดังนี้:

<button id="changeBefore">Change</button>
<script>
    $('#changeBefore').click(function(){
        $('#something').addClass('activeS');
    });
</script>

หากคุณต้องการรับเนื้อหาของ:beforeมันสามารถทำได้ดังนี้:

<button id="getContent">Get Content</button>
<script>
    $('#getContent').click(function(){
        console.log($('#something').css('content'));//will print '1st'
    });
</script>

ในที่สุดหากคุณต้องการเปลี่ยน:beforeเนื้อหาแบบไดนามิกโดย jQuery คุณสามารถบรรลุดังต่อไปนี้:

<button id="changeBefore">Change</button>
<script>
    var newValue = '22';//coming from somewhere
    var add = '<style>#something:before{content:"'+newValue+'"!important;}</style>';
    $('#changeBefore').click(function(){
        $('body').append(add);
    });
</script>

การคลิกที่ปุ่ม "changeBefore" ด้านบนจะเปลี่ยน:beforeเนื้อหา#somethingเป็น '22' ซึ่งเป็นค่าแบบไดนามิก

ฉันหวังว่ามันจะช่วย


1

ฉันใช้ตัวแปรที่กำหนดไว้:rootภายในCSSเพื่อแก้ไข:after(องค์ประกอบเดียวกันกับ:before) องค์ประกอบหลอกโดยเฉพาะอย่างยิ่งการเปลี่ยนbackground-colorค่าสำหรับสไตล์ที่anchorกำหนดโดย.sliding-middle-out:hover:afterและcontentค่าสำหรับอีกanchor( #reference) ในตัวอย่างต่อไปนี้ที่สร้างสีแบบสุ่มโดยใช้ JavaScript / jQuery:

HTML

<a href="#" id="changeColor" class="sliding-middle-out" title="Generate a random color">Change link color</a>
<span id="log"></span>
<h6>
  <a href="https://stackoverflow.com/a/52360188/2149425" id="reference" class="sliding-middle-out" target="_blank" title="Stack Overflow topic">Reference</a>
</h6>
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script type="text/javascript" src="https://cdn.rawgit.com/davidmerfield/randomColor/master/randomColor.js"></script>

CSS

:root {
    --anchorsFg: #0DAFA4;
}
a, a:visited, a:focus, a:active {
    text-decoration: none;
    color: var(--anchorsFg);
    outline: 0;
    font-style: italic;

    -webkit-transition: color 250ms ease-in-out;
    -moz-transition: color 250ms ease-in-out;
    -ms-transition: color 250ms ease-in-out;
    -o-transition: color 250ms ease-in-out;
    transition: color 250ms ease-in-out;
}
.sliding-middle-out {
    display: inline-block;
    position: relative;
    padding-bottom: 1px;
}
.sliding-middle-out:after {
    content: '';
    display: block;
    margin: auto;
    height: 1px;
    width: 0px;
    background-color: transparent;

    -webkit-transition: width 250ms ease-in-out, background-color 250ms ease-in-out;
    -moz-transition: width 250ms ease-in-out, background-color 250ms ease-in-out;
    -ms-transition: width 250ms ease-in-out, background-color 250ms ease-in-out;
    -o-transition: width 250ms ease-in-out, background-color 250ms ease-in-out;
    transition: width 250ms ease-in-out, background-color 250ms ease-in-out;
}
.sliding-middle-out:hover:after {
    width: 100%;
    background-color: var(--anchorsFg);
    outline: 0;
}
#reference {
  margin-top: 20px;
}
.sliding-middle-out:before {
  content: attr(data-content);
  display: attr(data-display);
}

JS / jQuery

var anchorsFg = randomColor();
$( ".sliding-middle-out" ).hover(function(){
    $( ":root" ).css({"--anchorsFg" : anchorsFg});
});

$( "#reference" ).hover(
 function(){
    $(this).attr("data-content", "Hello World!").attr("data-display", "block").html("");
 },
 function(){
    $(this).attr("data-content", "Reference").attr("data-display", "inline").html("");
 }
);

การสนับสนุนattr()ยกเว้นในcontentนั้นหายากจริงๆ คุณอาจตรวจสอบ caniuse.com :rootและการสนับสนุน css-variables นั้นดีกว่า แต่ก็ยังไม่แพร่หลายมากนักเนื่องจากการสนับสนุนเป็นเรื่องใหม่ (ตรวจสอบการสนับสนุนได้ที่ caniuse.com)
BananaAcid

1

ฉันได้สร้างปลั๊กอิน jQuery เพื่อเพิ่มกฎ css-pseudo เช่นใช้.css()สำหรับองค์ประกอบเฉพาะ

  • รหัสปลั๊กอินและกรณีทดสอบอยู่ที่นี่
  • ใช้กรณีเป็นป๊อปอัพภาพ CSS ง่าย ๆที่นี่

การใช้งาน:

$('body')
  .css({
    backgroundColor: 'white'
  })
  .cssPseudo('after', {
    content: 'attr(title) ", you should try to hover the picture, then click it."',
    position: 'absolute',
    top: 20, left: 20  
  })
  .cssPseudo('hover:after', {
    content: '"Now hover the picture, then click it!"'
  });


0

คุณสามารถใช้ปลั๊กอินของฉันเพื่อจุดประสงค์นี้

JQuery:

(function() {
  $.pseudoElements = {
    length: 0
  };

  var setPseudoElement = function(parameters) {
    if (typeof parameters.argument === 'object' || (parameters.argument !== undefined && parameters.property !== undefined)) {
      for (var element of parameters.elements.get()) {
        if (!element.pseudoElements) element.pseudoElements = {
          styleSheet: null,
          before: {
            index: null,
            properties: null
          },
          after: {
            index: null,
            properties: null
          },
          id: null
        };

        var selector = (function() {
          if (element.pseudoElements.id !== null) {
            if (Number(element.getAttribute('data-pe--id')) !== element.pseudoElements.id) element.setAttribute('data-pe--id', element.pseudoElements.id);
            return '[data-pe--id="' + element.pseudoElements.id + '"]::' + parameters.pseudoElement;
          } else {
            var id = $.pseudoElements.length;
            $.pseudoElements.length++

              element.pseudoElements.id = id;
            element.setAttribute('data-pe--id', id);

            return '[data-pe--id="' + id + '"]::' + parameters.pseudoElement;
          };
        })();

        if (!element.pseudoElements.styleSheet) {
          if (document.styleSheets[0]) {
            element.pseudoElements.styleSheet = document.styleSheets[0];
          } else {
            var styleSheet = document.createElement('style');

            document.head.appendChild(styleSheet);
            element.pseudoElements.styleSheet = styleSheet.sheet;
          };
        };

        if (element.pseudoElements[parameters.pseudoElement].properties && element.pseudoElements[parameters.pseudoElement].index) {
          element.pseudoElements.styleSheet.deleteRule(element.pseudoElements[parameters.pseudoElement].index);
        };

        if (typeof parameters.argument === 'object') {
          parameters.argument = $.extend({}, parameters.argument);

          if (!element.pseudoElements[parameters.pseudoElement].properties && !element.pseudoElements[parameters.pseudoElement].index) {
            var newIndex = element.pseudoElements.styleSheet.rules.length || element.pseudoElements.styleSheet.cssRules.length || element.pseudoElements.styleSheet.length;

            element.pseudoElements[parameters.pseudoElement].index = newIndex;
            element.pseudoElements[parameters.pseudoElement].properties = parameters.argument;
          };

          var properties = '';

          for (var property in parameters.argument) {
            if (typeof parameters.argument[property] === 'function')
              element.pseudoElements[parameters.pseudoElement].properties[property] = parameters.argument[property]();
            else
              element.pseudoElements[parameters.pseudoElement].properties[property] = parameters.argument[property];
          };

          for (var property in element.pseudoElements[parameters.pseudoElement].properties) {
            properties += property + ': ' + element.pseudoElements[parameters.pseudoElement].properties[property] + ' !important; ';
          };

          element.pseudoElements.styleSheet.addRule(selector, properties, element.pseudoElements[parameters.pseudoElement].index);
        } else if (parameters.argument !== undefined && parameters.property !== undefined) {
          if (!element.pseudoElements[parameters.pseudoElement].properties && !element.pseudoElements[parameters.pseudoElement].index) {
            var newIndex = element.pseudoElements.styleSheet.rules.length || element.pseudoElements.styleSheet.cssRules.length || element.pseudoElements.styleSheet.length;

            element.pseudoElements[parameters.pseudoElement].index = newIndex;
            element.pseudoElements[parameters.pseudoElement].properties = {};
          };

          if (typeof parameters.property === 'function')
            element.pseudoElements[parameters.pseudoElement].properties[parameters.argument] = parameters.property();
          else
            element.pseudoElements[parameters.pseudoElement].properties[parameters.argument] = parameters.property;

          var properties = '';

          for (var property in element.pseudoElements[parameters.pseudoElement].properties) {
            properties += property + ': ' + element.pseudoElements[parameters.pseudoElement].properties[property] + ' !important; ';
          };

          element.pseudoElements.styleSheet.addRule(selector, properties, element.pseudoElements[parameters.pseudoElement].index);
        };
      };

      return $(parameters.elements);
    } else if (parameters.argument !== undefined && parameters.property === undefined) {
      var element = $(parameters.elements).get(0);

      var windowStyle = window.getComputedStyle(
        element, '::' + parameters.pseudoElement
      ).getPropertyValue(parameters.argument);

      if (element.pseudoElements) {
        return $(parameters.elements).get(0).pseudoElements[parameters.pseudoElement].properties[parameters.argument] || windowStyle;
      } else {
        return windowStyle || null;
      };
    } else {
      console.error('Invalid values!');
      return false;
    };
  };

  $.fn.cssBefore = function(argument, property) {
    return setPseudoElement({
      elements: this,
      pseudoElement: 'before',
      argument: argument,
      property: property
    });
  };
  $.fn.cssAfter = function(argument, property) {
    return setPseudoElement({
      elements: this,
      pseudoElement: 'after',
      argument: argument,
      property: property
    });
  };
})();

$(function() {
  $('.element').cssBefore('content', '"New before!"');
});
.element {
  width: 480px;
  margin: 0 auto;
  border: 2px solid red;
}

.element::before {
  content: 'Old before!';
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.1.1/jquery.min.js"></script>

<div class="element"></div>

ควรระบุค่าเช่นเดียวกับในฟังก์ชั่นปกติของ jQuery.css

นอกจากนี้คุณยังสามารถรับค่าของพารามิเตอร์หลอกองค์ประกอบเช่นในฟังก์ชั่นปกติของ jQuery.css:

console.log( $(element).cssBefore(parameter) );

JS:


GitHub: https://github.com/yuri-spivak/managing-the-properties-of-pseudo-elements/


0

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

<style id="pseudo"></style>

จากนั้น JavaScript จะมีลักษณะดังนี้:

var pseudo = document.getElementById("pseudo");

function setHeight() {
    let height = document.getElementById("container").clientHeight;
    pseudo.innerHTML = `.class:before { height: ${height}px; }`
}

setHeight()

ตอนนี้ในกรณีของฉันฉันต้องการสิ่งนี้เพื่อตั้งค่าความสูงขององค์ประกอบก่อนตามความสูงขององค์ประกอบอื่นและมันจะเปลี่ยนตามการปรับขนาดดังนั้นการใช้นี้ฉันสามารถเรียกใช้setHeight()ทุกครั้งที่มีการปรับขนาดหน้าต่างและจะเปลี่ยน<style>อย่างถูกต้อง

หวังว่าจะช่วยให้คนที่ติดอยู่พยายามทำสิ่งเดียวกัน


-1

ฉันมีบางสิ่งที่แตกต่างสำหรับคุณซึ่งง่ายและมีประสิทธิภาพ

    <style> 
    .case-after:after { // set your properties here like eg: 
        color:#3fd309 !important; 
     } 
     .case-before:before { // set your properties here like eg: 
        color:#151715 !important; 
     }
 </style>
  // case for after
    $('#button-id').on('click', function() {
        $(".target-div").toggleClass('case-after');
    });

     // case for before
    $('#button-id').on('click', function() {
        $(".target-div").toggleClass('case-before');
    });
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.