Подтвердить что ты не робот

JQuery CSS-плагин, который возвращает вычисленный стиль элемента для псевдо-клонирования этого элемента?

Я ищу способ использования jQuery для возврата объекта вычисленных стилей для 1-го согласованного элемента. Затем я мог передать этот объект другому вызову метода jQuery css.

Например, с width я могу сделать следующее, чтобы сделать 2 divs одинаковой ширины:

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

Было бы неплохо, если бы я мог сделать ввод текста похожим на существующий диапазон:

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

где .css() без аргумента возвращает объект, который может быть передан . css (obj).

(Я не могу найти плагин jQuery для этого, но похоже, что он должен существовать. Если он не существует, я превращу свой ниже в плагин и разместил его со всеми свойствами, которые я использую. )

В принципе, я хочу псевдо-клонировать определенные элементы , но использовать другой тег. Например, у меня есть элемент li, который я хочу скрыть и поместить на него элемент ввода, который выглядит одинаково. Когда пользователь набирает, , похоже, что они редактируют элемент inline.

Я также открыт для других подходов к этой проблеме псевдо-клонирования для редактирования. Любые предложения?

Вот что я сейчас имею. Единственная проблема - просто получить все возможные стили. Это может быть смехотворно длинный список.


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 аргументов переданы, он возвращает объект с вычисленным стилем.

Как вы можете видеть, он немедленно вызывает исходный метод css, если это применимо. В противном случае он получает вычисленные стили всех перечисленных свойств (собранных из списка расклассифицированных стилей Firebug). Хотя он получает длинный список ценностей, он довольно быстро. Надеюсь, это полезно для других.

4b9b3361

Ответ 1

Два года спустя, но у меня есть решение, которое вы ищете. Здесь плагин, который я написал (путем обертывания другой функции парня в формате плагина), который делает именно то, что вы хотите, но получает все возможные стили во всех браузерах, даже 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 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

Надеюсь, что это поможет.

Ответ 2

Это не jQuery, но в Firefox, Opera и Safari вы можете использовать window.getComputedStyle(element) для получения вычисленных стилей для элемента, а в IE <= 8 вы можете использовать element.currentStyle. Возвращаемые объекты в каждом случае разные, и я не уверен, насколько хорошо либо работать с элементами и стилями, созданными с помощью Javascript, но, возможно, они будут полезны.

В Safari вы можете сделать следующее, которое является аккуратным:

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

Ответ 3

Я не знаю, довольны ли вы ответами, которые вы получили до сих пор, но я не был и мой, возможно, не понравился вам, но это может помочь кому-то другому.

Подумав о том, как стили "клонировать" или "копировать" элементы из одного в другой, я понял, что он не очень оптимален для подхода к циклу через n и применяется к n2, но мы сортируем застрял с этим.

Когда вы сталкиваетесь с этими проблемами, вам редко приходится копировать ВСЕ стили из одного элемента в другой... у вас обычно есть определенная причина, чтобы требовать применения "некоторых" стилей.

Здесь я вернул:

$.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, разделенных пробелами, в качестве первого аргумента и node, который вы хотите клонировать в качестве второго аргумента, например:

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

В любом случае, что-то вроде бы "смещается" после этого, я попытаюсь исправить с помощью таблиц стилей, чтобы не загромождать мои Js слишком много пропущенных идей.

Ответ 4

Теперь, когда у меня было время, чтобы изучить проблему и лучше понять, как работает метод jQuery internal css, то, что я опубликовал, кажется, работает достаточно хорошо для используемого случая, о котором я упоминал.

Было предложено решить эту проблему с помощью CSS, но я думаю, что это более обобщенное решение, которое будет работать в любом случае без необходимости добавления классов удаления или обновления вашего css.

Я надеюсь, что другие считают это полезным. Если вы обнаружили ошибку, сообщите мне.

Ответ 5

Мне нравится ваш ответ 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');

Затем он вернет объект с вашими объявлениями CSS, которые вы сможете использовать позже:

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

Спасибо за отправную точку.

Ответ 6

Многоцелевой .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);

Основная идея взята из ответов Dakota's и HexInteractive.

Ответ 7

Большая функция, предоставляемая 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']);

Ответ 8

Я просто хотел добавить расширение к коду, представленному Dakota.

Если вы хотите клонировать элемент со всеми применяемыми к нему стилями и всеми дочерними элементами, вы можете использовать следующий код:

/*
 * 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() {
        styles = {};

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

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

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

        return $clone
    }

})(jQuery);

Тогда вы можете просто сделать: $clone = $("#target").cloneWithCSS()

Ответ 9

$.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'])