2013-02-05 21 views
6

Để nhận các hiệu ứng CSS3 (bán kính đường viền, hộp bóng ...) trên IE 6/7/8, tôi đang sử dụng css3pie.css3pie làm hỏng DOM, kết quả trong các lỗi bộ chọn jQuery

Tuy nhiên, css3pie tạo một số thẻ css3-container (v1)/css3pie (v2) trong DOM, điều này làm rối loạn kiến ​​trúc mong đợi. Dưới đây là một ví dụ:

CSS

pre { 
    border: 1px solid #aaa; 
    border-radius: 5px; 
    behavior: url(pie.htc); 
} 

HTML

<div class="foo">bar</div> 
<p class="getme">paragraph</p> 
<pre>preformatted</pre> 

jQuery

// undefined  expected: getme 
alert($("pre").prev().attr("class")); 

// css3-container expected: p 
alert($("pre").prev()[0].tagName); 

// getme   expected: foo 
alert($("pre").prev().prev().attr("class")); 

// 4    expected: 3 
alert($("body").children().size()); 

// will not set  expected: Impact 
$("p+pre").css({fontFamily: "Impact"}); 

// it almost affects all such jQuery selctors 

Các gener thực tế nguồn ated giống như sau:

<DIV class="foo">bar</DIV> 
<P class="paragraph">paragraph</P> 
<css3-container...> 
    <border...> 
     <shape...><stroke></stroke><stroke></stroke></shape> 
    </border> 
</css3-container> 
<PRE>preformatted</PRE> 

Có ai gặp phải loại vấn đề này không? Có cách giải quyết nào không? Có một thay thế cho css3pie để có được CSS3 làm việc trên IE 6/7/8?

+0

Nó không đáng. IE 6 và 7 không được hỗ trợ bởi Microsoft, vậy tại sao bạn muốn hỗ trợ chúng 100%? :) Nhưng nghiêm túc - là các góc tròn quan trọng đối với những người sử dụng trình duyệt mà hầu hết Internet đều có vẻ xấu? Làm cho nó hoạt động với các góc tròn sẽ làm tổn thương hiệu năng và có thể làm cho trang web không thể sử dụng được trong các trình duyệt IE cũ. – naugtur

Trả lời

3

Tôi cũng đã thử sử dụng CSS3PIE và gặp phải các vấn đề tương tự (chủ yếu là với jquery và mediaqueries). Tôi thấy không có giải pháp dễ dàng/thực tế cho tất cả các vấn đề nó gây ra, thực sự.

Lời khuyên của tôi sẽ là sử dụng Modernizr's load để nâng cao dần trải nghiệm người dùng cũ của IE. Nó đòi hỏi một quá trình khó khăn/lâu hơn, như bạn đã thiết lập một polyfill duy nhất cho mỗi và mọi tính năng CSS3. Dưới dạng mario.tco đã thông báo cho bạn, có list of cross-browser polyfills trên repo của Modernizr. Và đây là danh sách các đoạn mã feature detection.

Ngoài ra, hãy xem html5pleasecaniuse.

Đối với IE6 và 7, trừ khi thống kê trang web của bạn cho biết điều gì đó khác biệt, mức sử dụng là below 1% on average (với một số ngoại lệ, hãy kiểm tra ie6countdown), để bạn gần như có thể bỏ qua chúng. Tuy nhiên, với conditional comments bạn có thể nhắm mục tiêu mỗi phiên bản IE < 10 với những hạn chế cụ thể.

Hãy nhớ rằng bạn không thực sự cần phải có bóng đổ hộp và các trang trí trực quan khác (trừ khi chúng cần thiết cho khả năng sử dụng) trên IE < 9. Thật vậy, bất kỳ dự phòng nào cũng có thể gây ra vấn đề hiệu suất lớn (suy nghĩ về phần cứng nào người dùng IE7 có thể có). Websites don't need to look exactly the same in any browser.

+0

Dường như đây là một vấn đề không thể giải quyết miễn là chúng tôi muốn nhìn lạ mắt trên các trình duyệt cũ. Tôi đã thực sự loại bỏ css3pie khỏi dự án của tôi, như @naugtur đã nói ... nó không đáng đâu. ừm ... tôi phải chọn câu trả lời để chấp nhận và thông tin bạn cung cấp có vẻ hữu ích. – user1643156

+0

cảm ơn @ user1643156, chúc bạn may mắn với dự án của mình – Giona

0

Thay vì chỉ sử dụng các nguyên prev() thêm một chọn CSS để nó để thu hẹp tìm kiếm

$("pre").prevUntil('p').attr("class"); 
// OR 
$("pre").prevUntil('.paragraph').attr("class"); 

Nếu bạn đang sử dụng một CSS3 "hack" để làm cho IE 6/7/8 cư xử một cách chính xác không cố gắng và dựa vào cấu trúc DOM dự kiến ​​khi đi bộ DOM cố gắng cụ thể hơn.

EDIT

thay đổi cuộc gọi prev() chức năng để prevUntil()

+0

'prev ('p')' hoặc 'prev ('. Đoạn')' sẽ ** không ** làm việc vì 'tham chiếu jQuery: prev() - Nhận ** ngay lập tức ** trước anh chị em ...' phải là sử dụng 'prevUntil'. Nhưng ... điều gì sẽ xảy ra nếu yếu tố trước không rõ? – user1643156

+0

cảm ơn vì đã chỉ ra điều đó - tôi đã cập nhật câu trả lời của mình - trong trường hợp này tôi nghĩ bạn có thể cần phải phụ thuộc ít hơn vào cấu trúc DOM nếu nó sẽ thay đổi trước khi bạn thực hiện hành động đó. –

2

CSS3PIE là một cách rất hữu ích và mạnh mẽ để mô phỏng CSS3 góc tròn - và trong công ty của tôi nó là một trong đó chúng tôi đã chọn, nhưng có có nhiều cách khác để làm điều đó.

Cách CSS3PIE tạo các góc được làm tròn, nó sẽ tạo thẻ <css3-container> làm anh chị em trước đó cho phần tử có thuộc tính hành vi, vì vậy nó sẽ thay đổi cấu trúc DOM và ngắt cuộc gọi prev() của bạn. Vùng chứa css rất quan trọng vì nó là bản vẽ VML của nền góc tròn phía sau thẻ <pre> của bạn.

Một cách để bạn có thể làm điều này sẽ được quấn thẻ <pre> của bạn trong cái gì khác giống như một <div> và sau đó sử dụng <div> để điều hướng các DOM bằng cách sử dụng chức năng prev().

Một cách khác bạn có thể làm được điều này sẽ tạo ra một plugin jQuery như thế này

/* This adds a plugin prevPie and nextPie - it is the same as the 
    existing prev and next, but it will ignore css3-containers. */ 
(function($){ 
    function addPlugin(name) { 
     $.fn[name + 'Pie'] = function() { 
      var result = []; 
      this[name]().each(function(i,el){ 
       if (el.tagName == 'css3-container') { 
        var val = $(el)[name]()[0]; 
        val && result.push(val); 
       } else { 
        result.push(el); 
       } 
      }); 
      return $(result); 
     } 
    } 
    addPlugin('prev'); 
    addPlugin('next'); 
})(jQuery); 

Bây giờ sau nên làm việc như bạn muốn nó trong tất cả các trình duyệt.

// undefined  expected: getme 
alert($("pre").prevPie().attr("class")); 
// css3-container expected: p 
alert($("pre").prevPie()[0].tagName); 

// getme   expected: foo 
alert($("pre").prevPie().prevPie().attr("class")); 
// P    expected: div 
alert($("pre").prevPie().prevPie()[0].tagName)); 
+0

Plugin của bạn thực hiện công việc để giải quyết vấn đề 'prev' cụ thể này. Nhưng vẫn còn rất nhiều vấn đề với css3pie, nó ảnh hưởng đến hầu hết các bộ chọn jQuery ... ví dụ: '$ (" body "). children(). size()' sẽ trả về 4 thay vì 3 trong ví dụ của tôi. Viết một plugin để sửa tất cả các lỗi này dường như không phải là một giải pháp hoàn hảo. – user1643156

+0

Có, nói chung tôi đã học được nó không phải là một ý tưởng tốt để sử dụng các loại selectors khi sử dụng css3pie. Khi kiểm tra mã của bạn chỉ cần chắc chắn rằng bạn kiểm tra trình duyệt IE mọi lúc vì những vấn đề này. Một điều bạn có thể muốn làm là cung cấp tên lớp trên hầu hết các phần tử mà bạn cần tìm hoặc đếm và sử dụng các tên lớp này trong bộ chọn của bạn để nó luôn hoạt động bất kể các phần tử css3-container bổ sung này. – codefactor

+0

Cảm ơn bạn đã trả lời, codefactor. Nhưng vấn đề là đôi khi chúng ta không biết id/class, yếu tố prev có thể hoàn toàn không rõ.Đối với góc tròn và bóng tối, tôi có thể làm thêm một số công việc để viết một plugin bằng cách sử dụng hình ảnh cho IE 6/7/8, nhưng nó thực sự không phải là tuyệt vọng. Vì vậy, cho đến khi ai đó đến với một giải pháp hoàn hảo, tôi đoán tôi sẽ phải thả css3pie từ ứng dụng của tôi. – user1643156

1

Đây có lẽ không phải là câu trả lời bạn đang tìm kiếm, mà thay vì cố gắng để jQuery bỏ qua các phần tử được tiêm của PIE, tôi khuyên bạn nên viết lại jQuery của bạn để sử dụng lớp/ID nhiều hơn và ít phụ thuộc hơn trên cấu trúc trang.Điều này có lợi ích là làm cho mã của bạn linh hoạt hơn so với các thay đổi cấu trúc trang khác, cũng như làm cho mã của bạn dễ dàng hơn và có thể tái sử dụng được.

Khi bạn phải đi qua DOM, hầu hết (nếu không muốn nói là tất cả) jQuery's traversal methods bao gồm một luận cứ lọc chọn mà bạn có thể sử dụng để loại trừ các yếu tố PIE của, ví dụ:

$("pre").prevUntil('*', 'not(css3-container)') 

$("body").children('not(css3-container)') 
Các vấn đề liên quan