Reputation: 1115
Looking for help with a javascript reg ex replacement. What I need, is to replace all instances of
width="100">
With
style="width: 100px;"
But the actual px value is variable which is what is causing issues for me. I know reg expression is the way to go but I dont quite understand it.
This is a similar question but doesn't solve the issue for me: JavaScript Regex Replace Width Attribute Matching
The reason this is a problem is because of the HTML generated by TinyMce...
Upvotes: 0
Views: 1995
Reputation: 9180
My first thought also was to work with the DOM instead of using RegEx. Instead of iterating over all the elements, we could just use querySelector
, which supports attribute selectors.
var html = '<img src="//placehold.it/100x100" alt="" style="100px;">'+
'<img src="//placehold.it/120x120" alt="" width="120" style="border: 2px solid steelblue;">'+
'<img src="//placehold.it/140x140" alt="" width="140">',
wrap = document.createElement('div'),
nodes;
wrap.innerHTML = html;
nodes = wrap.querySelectorAll('[width]');
Array.prototype.forEach.call(nodes, function(el) {
var width = el.getAttribute('width');
if(width) {
el.removeAttribute('width');
el.style.width = width+'px';
}
});
Upvotes: 0
Reputation: 1075199
Two options:
Using a regular expression
Parsing the HTML and working with the DOM (preferred)
The expression is fairly straightforward:
str = str.replace(/\bwidth="(\d+)"/g, 'style="width: $1px"');
The $1
in the replacement string is filled in with the content of the first capture group.
Example:
var str = '<div width="100">Stuff here</div><div width="240">More stuff here</div>';
display("Before: '" + str + "'");
str = str.replace(/\bwidth="(\d+)"/g, 'style="width: $1px"');
display("After: '" + str + "'");
function display(msg) {
document.body.insertAdjacentHTML(
"beforeend",
"<p>" +
String(msg)
.replace(/&/g, "&")
.replace(/</g, "<") +
"</p>"
);
}
But note that that will:
Replace width="nnn"
everywhere in the string, even if not inside a start tag
End up adding a second style
attribute to a tag that already has one
If that's okay, great; if not, you might want to parse the HTML, process the resulting parsed DOM nodes, and then serialize it again.
A better option is to parse the HTML and work with the DOM. You've said that the HTML will be for a div
, so we don't have to worry about things like standalone table cells, etc.
Here's a simple parsing and updating example:
var str = '<div width="100">Stuff here</div><div width="240">More stuff here</div>';
var div = document.createElement('div');
div.innerHTML = str;
update(div.childNodes);
display("Before: '" + str + "'");
str = div.innerHTML;
display("After: '" + str + "'");
function update(nodes) {
Array.prototype.forEach.call(nodes, function(node) {
var width;
if (node.nodeType === 1) { // An element
width = node.getAttribute("width");
if (width) {
node.removeAttribute("width");
node.style.width = width + "px";
}
update(node.childNodes);
}
});
}
function display(msg) {
document.body.insertAdjacentHTML(
"beforeend",
"<p>" +
String(msg)
.replace(/&/g, "&")
.replace(/</g, "<") +
"</p>"
);
}
Upvotes: 3