Chọn và thao tác các phần tử giả CSS như :: trước và :: sau khi sử dụng jQuery


943

Có cách nào để chọn / thao tác các phần tử giả CSS như ::before::after(và phiên bản cũ với một dấu chấm phẩy) bằng jQuery không?

Ví dụ: biểu định kiểu của tôi có quy tắc sau:

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

Làm cách nào tôi có thể thay đổi 'foo' thành 'bar' bằng jQuery?


4
Tôi đã làm một cái gì đó phù hợp với bạn: gist.github.com/yckart/5563717
yckart

1
Tôi ghét những bình luận như vậy về stackoverflow mà tôi sẽ viết (trong đó người bình luận hỏi tại sao bạn không làm điều đó hoàn toàn ngược lại? ), Nhưng: đến một lúc nào đó, người ta nên nhận ra vấn đề thiết kế mã và thay thế phần tử giả đó bằng một span hoặc một cái gì đó. Tôi đoán bạn biết những gì tôi đang chỉ vào.
zsitro

1
Câu trả lời được chấp nhận là tuyệt vời. Mặc dù nếu bạn đang cố gắng đạt được bất kỳ điểm nào sau đây, câu trả lời sẽ không hoạt động: 1. thay đổi phong cách của: trước bởi JS. 2. thay đổi nội dung của: trước bởi JS Vui lòng xem câu trả lời của tôi cho điều đó nếu bạn cần.
Học viên


@Learner Bây giờ có câu trả lời cho tất cả những điều này: stackoverflow.com/a/49618941/8620333
Temani Afif

Câu trả lời:


695

Bạn cũng có thể chuyển nội dung cho phần tử giả bằng thuộc tính dữ liệu và sau đó sử dụng jQuery để thao tác điều đó:

Trong HTML:

<span>foo</span>

Trong jQuery:

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

Trong CSS:

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

Nếu bạn muốn ngăn 'văn bản khác' hiển thị, bạn có thể kết hợp điều này với giải pháp của seucolega như thế này:

Trong HTML:

<span>foo</span>

Trong jQuery:

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

Trong CSS:

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

2
Bạn có một liên kết trong thông số kỹ thuật để sử dụng attrchức năng đó đối với contenttài sản không? Tôi ngạc nhiên Tôi chưa bao giờ nghe về điều này ...
Kevin Peno

95
+1 cho attr(), quá tệ, tôi không thể sử dụng nó với các thuộc tính khác content. Bản demo
Maksim Vi.

28
Đó là bởi vì chưa có trình duyệt nào tồn tại attr()ngoài CSS2, trong khi đó trong CSS2 attr()chỉ được xác định cho thuộc contenttính.
BoltClock

10
Liên kết được cập nhật cho các tham chiếu thuộc tính: w3.org/TR/css3-values/#attr-notation


477

Bạn sẽ nghĩ rằng đây sẽ là một câu hỏi đơn giản để trả lời, với mọi thứ khác mà jQuery có thể làm. Thật không may, vấn đề bắt nguồn từ một vấn đề kỹ thuật: css: after và: before quy tắc không phải là một phần của DOM và do đó không thể thay đổi bằng các phương thức DOM của jQuery.

nhiều cách để thao tác các phần tử này bằng cách sử dụng JavaScript và / hoặc giải pháp CSS; cái nào bạn sử dụng phụ thuộc vào yêu cầu chính xác của bạn.


Tôi sẽ bắt đầu với những gì được coi là phương pháp "tốt nhất":

1) Thêm / xóa một lớp định trước

Theo cách tiếp cận này, bạn đã tạo một lớp trong CSS bằng một kiểu :afterhoặc :beforekiểu khác. Đặt lớp "mới" này sau trong biểu định kiểu của bạn để đảm bảo nó ghi đè:

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

Sau đó, bạn có thể dễ dàng thêm hoặc xóa lớp này bằng jQuery (hoặc vanilla JavaScript):

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

  • Ưu điểm: Dễ thực hiện với jQuery; nhanh chóng thay đổi nhiều phong cách cùng một lúc; thực thi tách các mối quan tâm (tách biệt CSS và JS khỏi HTML của bạn)
  • Nhược điểm: CSS phải được viết sẵn, vì vậy nội dung của :beforehoặc :afterkhông hoàn toàn động

2) Thêm kiểu mới trực tiếp vào biểu định kiểu của tài liệu

Có thể sử dụng JavaScript để thêm kiểu trực tiếp vào biểu định kiểu tài liệu, bao gồm :after:beforekiểu. jQuery không cung cấp một lối tắt thuận tiện, nhưng may mắn thay, JS không phức tạp như vậy:

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

.addRule()và các .insertRule()phương pháp liên quan được hỗ trợ khá tốt hiện nay.

Là một biến thể, bạn cũng có thể sử dụng jQuery để thêm một biểu định kiểu hoàn toàn mới vào tài liệu, nhưng mã cần thiết không phải là bất kỳ trình dọn dẹp nào:

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

Nếu chúng ta đang nói về việc "thao túng" các giá trị, không chỉ thêm vào chúng, chúng ta cũng có thể đọc các kiểu hiện có :afterhoặc :beforekiểu sử dụng một cách tiếp cận khác:

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

Chúng ta có thể thay thế document.querySelector('p')bằng $('p')[0]khi sử dụng jQuery, với mã ngắn hơn một chút.

  • Ưu điểm: bất kỳ chuỗi nào có thể được tự động chèn vào kiểu
  • Nhược điểm: kiểu gốc không bị thay đổi, chỉ bị ghi đè; việc sử dụng lặp đi lặp lại (ab) có thể làm cho DOM phát triển lớn tùy ý

3) Thay đổi thuộc tính DOM khác

Bạn cũng có thể sử dụng attr()CSS của mình để đọc một thuộc tính DOM cụ thể. ( Nếu một trình duyệt hỗ trợ :before, nó cũng hỗ trợ attr(). ) Bằng cách kết hợp điều này với content:một số CSS được chuẩn bị kỹ lưỡng, chúng tôi có thể thay đổi nội dung (nhưng không phải các thuộc tính khác, như lề hoặc màu) :before:afterđộng:

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

JS:

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

Điều này có thể được kết hợp với kỹ thuật thứ hai nếu CSS không thể được chuẩn bị trước thời hạn:

var str = "bar";

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

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

  • Ưu điểm: Không tạo ra các kiểu phụ vô tận
  • Nhược điểm: attr trong CSS chỉ có thể áp dụng cho chuỗi nội dung, không phải URL hoặc màu RGB

2
Tôi đang cố gắng tự động đặt các giá trị glyphicon (nghĩa là thông qua các giá trị hex của chúng) trong :: sau psedo. nội dung: phần tử (ví dụ: nội dung: "\ e043";). nó dường như không hoạt động đối với tôi vì vậy tôi cho rằng nó cũng không hoạt động với các giá trị hex cho glyphicons?
dùng2101068

@ user2101068 Bạn nên đăng nó như một câu hỏi mới. Tôi phải xem tất cả các mã bạn đang sử dụng.
Blazemonger

Blazemonger, cảm ơn vì đã trả lời nhanh chóng .. thật không may là có khá nhiều mã và sẽ mất khá nhiều nỗ lực để lấy ra mã liên quan. Tôi đã dành hơn 12 giờ cố gắng để có được tác phẩm này và đây là nỗ lực thở hổn hển cuối cùng của tôi để khiến nó hoạt động. Tôi cần phải cắt lỗ của tôi. Tôi đã hy vọng bạn có thể chỉ cần xác minh lại giá trị giả định của tôi: các giá trị hex khi sử dụng kỹ thuật bạn mô tả trong # 3 ở trên (trước đoạn mã). Tôi có thể chèn chuỗi hex trong phần tử nội dung nhưng nó hiển thị văn bản cho giá trị hex glyphicon chứ không phải glyphicon thực tế. Ấn tượng mà không thấy hết mã?
dùng2101068

1
@ user2101068 Đừng sử dụng chuỗi hex; thay vào đó, sao chép và dán ký tự Unicode thực tế vào thuộc tính HTML. jsfiddle.net/mblase75/Lcsjkc5y
Blazemonger

liên quan đến giải pháp 2. & 3. thực sự bạn có thể ngăn biểu định kiểu (tăng) phát triển nếu bạn sử dụng: document.styleSheets [0] .insertRule (quy tắc, chỉ mục), sau đó sử dụng chỉ mục này bạn có thể xóa quy tắc khi không cần thiết: tài liệu. styleSheets [0] .deleteRule (index)
Picard

158

Mặc dù chúng được trình duyệt hiển thị thông qua CSS như thể chúng giống như các phần tử DOM thực khác, bản thân các phần tử giả không phải là một phần của DOM, vì các phần tử giả, như tên gọi, không phải là phần tử thực, và do đó bạn không thể chọn và thao tác trực tiếp với jQuery (hoặc bất kỳ API JavaScript nào cho vấn đề đó, thậm chí không phải API chọn ). Điều này áp dụng cho bất kỳ yếu tố giả nào có phong cách bạn đang cố gắng sửa đổi bằng tập lệnh, không chỉ ::before::after.

Bạn chỉ có thể truy cập các kiểu phần tử giả trực tiếp trong thời gian chạy thông qua CSSOM (think window.getComputedStyle()), không được jQuery tiết lộ .css(), một phương thức không hỗ trợ các phần tử giả.

Tuy nhiên, bạn luôn có thể tìm các cách khác xung quanh nó, ví dụ:

  • Áp dụng các kiểu cho các phần tử giả của một hoặc nhiều lớp tùy ý, sau đó chuyển đổi giữa các lớp (xem câu trả lời của seucolega để biết ví dụ nhanh) - đây là cách thành ngữ vì nó sử dụng các bộ chọn đơn giản (mà phần tử giả không phải) phân biệt giữa các yếu tố và trạng thái thành phần, cách chúng được sử dụng

  • Thao tác các kiểu đang được áp dụng cho các phần tử giả đã nói, bằng cách thay đổi biểu định kiểu tài liệu, phần lớn là hack


78

Bạn không thể chọn các phần tử giả trong jQuery vì chúng không phải là một phần của DOM. Nhưng bạn có thể thêm một lớp cụ thể vào phần tử cha và điều khiển các phần tử giả của nó trong CSS.

THÍ DỤ

Trong jQuery:

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

Trong CSS:

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

48

Chúng ta cũng có thể dựa vào các thuộc tính tùy chỉnh (còn gọi là biến CSS) để thao tác phần tử giả. Chúng ta có thể đọc trong đặc tả rằng:

Thuộc tính tùy chỉnh là thuộc tính thông thường, do đó chúng có thể được khai báo trên bất kỳ phần tử nào, được giải quyết bằng quy tắc thừa kếtầng thông thường , có thể được tạo điều kiện với @media và các quy tắc có điều kiện khác , có thể được đọc hoặc đặt trong thuộc tính kiểu HTML , có thể được đọc hoặc đặt sử dụng CSSOM , v.v.

Xem xét điều này, ý tưởng là xác định thuộc tính tùy chỉnh trong phần tử và phần tử giả sẽ đơn giản kế thừa nó; do đó chúng ta có thể dễ dàng sửa đổi nó.

1) Sử dụng kiểu nội tuyến :

.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) Sử dụng CSS và các lớp

.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) Sử dụng 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) Sử dụng 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>


Nó cũng có thể được sử dụng với các giá trị phức tạp:

.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>

Bạn có thể nhận thấy rằng tôi đang xem xét cú pháp var(--c,value)ở đâu valuelà giá trị mặc định và còn được gọi là giá trị dự phòng.

Từ cùng một đặc điểm kỹ thuật chúng ta có thể đọc:

Giá trị của thuộc tính tùy chỉnh có thể được thay thế thành giá trị của thuộc tính khác bằng hàm var (). Cú pháp của var () là:

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

Đối số đầu tiên cho hàm là tên của thuộc tính tùy chỉnh được thay thế. Đối số thứ hai cho hàm, nếu được cung cấp, là giá trị dự phòng, được sử dụng làm giá trị thay thế khi thuộc tính tùy chỉnh được tham chiếu không hợp lệ.

Và sau đó:

Để thay thế một var () trong giá trị của thuộc tính:

  1. Nếu thuộc tính tùy chỉnh được đặt tên bởi đối số đầu tiên của var()hàm là bị mờ hoạt hình và var()hàm đang được sử dụng trong thuộc tính hoạt hình hoặc một trong các hàm dài của nó, hãy coi thuộc tính tùy chỉnh là có giá trị ban đầu cho phần còn lại của thuật toán này.
  2. Nếu giá trị của thuộc tính tùy chỉnh được đặt tên bởi đối số đầu tiên cho var()hàm là bất cứ thứ gì ngoại trừ giá trị ban đầu, hãy thay thế var()hàm bằng giá trị của thuộc tính tùy chỉnh tương ứng.
  3. Mặt khác, nếu var()hàm có giá trị dự phòng làm đối số thứ hai của nó, hãy thay thế var()hàm bằng giá trị dự phòng. Nếu có bất kỳ var()tài liệu tham khảo nào trong dự phòng, hãy thay thế chúng.
  4. Mặt khác, thuộc tính chứa var()hàm không hợp lệ tại thời điểm tính giá trị.

Nếu chúng ta không đặt thuộc tính tùy chỉnh HOẶC chúng ta đặt nó thành initialHOẶC nó chứa giá trị không hợp lệ thì giá trị dự phòng sẽ được sử dụng. Việc sử dụng initialcó thể hữu ích trong trường hợp chúng tôi muốn đặt lại một thuộc tính tùy chỉnh về giá trị mặc định của nó.

Liên quan

Làm cách nào để lưu trữ giá trị kế thừa bên trong thuộc tính tùy chỉnh CSS (còn gọi là biến CSS)?

Thuộc tính tùy chỉnh CSS (biến) cho mô hình hộp


Xin lưu ý rằng các biến CSS có thể không có sẵn trong tất cả các trình duyệt mà bạn cho là có liên quan (ví dụ: IE 11): https://caniuse.com/#feat=css-variables


@akalata có, mã yêu cầu phiên bản jQuery 3.x .. Tôi đã thêm chi tiết và một thay thế khác với jQuery;)
Temani Afif

Làm thế nào điều này sẽ thực hiện trong IE 11?
Connexo

1
@connexo giống như bất kỳ tốt và tính năng hiện đại .. nó không được hỗ trợ và không làm việc sẽ caniuse.com/#feat=css-variables
Temani Afif

Tất nhiên tôi biết điều đó và vì IE 11 vẫn còn rất phù hợp, tôi đã bỏ lỡ phần thông tin đó ngay trong phần giới thiệu câu trả lời của bạn.
Connexo

1
Câu trả lời này là một hướng dẫn chuyên sâu về các yếu tố giả liên quan và sửa đổi với JavaScript bằng cách sử dụng các biến CSS. Cảm ơn bạn rất nhiều vì thời gian của bạn và đã chia sẻ (các) kỹ thuật vô cùng quý giá này.
LebCit

37

Theo dòng những gì Christian gợi ý, bạn cũng có thể làm:

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

2
Ở đây nên được thêm một thuộc tính id, vì vậy phần tử có thể được chọn và xóa trước khi thêm một thuộc tính mới. Nếu không, có thể xuất hiện rất nhiều nút kiểu không cần thiết.
KS

24

Đây là cách để truy cập: after và: before thuộc tính style, được xác định trong 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

NẾU bạn muốn thao tác các phần tử :: trước hoặc :: sau sudo hoàn toàn thông qua CSS, bạn có thể thực hiện nó. Xem bên dưới;

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

Lưu ý cách <style>phần tử có ID, mà bạn có thể sử dụng để xóa nó và nối lại nó nếu kiểu của bạn thay đổi linh hoạt.

Theo cách này, phần tử của bạn là kiểu chính xác theo cách bạn muốn thông qua CSS, với sự trợ giúp của JS.


6

một cách làm việc nhưng không hiệu quả là thêm một quy tắc vào tài liệu với nội dung mới và tham chiếu nó với một lớp. tùy thuộc vào những gì cần thiết, lớp có thể cần một id duy nhất cho mỗi giá trị trong nội dung.

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

5

Đây là HTML:

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

Kiểu tính toán trên 'trước' là content: "VERIFY TO WATCH";

Đây là hai dòng jQuery của tôi, sử dụng ý tưởng thêm một lớp bổ sung để tham chiếu cụ thể phần tử này và sau đó nối thêm thẻ kiểu (với thẻ! Quan trọng) để thay đổi CSS của giá trị nội dung của phần tử sudo:

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

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


5

Cảm ơn tất cả! tôi quản lý để làm những gì tôi muốn: D http://jsfiddle.net/Tfc9j/42/ ở đây hãy xem

tôi muốn có độ mờ đục của div bên ngoài khác với độ mờ đục của div bên trong và thay đổi đó bằng một cú nhấp chuột ở đâu đó;) Cảm ơn!

   $('#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>

Không thử append, sử dụng htmllà tốt nhất để ngăn chặn
KingRider

1
Xem ra: ở đây bạn đang gắn thẻ kiểu vào đầu mỗi khi một trong những nhấp chuột đó được xử lý. Tôi muốn viết mã một cách để loại bỏ cái cũ trước khi thêm cái mới.
sinh

3

Bạn có thể tạo một tài sản giả hoặc sử dụng một tài sản hiện có và kế thừa nó trong biểu định kiểu của phần tử giả.

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>

Có vẻ như nó không hoạt động cho thuộc tính "nội dung" :(


3

Điều này không thực tế vì tôi đã không viết điều này cho việc sử dụng trong thế giới thực, chỉ để cho bạn một ví dụ về những gì có thể đạt được.

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

cái này hiện đang thêm a / hoặc nối thêm phần tử Style chứa thuộc tính cần thiết của bạn, thứ sẽ ảnh hưởng đến phần tử đích sau phần tử Pseudo.

cái này có thể dùng

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

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

như sau: và trước: các phần tử giả không thể truy cập trực tiếp thông qua DOM, hiện tại không thể chỉnh sửa các giá trị cụ thể của css một cách tự do.

Cách của tôi chỉ là một ví dụ và nó không tốt cho thực tiễn, bạn có thể sửa đổi nó thử một số thủ thuật của riêng bạn và làm cho nó chính xác để sử dụng trong thế giới thực.

vì vậy hãy làm thí nghiệm của riêng bạn với cái này và cái khác!

liên quan - Adarsh ​​Hegde.


3

Tôi luôn luôn thêm chức năng utils của riêng mình, trông giống như thế này.

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

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

hoặc sử dụng các tính năng ES6:

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

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

2

Tại sao thêm các lớp hoặc thuộc tính khi bạn chỉ có thể nối thêm stylevào đầu

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

2

Có nhiều câu trả lời ở đây nhưng không có câu trả lời nào giúp thao túng css của :beforehoặc :after, thậm chí không được chấp nhận.

Đây là cách tôi đề xuất để làm điều đó. Giả sử HTML của bạn giống như thế này:

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

Và sau đó, bạn đang thiết lập nó: trước đó trong CSS và thiết kế nó như sau:

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

Xin lưu ý rằng tôi cũng thiết lập contentthuộc tính trong chính phần tử để bạn có thể lấy nó ra một cách dễ dàng sau này. Bây giờ có một buttonnhấp chuột vào đó, bạn muốn thay đổi màu của: trước thành màu xanh lá cây và kích thước phông chữ của nó thành 30px. Bạn có thể đạt được điều đó như sau:

Xác định một css với kiểu yêu cầu của bạn trên một số lớp .activeS:

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

Bây giờ bạn có thể thay đổi: trước kiểu bằng cách thêm lớp vào phần tử: trước như sau:

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

Nếu bạn chỉ muốn lấy nội dung :before, nó có thể được thực hiện như sau:

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

Cuối cùng, nếu bạn muốn thay đổi động :beforenội dung bằng jQuery, Bạn có thể đạt được điều đó như sau:

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

Nhấp vào nút "ChangeB Before" ở trên sẽ thay đổi :beforenội dung #somethingthành '22', đây là một giá trị động.

Tôi hy vọng nó sẽ giúp


1

Tôi đã sử dụng các biến được xác định :rootbên trong CSSđể sửa đổi phần tử giả:after (tương tự áp dụng cho :before) , đặc biệt là để thay đổi giá trị cho một kiểu được xác định bởi và giá trị cho một ( ) khác trong bản demo sau đây tạo ra màu sắc ngẫu nhiên bằng cách sử dụng JavaScript / jQuery:background-coloranchor.sliding-middle-out:hover:aftercontentanchor#reference

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("");
 }
);

Hỗ trợ attr()ngoại trừ trong content, thực sự khan hiếm. Bạn có thể kiểm tra caniuse.com cho nó. :rootvà hỗ trợ biến css là tốt hơn, nhưng vẫn chưa được phổ biến rộng rãi vì hỗ trợ cho nó khá mới. (cũng kiểm tra hỗ trợ cho nó tại caniuse.com)
BananaAcid

1

Tôi đã tạo một plugin jQuery để thêm các quy tắc css-pseudo như sử dụng .css()cho các phần tử cụ thể.

  • mã plugin và trường hợp thử nghiệm ở đây
  • trường hợp sử dụng như cửa sổ bật lên hình ảnh css đơn giản ở đây

sử dụng:

$('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

 $('.span').attr('data-txt', 'foo');
        $('.span').click(function () {
         $(this).attr('data-txt',"any other text");
        })
.span{
}
.span:after{ 
  content: attr(data-txt);
 }
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<div class='span'></div>


0

Bạn có thể sử dụng plugin của tôi cho mục đích này.

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>

Các giá trị phải được chỉ định, như trong hàm thông thường của jQuery.css

Ngoài ra, bạn cũng có thể nhận giá trị của tham số phần tử giả, như trong hàm thông thường của jQuery.css:

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

JS:


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


0

Một số người khác nhận xét về việc gắn thêm phần tử đầu với phần tử kiểu đầy đủ và điều đó không tệ nếu bạn chỉ thực hiện một lần nhưng nếu bạn cần đặt lại nhiều hơn một lần, bạn sẽ kết thúc với rất nhiều yếu tố kiểu. Vì vậy, để ngăn chặn điều đó, tôi đã tạo một phần tử kiểu trống trong đầu bằng một id và thay thế phần bên trong của nó như thế này:

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

Sau đó, JavaScript sẽ trông như thế này:

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

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

setHeight()

Bây giờ trong trường hợp của tôi, tôi cần cái này để đặt chiều cao của phần tử trước dựa trên chiều cao của phần tử khác và nó sẽ thay đổi khi thay đổi kích thước để sử dụng cái này tôi có thể chạy setHeight()mỗi khi cửa sổ được thay đổi kích thước và nó sẽ thay thế <style>đúng.

Hy vọng rằng sẽ giúp một người bị mắc kẹt cố gắng làm điều tương tự.


-1

Tôi có một cái gì đó khác nhau cho bạn đó là dễ dàng và hiệu quả.

    <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');
    });
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.