Nhận / Đặt sâu trong Bản đồ - Thủ thuật CSS

Anonim

Khi làm việc trên các kiến ​​trúc Sass phức tạp, không có gì lạ khi sử dụng bản đồ Sass để duy trì cấu hình và các tùy chọn. Đôi khi, bạn sẽ thấy các bản đồ trong bản đồ (có thể ở một số cấp độ) như bản đồ này từ o-grid:

$o-grid-default-config: ( columns: 12, gutter: 10px, min-width: 240px, max-width: 1330px, layouts: ( S: 370px, // ≥20px columns M: 610px, // ≥40px columns L: 850px, // ≥60px columns XL: 1090px // ≥80px columns ), fluid: true, debug: false, fixed-layout: M, enhanced-experience: true );

Vấn đề với các bản đồ như vậy là không dễ dàng lấy và thiết lập các giá trị từ cây lồng nhau. Đây chắc chắn là thứ bạn muốn ẩn bên trong các hàm để tránh phải thực hiện thủ công mỗi lần.

Nhận sâu

Trên thực tế, việc xây dựng một hàm để tìm nạp các giá trị lồng nhau sâu từ bản đồ là rất dễ dàng.

/// Map deep get /// @author Hugo Giraudel /// @access public /// @param (Map) $map - Map /// @param (Arglist) $keys - Key chain /// @return (*) - Desired value @function map-deep-get($map, $keys… ) ( @each $key in $keys ( $map: map-get($map, $key); ) @return $map; )

Ví dụ: nếu chúng ta muốn nhận giá trị được liên kết với Mbố cục từ bản đồ cấu hình của mình, nó dễ dàng như sau:

$m-breakpoint: map-deep-get($o-grid-default-config, "layouts", "M"); // 610px

Lưu ý rằng dấu ngoặc kép xung quanh chuỗi là tùy chọn. Chúng tôi chỉ thêm chúng cho các mối quan tâm về khả năng đọc.

Tập hợp sâu

Mặt khác, việc xây dựng một chức năng để đặt một khóa lồng nhau sâu có thể rất tẻ nhạt.

/// Deep set function to set a value in nested maps /// @author Hugo Giraudel /// @access public /// @param (Map) $map - Map /// @param (List) $keys - Key chaine /// @param (*) $value - Value to assign /// @return (Map) @function map-deep-set($map, $keys, $value) ( $maps: ($map,); $result: null; // If the last key is a map already // Warn the user we will be overriding it with $value @if type-of(nth($keys, -1)) == "map" ( @warn "The last key you specified is a map; it will be overrided with `#($value)`."; ) // If $keys is a single key // Just merge and return @if length($keys) == 1 ( @return map-merge($map, ($keys: $value)); ) // Loop from the first to the second to last key from $keys // Store the associated map to this key in the $maps list // If the key doesn't exist, throw an error @for $i from 1 through length($keys) - 1 ( $current-key: nth($keys, $i); $current-map: nth($maps, -1); $current-get: map-get($current-map, $current-key); @if $current-get == null ( @error "Key `#($key)` doesn't exist at current level in map."; ) $maps: append($maps, $current-get); ) // Loop from the last map to the first one // Merge it with the previous one @for $i from length($maps) through 1 ( $current-map: nth($maps, $i); $current-key: nth($keys, $i); $current-val: if($i == length($maps), $value, $result); $result: map-merge($current-map, ($current-key: $current-val)); ) // Return result @return $result; )

Bây giờ, nếu chúng ta muốn cập nhật giá trị được liên kết với Mbố cục từ bản đồ cấu hình của mình, chúng ta có thể thực hiện:

$o-grid-default-config: map-deep-set($o-grid-default-config, "layouts" "M", 650px);

Các nguồn bổ sung

Chức năng trên không phải là giải pháp duy nhất cho vấn đề này.

Thư viện Sassy-Maps cũng cung cấp map-deep-setmap-deep-gethoạt động. Cùng với đó, Hugo Giraudel cũng đã viết một extendhàm kiểu jQuery để làm cho map-mergeđệ quy tích hợp sẵn và có thể hợp nhất nhiều hơn 2 bản đồ cùng một lúc.