javascript - tiene - jQuery CSS plugin que devuelve el estilo calculado del elemento para pseudo clonar ese elemento?
saber si un elemento tiene un atributo jquery (9)
Multiusos .css()
Uso
$(''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
Código
(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);
La idea principal está tomada de HexInteractive''s respuestas de Dakota''s & HexInteractive''s .
Estoy buscando una forma de usar jQuery para devolver un objeto de estilos calculados para el primer elemento coincidente. Podría pasar este objeto a otra llamada del método css de jQuery.
Por ejemplo, con width , puedo hacer lo siguiente para hacer que los 2 div tengan el mismo ancho:
$(''#div2'').width($(''#div1'').width());
Sería bueno si pudiera hacer que una entrada de texto se viera como un lapso existente :
$(''#input1'').css($(''#span1'').css());
donde .css () sin argumento devuelve un objeto que se puede pasar a .css(obj) .
(No puedo encontrar un complemento de jQuery para esto, pero parece que debería existir. Si no existe, convertiré el mío a continuación en un complemento y lo publicaré con todas las propiedades que uso).
Básicamente, quiero pseudo clonar ciertos elementos pero usar una etiqueta diferente . Por ejemplo, tengo un elemento li que quiero ocultar y coloco un elemento de entrada sobre él que se ve igual. Cuando el usuario escribe, parece que está editando el elemento en línea .
También estoy abierto a otros enfoques para este problema de pseudo clonación para la edición. ¿Alguna sugerencia?
Esto es lo que tengo actualmente. El único problema es simplemente obtener todos los estilos posibles. Esta podría ser una lista ridículamente larga.
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;
}
Editar: He estado usando el código anterior por un tiempo. Funciona bien y se comporta exactamente como el método css original con una excepción: si se pasan 0 args, devuelve el objeto de estilo calculado.
Como puede ver, inmediatamente llama al método css original si ese es el caso que se aplica. De lo contrario, obtiene los estilos calculados de todas las propiedades enumeradas (recopiladas de la lista de estilos computados de Firebug). Aunque está obteniendo una larga lista de valores, es bastante rápido. Espero que sea útil para otros.
Ahora que he tenido algo de tiempo para analizar el problema y comprender mejor cómo funciona el método css interno de jQuery, lo que he publicado parece funcionar bastante bien para el caso de uso que mencioné.
Se ha propuesto que puedas resolver este problema con CSS, pero creo que esta es una solución más general que funcionará en cualquier caso sin tener que agregar un eliminar clases o actualizar tu CSS.
Espero que otros lo encuentren útil. Si encuentras un error, házmelo saber.
Dos años tarde, pero tengo la solución que estás buscando. Aquí hay un complemento que escribí (envolviendo la función de otro tipo en formato de complemento) que hace exactamente lo que quiere, pero obtiene todos los estilos posibles en todos los navegadores, incluso en 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);
El uso básico es bastante simple:
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
Espero que ayude.
Gran función proporcionada por el OP. Lo modifiqué ligeramente para que pueda elegir qué valores desea devolver.
(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);
Elija qué valores desea especificando su propia matriz: $().css([''width'',''height'']);
Me gusta tu respuesta Quickredfox. Necesitaba copiar algo de CSS pero no de forma inmediata, así que lo modifiqué para que el "toNode" fuera opcional.
$.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 );
}
Si lo llamas así:
$(''div#copyFrom'').copyCSS(''width height color'');
Luego, devolverá un objeto con sus declaraciones CSS para que lo use más adelante:
{
''width'': ''140px'',
''height'': ''860px'',
''color'': ''rgb(238, 238, 238)''
}
Gracias por el punto de partida.
No es jQuery, pero en Firefox, Opera y Safari puedes usar window.getComputedStyle(element)
para obtener los estilos calculados para un elemento y en IE <= 8 puedes usar element.currentStyle
. Los objetos devueltos son diferentes en cada caso, y no estoy seguro de qué tan bien funcionan con los elementos y estilos creados con Javascript, pero quizás sean útiles.
En Safari puedes hacer lo siguiente, que es bastante ordenado:
document.getElementById(''b'').style.cssText = window.getComputedStyle(document.getElementById(''a'')).cssText;
No sé si estás contento con las respuestas que has obtenido hasta ahora, pero yo no estaba y el mío tampoco te puede agradar, pero puede ayudar a alguien más.
Después de reflexionar sobre cómo "clonar" o "copiar" los estilos de los elementos de uno a otro, me he dado cuenta de que no era muy óptimo un enfoque para recorrer n y aplicarlo a n2, sin embargo, estamos muy atascados con esto. .
Cuando te encuentras frente a estos problemas, casi nunca necesitas copiar TODOS los estilos de un elemento a otro ... por lo general, tienes una razón específica para querer aplicar "algunos" estilos.
Aquí es a lo que volví:
$.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;
}
Puede pasarle una lista de atributos css separados por espacios como el primer argumento y el nodo al que desea clonar como el segundo argumento, así:
$(''div#copyFrom'').copyCSS(''width height color'',$(''div#copyTo''));
Cualquier otra cosa que parezca "desalinearse" después de eso, intentaré corregir con hojas de estilo para no saturar mi J con demasiadas ideas erróneas.
Solo quería agregar una extensión al código enviado por Dakota.
Si desea clonar un elemento con todos los estilos aplicados y todos los elementos secundarios, puede usar el siguiente código:
/*
* 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);
Entonces puede hacer: $clone = $("#target").cloneWithCSS()
$.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;
};
Use el ejemplo
$("#element").cssCopy($("#element2"),[''width'',''height'',''border''])