如何从一个元素移动所有计算的CSS样式并使用JavaScript将它们应用于不同的元素?

时间:2022-11-12 11:34:35

I have an external stylesheet that is applying some styles to a given element. I want to be able to move those styles (using JavaScript) to a different element entirely, without having prior knowledge of the styles that are being applied.

我有一个外部样式表,它将一些样式应用于给定元素。我希望能够将这些样式(使用JavaScript)完全移动到不同的元素,而无需事先了解正在应用的样式。

The CSS:

CSS:

td { padding: 5px }
div { }

The HTML:

HTML:

<td>
    <div>
        Apply the TD styles to this DIV (instead of the TD).
    </div>
</td>

The JavaScript:

JavaScript:

$(document).ready(function(){
    $('tr').children('td').each(function(){
        //move the td styles to div
    });
});

How can I achieve this?

我怎样才能做到这一点?

Update: To be clear, I have no control over the CSS. I have no way of knowing what styles may be applied. The problem that I'm trying to solve is being able to take an element and copy its styles (which may be unknown) and apply them to a different element.

更新:要明确,我无法控制CSS。我无法知道可以应用哪些样式。我试图解决的问题是能够获取元素并复制其样式(可能是未知的)并将它们应用于不同的元素。

9 个解决方案

#1


8  

This is a solution I figured out, it mixes document.defaultView.getComputedStyle and jQuery's .css():

这是我想出的解决方案,它混合了document.defaultView.getComputedStyle和jQuery的.css():

<!-- index.html -->
<!DOCTYPE html>
<html>
<head>
    <script src="//ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js" >            </script>
    <link href="style.css" type="text/css" rel="stylesheet" />
</head>
<body>
    <div id="test" style="background-color: #FF7300">
        <p>Hi</p>
    </div>
    <a href="#" id="button">Apply styles</a>
    <script>
        $("#button").click(function() {
            var element = document.getElementById("test");
             $("#victim").css(document.defaultView.getComputedStyle(element, null));
        });
    </script>
    <div id="victim">
        <p>Hi again</p>
    </div>
</body>

//style.css 
#test {
    border: 3px solid #000000;
}

What this does is copy the computed style object, including the style.css and the inline style, and set it to the other div using jQuery's .css()

这样做是复制计算出的样式对象,包括style.css和内联样式,并使用jQuery的.css()将其设置为另一个div。

I hope I didn't misunderstand the question and that this is what you need.

我希望我没有误解这个问题,而这正是你所需要的。

Edit: Something I forgot is that you asked to 'move' the style rather than copy it. It's very simple to remove styles from the previous div using jQuery's .removeClass() and using .attr() to remove the style attribute, but you have to keep in mind that if there are any style rules being applied to the element's ID, there's no way to keep them from being applied.

编辑:我忘了的是你要求'移动'风格而不是复制它。使用jQuery的.removeClass()并使用.attr()删除样式属性来删除前一个div中的样式非常简单,但是你必须记住,如果有任何样式规则应用于元素的ID,那么无法阻止它们被应用。

#2


2  

EDIT: This answer was written before the question was clarified.

编辑:这个答案是在问题澄清之前写的。

Give your elements IDs, like this:

提供您的元素ID,如下所示:

<td id="td_element" style="padding:5px">
    <div id="div_element">
        Apply the TD styles to this DIV (instead of the TD).
    </div>
</td>

And use

并使用

var td_element = $('#td_element')
$('#div_element').attr('style', td_element.attr('style'));
td_element.removeAttr('style');

Of course you could use a class instead - or you may have the elements from previous javascript code. You'll need to decide the best way to reference the elements yourself.

当然你可以使用一个类 - 或者你可以使用以前的javascript代码中的元素。您需要自己决定引用元素的最佳方法。

#3


2  

I know this will look rough but it works. Initially copying all the computed styles from <td> and applying them to <div> is easy with this plugin from Mike Dunn. The troublesome bit is in removing the styles from the <td> after they have been copied. From what I can tell, the only thing you can do is manually reset them to default with .css().

我知道这看起来很粗糙但是有效。最初使用Mike Dunn的插件轻松地从复制所有计算出的样式并将它们应用到

。麻烦的一点就是在复制后从中删除样式。据我所知,你唯一能做的就是用.css()手动将它们重置为默认值。

Working Example

工作实例

$.fn.copyCSS = function (source) {
    var dom = $(source).get(0);
    var dest = {};
    var style, prop;
    if (window.getComputedStyle) {
        var camelize = function (a, b) {
                return b.toUpperCase();
        };
        if (style = window.getComputedStyle(dom, null)) {
            var camel, val;
            if (style.length) {
                for (var i = 0, l = style.length; i < l; i++) {
                    prop = style[i];
                    camel = prop.replace(/\-([a-z])/, camelize);
                    val = style.getPropertyValue(prop);
                    dest[camel] = val;
                }
            } else {
                for (prop in style) {
                    camel = prop.replace(/\-([a-z])/, camelize);
                    val = style.getPropertyValue(prop) || style[prop];
                    dest[camel] = val;
                }
            }
            return this.css(dest);
        }
    }
    if (style = dom.currentStyle) {
        for (prop in style) {
            dest[prop] = style[prop];
        }
        return this.css(dest);
    }
    if (style = dom.style) {
        for (prop in style) {
            if (typeof style[prop] != 'function') {
                dest[prop] = style[prop];
            }
        }
    }
    return this.css(dest);
};

$('td').click(function () {
    $('div').copyCSS('td');

    $('td').removeAttr('style');

    $("td").css({
        'font-family': 'none',
            'font-size': 'none',
            'font-weight': 'none',
            'font-style': 'none',
            'color': '#000',
            'text-transform': 'none',
            'text-decoration': 'none',
            'letter-spacing': 'none',
            'word-spacing': 'none',
            'line-height': 'none',
            'text-align': 'none',
            'vertical-align': 'none',
            'direction': 'none',
            'background-color': 'transparent',
            'background-image': 'none',
            'background-repeat': 'none',
            'background-position': 'none',
            'background-attachment': 'none',
            'opacity': '1',
            'width': 'none',
            'height': 'none',
            'top': '',
            'right': '',
            'bottom': '',
            'left': '',
            'margin-top': '0',
            'margin-right': '0',
            'margin-bottom': '0',
            'margin-left': '0',
            'padding-top': '0',
            'padding-right': '0',
            'padding-bottom': '0',
            'padding-left': '0',
            'border-top-width': '0',
            'border-right-width': '0',
            'border-bottom-width': '0',
            'border-left-width': '0',
            'border-top-color': '0',
            'border-right-color': '0',
            'border-bottom-color': '0',
            'border-left-color': '0',
            'border-top-style': '0',
            'border-right-style': '0',
            'border-bottom-style': '0',
            'border-left-style': '0',
            'position': 'static',
            'display': '',
            'visibility': 'visible',
            'z-index': 'auto',
            'overflow-x': 'auto',
            'overflow-y': 'auto',
            'white-space': 'normal',
            'clip': 'auto',
            'float': 'none',
            'clear': 'none',
            'cursor': 'default',
            'list-style-image': 'none',
            'list-style-position': '0',
            'list-style-type': 'disc',
            'marker-offset': '',
            'padding': '0',
            'transition': 'none',
            'border-radius': 'none'
    });
});

Note: obviously I have not included a reset for all possible styles.

注意:显然我没有为所有可能的样式包含重置。

#4


1  

EDIT: Code corrected

编辑:代码已更正

$('div').attr('style', $('td').attr('style'));

If you want to move just add this line afterwards

如果你想移动,只需在之后添加此行

$('td').attr('style', '');

I realize that this looks contrived but I have no other selectors to work with here. Normally you'd want to do this with an id or a class instead of the actual attribute.

我意识到这看起来很做人,但我没有其他选择器可以在这里工作。通常,您希望使用id或类而不是实际属性来执行此操作。

#5


1  

Don't move the styles is my short answer - find another way. Can you load another stylesheet after the stylesheet being loaded? If so, add a stylesheet that overrides the td and div padding defined in the stylesheet you're having to reference.

不要移动样式是我的简答 - 找到另一种方式。加载样式表后可以加载另一个样式表吗?如果是这样,添加一个样式表,覆盖您必须引用的样式表中定义的td和div填充。

#6


0  

What about applying the actual TD style to a class? Then just modify the class of the TD and the DIVs. Or you dont have access to the stylesheet?

将实际的TD风格应用于课程怎么样?然后只需修改TD和DIV的类。或者你没有访问样式表?

The CSS:

CSS:

.class_name { padding: 5px }

The HTML:

HTML:

<td class="class_name">
    <div>
        Apply the TD styles to this DIV (instead of the TD).
    </div>
</td>

The JavaScript:

JavaScript:

$(document).ready(function(){
    $('.class_name').removeClass('class_name').children('div').addClass('class_name');
});

#7


0  

You can try the following steps to copy the styles defined for particular element in stylesheets and <style> tags ( code is little bit lengthy ):

您可以尝试以下步骤来复制样式表和

  1. Get the contents of original stylesheets using ajax. and contents of each <style> tags
  2. 使用ajax获取原始样式表的内容。和每个
  3. Parse the css contents into array
  4. 将css内容解析为数组
  5. For each selectors in the parsed stylesheet, compare it's dom element with target dom element ( from which you are copying the styles ). if any of them matches , then apply styles corresponding to mathced selector to the required element
  6. 对于已解析样式表中的每个选择器,将其dom元素与目标dom元素(从中复制样式)进行比较。如果它们中的任何一个匹配,则将与数学选择器对应的样式应用于所需元素

Here is the code:

这是代码:

<html>
    <head>
        <script src="http://ajax.googleapis.com/ajax/libs/jquery/1.10.1/jquery.min.js"></script>
        <style>
        #source { width: 100px; height: 100px; background-color: black; }
        </style>
        <link rel="stylesheet" href="style.css">
    </head>
    <body>
       <table>
            <tr>
                <td id="source"></td>
            </tr>
       </table>
       <div id="target"></div>
    </body>

    <script>
    var source = $('#source'); // source
    var target = $( '#target' ); // target

    $( 'link[rel="stylesheet"]' ).each( function() {
          $.get( $(this).attr( 'href' ), {}, function( data ) {
                 var css_obj = parse_css( data );
                 copy_css( css_obj, source, target );
          });
    });

    $( 'style' ).each( function() {
        var css = $(this).text();
        var css_obj = parse_css( css );
        copy_css( css_obj, source, target );
    })

    function copy_css( css_obj, source, target ) {
        for( selector in css_obj ) {
            if( $(selector)[0] === source[0] ) { // compare raw dom elements 
                for( prop in css_obj[selector] ) {
                    target.css( prop, css_obj[selector][prop] );
                }
            }                             
        }
    }


    function parse_css( css ) { 
        var css = css.replace( /[\s\n\t]+/g, ' ' ); // remove extra spaces, tabs and newlines
        css = css.replace( /\/\*(.|\n)+\*\//g, '' ); // remove comments
        css = css.split( '}' );  // split into groups
        var css_obj = []; // array to hold parsed css

        for( i in css ) {
            if( css[i] == false ) continue;
            var chunks = css[i].split( '{' );
            var selector = $.trim( chunks[0] );
            var style_defs = [];
            chunks = chunks[1].split( ';' );
            for( j in chunks ) {
                if( chunks[j] == false ) continue;
                var style_def = chunks[j].split( ':' );
                var property = $.trim( style_def[0] );
                var value = $.trim( style_def[1].replace( /\;$/, '' ) );
                style_defs[property] = value;
            }
            css_obj[selector] = style_defs;
        }
        return css_obj;
    }

    </script>

#8


0  

Here's how I do it:

我是这样做的:

var elFrom = document.getElementById('fromID');
var computedStyle = document.defaultView.getComputedStyle(elFrom,null);
$.each(computedStyle,function(key,value) {
    $('#toID').css(value,$(elFrom).css(value));
});

#9


-1  

And a more generalized solution from the provided answers..

从提供的答案中得到更广泛的解决方案..

HTML

HTML

<td style="padding:5px">
    <div class="inherit">
        Apply the TD styles to this DIV (instead of the TD).
    </div>
</td>

JS

JS

$('.inherit')
     .attr('style', $(this)
                    .parents('td')
                    .attr('style')
          )
     .parents('td')
     .removeAttr('style');

#1


8  

This is a solution I figured out, it mixes document.defaultView.getComputedStyle and jQuery's .css():

这是我想出的解决方案,它混合了document.defaultView.getComputedStyle和jQuery的.css():

<!-- index.html -->
<!DOCTYPE html>
<html>
<head>
    <script src="//ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js" >            </script>
    <link href="style.css" type="text/css" rel="stylesheet" />
</head>
<body>
    <div id="test" style="background-color: #FF7300">
        <p>Hi</p>
    </div>
    <a href="#" id="button">Apply styles</a>
    <script>
        $("#button").click(function() {
            var element = document.getElementById("test");
             $("#victim").css(document.defaultView.getComputedStyle(element, null));
        });
    </script>
    <div id="victim">
        <p>Hi again</p>
    </div>
</body>

//style.css 
#test {
    border: 3px solid #000000;
}

What this does is copy the computed style object, including the style.css and the inline style, and set it to the other div using jQuery's .css()

这样做是复制计算出的样式对象,包括style.css和内联样式,并使用jQuery的.css()将其设置为另一个div。

I hope I didn't misunderstand the question and that this is what you need.

我希望我没有误解这个问题,而这正是你所需要的。

Edit: Something I forgot is that you asked to 'move' the style rather than copy it. It's very simple to remove styles from the previous div using jQuery's .removeClass() and using .attr() to remove the style attribute, but you have to keep in mind that if there are any style rules being applied to the element's ID, there's no way to keep them from being applied.

编辑:我忘了的是你要求'移动'风格而不是复制它。使用jQuery的.removeClass()并使用.attr()删除样式属性来删除前一个div中的样式非常简单,但是你必须记住,如果有任何样式规则应用于元素的ID,那么无法阻止它们被应用。

#2


2  

EDIT: This answer was written before the question was clarified.

编辑:这个答案是在问题澄清之前写的。

Give your elements IDs, like this:

提供您的元素ID,如下所示:

<td id="td_element" style="padding:5px">
    <div id="div_element">
        Apply the TD styles to this DIV (instead of the TD).
    </div>
</td>

And use

并使用

var td_element = $('#td_element')
$('#div_element').attr('style', td_element.attr('style'));
td_element.removeAttr('style');

Of course you could use a class instead - or you may have the elements from previous javascript code. You'll need to decide the best way to reference the elements yourself.

当然你可以使用一个类 - 或者你可以使用以前的javascript代码中的元素。您需要自己决定引用元素的最佳方法。

#3


2  

I know this will look rough but it works. Initially copying all the computed styles from <td> and applying them to <div> is easy with this plugin from Mike Dunn. The troublesome bit is in removing the styles from the <td> after they have been copied. From what I can tell, the only thing you can do is manually reset them to default with .css().

我知道这看起来很粗糙但是有效。最初使用Mike Dunn的插件轻松地从复制所有计算出的样式并将它们应用到

。麻烦的一点就是在复制后从中删除样式。据我所知,你唯一能做的就是用.css()手动将它们重置为默认值。

Working Example

工作实例

$.fn.copyCSS = function (source) {
    var dom = $(source).get(0);
    var dest = {};
    var style, prop;
    if (window.getComputedStyle) {
        var camelize = function (a, b) {
                return b.toUpperCase();
        };
        if (style = window.getComputedStyle(dom, null)) {
            var camel, val;
            if (style.length) {
                for (var i = 0, l = style.length; i < l; i++) {
                    prop = style[i];
                    camel = prop.replace(/\-([a-z])/, camelize);
                    val = style.getPropertyValue(prop);
                    dest[camel] = val;
                }
            } else {
                for (prop in style) {
                    camel = prop.replace(/\-([a-z])/, camelize);
                    val = style.getPropertyValue(prop) || style[prop];
                    dest[camel] = val;
                }
            }
            return this.css(dest);
        }
    }
    if (style = dom.currentStyle) {
        for (prop in style) {
            dest[prop] = style[prop];
        }
        return this.css(dest);
    }
    if (style = dom.style) {
        for (prop in style) {
            if (typeof style[prop] != 'function') {
                dest[prop] = style[prop];
            }
        }
    }
    return this.css(dest);
};

$('td').click(function () {
    $('div').copyCSS('td');

    $('td').removeAttr('style');

    $("td").css({
        'font-family': 'none',
            'font-size': 'none',
            'font-weight': 'none',
            'font-style': 'none',
            'color': '#000',
            'text-transform': 'none',
            'text-decoration': 'none',
            'letter-spacing': 'none',
            'word-spacing': 'none',
            'line-height': 'none',
            'text-align': 'none',
            'vertical-align': 'none',
            'direction': 'none',
            'background-color': 'transparent',
            'background-image': 'none',
            'background-repeat': 'none',
            'background-position': 'none',
            'background-attachment': 'none',
            'opacity': '1',
            'width': 'none',
            'height': 'none',
            'top': '',
            'right': '',
            'bottom': '',
            'left': '',
            'margin-top': '0',
            'margin-right': '0',
            'margin-bottom': '0',
            'margin-left': '0',
            'padding-top': '0',
            'padding-right': '0',
            'padding-bottom': '0',
            'padding-left': '0',
            'border-top-width': '0',
            'border-right-width': '0',
            'border-bottom-width': '0',
            'border-left-width': '0',
            'border-top-color': '0',
            'border-right-color': '0',
            'border-bottom-color': '0',
            'border-left-color': '0',
            'border-top-style': '0',
            'border-right-style': '0',
            'border-bottom-style': '0',
            'border-left-style': '0',
            'position': 'static',
            'display': '',
            'visibility': 'visible',
            'z-index': 'auto',
            'overflow-x': 'auto',
            'overflow-y': 'auto',
            'white-space': 'normal',
            'clip': 'auto',
            'float': 'none',
            'clear': 'none',
            'cursor': 'default',
            'list-style-image': 'none',
            'list-style-position': '0',
            'list-style-type': 'disc',
            'marker-offset': '',
            'padding': '0',
            'transition': 'none',
            'border-radius': 'none'
    });
});

Note: obviously I have not included a reset for all possible styles.

注意:显然我没有为所有可能的样式包含重置。

#4


1  

EDIT: Code corrected

编辑:代码已更正

$('div').attr('style', $('td').attr('style'));

If you want to move just add this line afterwards

如果你想移动,只需在之后添加此行

$('td').attr('style', '');

I realize that this looks contrived but I have no other selectors to work with here. Normally you'd want to do this with an id or a class instead of the actual attribute.

我意识到这看起来很做人,但我没有其他选择器可以在这里工作。通常,您希望使用id或类而不是实际属性来执行此操作。

#5


1  

Don't move the styles is my short answer - find another way. Can you load another stylesheet after the stylesheet being loaded? If so, add a stylesheet that overrides the td and div padding defined in the stylesheet you're having to reference.

不要移动样式是我的简答 - 找到另一种方式。加载样式表后可以加载另一个样式表吗?如果是这样,添加一个样式表,覆盖您必须引用的样式表中定义的td和div填充。

#6


0  

What about applying the actual TD style to a class? Then just modify the class of the TD and the DIVs. Or you dont have access to the stylesheet?

将实际的TD风格应用于课程怎么样?然后只需修改TD和DIV的类。或者你没有访问样式表?

The CSS:

CSS:

.class_name { padding: 5px }

The HTML:

HTML:

<td class="class_name">
    <div>
        Apply the TD styles to this DIV (instead of the TD).
    </div>
</td>

The JavaScript:

JavaScript:

$(document).ready(function(){
    $('.class_name').removeClass('class_name').children('div').addClass('class_name');
});

#7


0  

You can try the following steps to copy the styles defined for particular element in stylesheets and <style> tags ( code is little bit lengthy ):

您可以尝试以下步骤来复制样式表和

  1. Get the contents of original stylesheets using ajax. and contents of each <style> tags
  2. 使用ajax获取原始样式表的内容。和每个
  3. Parse the css contents into array
  4. 将css内容解析为数组
  5. For each selectors in the parsed stylesheet, compare it's dom element with target dom element ( from which you are copying the styles ). if any of them matches , then apply styles corresponding to mathced selector to the required element
  6. 对于已解析样式表中的每个选择器,将其dom元素与目标dom元素(从中复制样式)进行比较。如果它们中的任何一个匹配,则将与数学选择器对应的样式应用于所需元素

Here is the code:

这是代码:

<html>
    <head>
        <script src="http://ajax.googleapis.com/ajax/libs/jquery/1.10.1/jquery.min.js"></script>
        <style>
        #source { width: 100px; height: 100px; background-color: black; }
        </style>
        <link rel="stylesheet" href="style.css">
    </head>
    <body>
       <table>
            <tr>
                <td id="source"></td>
            </tr>
       </table>
       <div id="target"></div>
    </body>

    <script>
    var source = $('#source'); // source
    var target = $( '#target' ); // target

    $( 'link[rel="stylesheet"]' ).each( function() {
          $.get( $(this).attr( 'href' ), {}, function( data ) {
                 var css_obj = parse_css( data );
                 copy_css( css_obj, source, target );
          });
    });

    $( 'style' ).each( function() {
        var css = $(this).text();
        var css_obj = parse_css( css );
        copy_css( css_obj, source, target );
    })

    function copy_css( css_obj, source, target ) {
        for( selector in css_obj ) {
            if( $(selector)[0] === source[0] ) { // compare raw dom elements 
                for( prop in css_obj[selector] ) {
                    target.css( prop, css_obj[selector][prop] );
                }
            }                             
        }
    }


    function parse_css( css ) { 
        var css = css.replace( /[\s\n\t]+/g, ' ' ); // remove extra spaces, tabs and newlines
        css = css.replace( /\/\*(.|\n)+\*\//g, '' ); // remove comments
        css = css.split( '}' );  // split into groups
        var css_obj = []; // array to hold parsed css

        for( i in css ) {
            if( css[i] == false ) continue;
            var chunks = css[i].split( '{' );
            var selector = $.trim( chunks[0] );
            var style_defs = [];
            chunks = chunks[1].split( ';' );
            for( j in chunks ) {
                if( chunks[j] == false ) continue;
                var style_def = chunks[j].split( ':' );
                var property = $.trim( style_def[0] );
                var value = $.trim( style_def[1].replace( /\;$/, '' ) );
                style_defs[property] = value;
            }
            css_obj[selector] = style_defs;
        }
        return css_obj;
    }

    </script>

#8


0  

Here's how I do it:

我是这样做的:

var elFrom = document.getElementById('fromID');
var computedStyle = document.defaultView.getComputedStyle(elFrom,null);
$.each(computedStyle,function(key,value) {
    $('#toID').css(value,$(elFrom).css(value));
});

#9


-1  

And a more generalized solution from the provided answers..

从提供的答案中得到更广泛的解决方案..

HTML

HTML

<td style="padding:5px">
    <div class="inherit">
        Apply the TD styles to this DIV (instead of the TD).
    </div>
</td>

JS

JS

$('.inherit')
     .attr('style', $(this)
                    .parents('td')
                    .attr('style')
          )
     .parents('td')
     .removeAttr('style');