簡體   English   中英

jQuery CSS 將元素的計算樣式返回到偽克隆該元素的插件?

[英]jQuery CSS plugin that returns computed style of element to pseudo clone that element?

我正在尋找一種使用 jQuery 返回第一個匹配元素的計算 styles 的 object 的方法。 然后我可以將這個 object 傳遞給 jQuery 的 css 方法的另一個調用。

例如,對於width ,我可以執行以下操作以使 2 個 div 具有相同的寬度:

$('#div2').width($('#div1').width());

如果我能讓文本輸入看起來像現有的 span 就好了

$('#input1').css($('#span1').css());

where.css() 沒有參數返回一個 object 可以傳遞給.css(obj)

(我找不到 jQuery 插件,但它似乎應該存在。如果它不存在,我將在下面將我的變成一個插件,並將它與我使用的所有屬性一起發布。)

基本上,我想偽克隆某些元素但使用不同的標簽 例如,我有一個 li 元素,我想隱藏它並在它上面放置一個看起來相同的 input 元素。 當用戶輸入時,看起來他們正在編輯內聯元素

對於這個用於編輯的偽克隆問題,我也願意接受其他方法。 有什么建議么?

這是我目前擁有的。 唯一的問題是獲取所有可能的 styles。這可能是一個長得離譜的列表。


jQuery.fn.css2 = jQuery.fn.css;
jQuery.fn.css = function() {
    if (arguments.length) return jQuery.fn.css2.apply(this, arguments);
    var attr = ['font-family','font-size','font-weight','font-style','color',
    'text-transform','text-decoration','letter-spacing','word-spacing',
    'line-height','text-align','vertical-align','direction','background-color',
    'background-image','background-repeat','background-position',
    'background-attachment','opacity','width','height','top','right','bottom',
    'left','margin-top','margin-right','margin-bottom','margin-left',
    'padding-top','padding-right','padding-bottom','padding-left',
    'border-top-width','border-right-width','border-bottom-width',
    'border-left-width','border-top-color','border-right-color',
    'border-bottom-color','border-left-color','border-top-style',
    'border-right-style','border-bottom-style','border-left-style','position',
    'display','visibility','z-index','overflow-x','overflow-y','white-space',
    'clip','float','clear','cursor','list-style-image','list-style-position',
    'list-style-type','marker-offset'];
    var len = attr.length, obj = {};
    for (var i = 0; i < len; i++) 
        obj[attr[i]] = jQuery.fn.css2.call(this, attr[i]);
    return obj;
}

編輯:我現在已經使用上面的代碼一段時間了。 它運行良好,行為與原始 css 方法完全一樣,但有一個例外:如果傳遞 0 個參數,它返回計算樣式 object。

如您所見,如果適用,它會立即調用原始的 css 方法。 否則,它會獲得所有列出的屬性的計算值 styles(從 Firebug 的計算樣式列表中收集)。 雖然它得到了一長串值,但速度相當快。 希望它對其他人有用。

晚了兩年,但我有你要找的解決方案。 這是我寫的一個插件(通過將另一個人的 function 包裝成插件格式),它完全符合你的要求,但在所有瀏覽器中獲得所有可能的 styles,甚至是 IE。

jquery.getStyleObject.js:

/*
 * getStyleObject Plugin for jQuery JavaScript Library
 * From: http://upshots.org/?p=112
 *
 * Copyright: Unknown, see source link
 * Plugin version by Dakota Schneider (http://hackthetruth.org)
 */

(function($){
    $.fn.getStyleObject = function(){
        var dom = this.get(0);
        var style;
        var returns = {};
        if(window.getComputedStyle){
            var camelize = function(a,b){
                return b.toUpperCase();
            }
            style = window.getComputedStyle(dom, null);
            for(var i=0;i<style.length;i++){
                var prop = style[i];
                var camel = prop.replace(/\-([a-z])/g, camelize);
                var val = style.getPropertyValue(prop);
                returns[camel] = val;
            }
            return returns;
        }
        if(dom.currentStyle){
            style = dom.currentStyle;
            for(var prop in style){
                returns[prop] = style[prop];
            }
            return returns;
        }
        return this.css();
    }
})(jQuery);

基本用法非常簡單:

var style = $("#original").getStyleObject(); // copy all computed CSS properties
$("#original").clone() // clone the object
    .parent() // select it's parent
    .appendTo() // append the cloned object to the parent, after the original
                // (though this could really be anywhere and ought to be somewhere
                // else to show that the styles aren't just inherited again
    .css(style); // apply cloned styles

它不是 jQuery,但在 Firefox、Opera 和 Safari 中,您可以使用window.getComputedStyle(element)獲取元素的計算 styles,在 IE<=8 中,您可以使用element.currentStyle 返回的對象在每種情況下都不同,我不確定使用元素和使用 Javascript 創建的 styles 的效果如何,但也許它們會有用。

在 Safari 中,您可以執行以下操作:

document.getElementById('b').style.cssText = window.getComputedStyle(document.getElementById('a')).cssText;

我不知道您是否對到目前為止得到的答案感到滿意,但我不滿意,我的答案可能也不會讓您滿意,但它可能會幫助其他人。

在思考如何將元素的 styles 從一個“克隆”或“復制”到另一個之后,我開始意識到循環 n 並應用於 n2 的方法並不是非常理想,但我們有點堅持這個.

當您發現自己面臨這些問題時,您很少需要將所有 styles 從一個元素復制到另一個元素......您通常有特定的理由想要應用“一些”styles。

這是我恢復的內容:

$.fn.copyCSS = function( style, toNode ){
  var self = $(this);
  if( !$.isArray( style ) ) style=style.split(' ');
  $.each( style, function( i, name ){ toNode.css( name, self.css(name) ) } );
  return self;
}

您可以將以空格分隔的 css 屬性列表作為第一個參數傳遞給它,將要將它們克隆到的節點作為第二個參數傳遞給它,如下所示:

$('div#copyFrom').copyCSS('width height color',$('div#copyTo'));

之后無論其他什么似乎“錯位”,我都會嘗試使用樣式表進行修復,以免讓我的 Js 因太多錯誤的想法而變得混亂。

我喜歡你的回答 Quickredfox。 我需要復制一些 CSS 但不是立即復制所以我修改它使“toNode”可選。

$.fn.copyCSS = function( style, toNode ){
  var self = $(this),
   styleObj = {},
   has_toNode = typeof toNode != 'undefined' ? true: false;
 if( !$.isArray( style ) ) {
  style=style.split(' ');
 }
  $.each( style, function( i, name ){ 
  if(has_toNode) {
   toNode.css( name, self.css(name) );
  } else {
   styleObj[name] = self.css(name);
  }  
 });
  return ( has_toNode ? self : styleObj );
}

如果你這樣稱呼它:

$('div#copyFrom').copyCSS('width height color');

然后它將返回一個 object 和你的 CSS 聲明供你稍后使用:

{
 'width': '140px',
 'height': '860px',
 'color': 'rgb(238, 238, 238)'
}

感謝您的起點。

現在我已經有時間研究這個問題並更好地理解 jQuery 的內部 css 方法是如何工作的,我發布的內容對於我提到的用例來說似乎工作得很好。

有人建議您可以使用 CSS 解決此問題,但我認為這是一個更通用的解決方案,在任何情況下都可以使用,而無需添加刪除類或更新您的 css。

我希望其他人覺得它有用。 如果您發現錯誤,請告訴我。

多用途.css()

用法

$('body').css();        // -> { ... } - returns all styles
$('body').css('*');     // -> { ... } - the same (more verbose)
$('body').css('color width height')  // -> { color: .., width: .., height: .. } - returns requested styles
$('div').css('width height', '100%')  // set width and color to 100%, returns self
$('body').css('color')  // -> '#000' - native behaviour

代碼

(function($) {

    // Monkey-patching original .css() method
    var nativeCss = $.fn.css;

    var camelCase = $.camelCase || function(str) {
        return str.replace(/\-([a-z])/g, function($0, $1) { return $1.toUpperCase(); });
    };

    $.fn.css = function(name, value) {
        if (name == null || name === '*') {
            var elem = this.get(0), css, returns = {};
            if (window.getComputedStyle) {
                css = window.getComputedStyle(elem, null);
                for (var i = 0, l = css.length; i < l; i++) {
                    returns[camelCase(css[i])] = css.getPropertyValue(css[i]);
                }
                return returns;
            } else if (elem.currentStyle) {
                css = elem.currentStyle;
                for (var prop in css) {
                    returns[prop] = css[prop];
                }
            }
            return returns;
        } else if (~name.indexOf(' ')) {
            var names = name.split(/ +/);
            var css = {};
            for (var i = 0, l = names.length; i < l; i++) {
                css[names[i]] = nativeCss.call(this, names[i], value);
            }
            return arguments.length > 1 ? this : css;
        } else {
            return nativeCss.apply(this, arguments);
        }
    }

})(jQuery);

主要思想取自DakotaHexInteractive 的回答。

我只是想對 Dakota 提交的代碼添加一個擴展。

如果你想克隆一個應用了所有 styles 和所有子元素的元素,那么你可以使用以下代碼:

/*
 * getStyleObject Plugin for jQuery JavaScript Library
 * From: http://upshots.org/?p=112
 *
 * Copyright: Unknown, see source link
 * Plugin version by Dakota Schneider (http://hackthetruth.org)
 */

(function($){
    $.fn.getStyleObject = function(){
        var dom = this.get(0);
        var style;
        var returns = {};
        if(window.getComputedStyle){
            var camelize = function(a,b){
                return b.toUpperCase();
            }
            style = window.getComputedStyle(dom, null);
            for(var i=0;i<style.length;i++){
                var prop = style[i];
                var camel = prop.replace(/\-([a-z])/g, camelize);
                var val = style.getPropertyValue(prop);
                returns[camel] = val;
            }
            return returns;
        }
        if(dom.currentStyle){
            style = dom.currentStyle;
            for(var prop in style){
                returns[prop] = style[prop];
            }
            return returns;
        }
        return this.css();
    }


    $.fn.cloneWithCSS = function() {
        var styles = {};

        var $this = $(this);
        var $clone = $this.clone();

        $clone.css( $this.getStyleObject() );

        var children = $this.children().toArray();
        var i = 0;
        while( children.length ) {
            var $child = $( children.pop() );
            styles[i++] = $child.getStyleObject();
            $child.children().each(function(i, el) {
                children.push(el);
            })
        }

        var cloneChildren = $clone.children().toArray()
        var i = 0;
        while( cloneChildren.length ) {
            var $child = $( cloneChildren.pop() );
            $child.css( styles[i++] );
            $child.children().each(function(i, el) {
                cloneChildren.push(el);
            })
        }

        return $clone
    }

})(jQuery);

然后你可以這樣做: $clone = $("#target").cloneWithCSS()

偉大的 function 由 OP 提供。 我稍微修改了它,以便您可以選擇要返回的值。

(function ($) {
    var jQuery_css = $.fn.css,
        gAttr = ['font-family','font-size','font-weight','font-style','color','text-transform','text-decoration','letter-spacing','word-spacing','line-height','text-align','vertical-align','direction','background-color','background-image','background-repeat','background-position','background-attachment','opacity','width','height','top','right','bottom','left','margin-top','margin-right','margin-bottom','margin-left','padding-top','padding-right','padding-bottom','padding-left','border-top-width','border-right-width','border-bottom-width','border-left-width','border-top-color','border-right-color','border-bottom-color','border-left-color','border-top-style','border-right-style','border-bottom-style','border-left-style','position','display','visibility','z-index','overflow-x','overflow-y','white-space','clip','float','clear','cursor','list-style-image','list-style-position','list-style-type','marker-offset'];
    $.fn.css = function() {
        if (arguments.length && !$.isArray(arguments[0])) return jQuery_css.apply(this, arguments);
        var attr = arguments[0] || gAttr,
            len = attr.length,
            obj = {};
        for (var i = 0; i < len; i++) obj[attr[i]] = jQuery_css.call(this, attr[i]);
        return obj;
    }
})(jQuery);

通過指定您自己的數組來選擇您想要的值: $().css(['width','height']);

$.fn.cssCopy=function(element,styles){
var self=$(this);
if(element instanceof $){
    if(styles instanceof Array){
        $.each(styles,function(val){
            self.css(val,element.css(val));
        });
    }else if(typeof styles===”string”){
        self.css(styles,element.css(styles));
    }
}
return this;
};

使用示例

$("#element").cssCopy($("#element2"),['width','height','border'])

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM