Reputation: 23
I have the following jQuery snippet which should replace a code such as [Button] Text Here [/Button] into something like:
<a class="button">Text Here</a>
The javascript I have is the following:
$(document).ready(function() {
var buttonStart = $("body").html().replace(/\[Button\]*/ig,'<a class="button">');
$("body").html(buttonStart);
var buttonEnd = $("body").html().replace(/\[\/Button\]*/ig,'</a>');
$("body").html(buttonEnd);
});
The problem I am having is that it keeps replacing other elements on my page which have nothing to do with the Tags [Button] [/Button]. For insance the following:
<div id="MiddleBarLeft"></div>
Also gets replaced into
<a class="button"><div id="MiddleBarLeft"></div></a>
Shouldn't the Regex I have above just look for [Button] and [/Button] Tags?
Also, is there any other efficient way to go about this?
Thanks
=====================
Update.. this is my entire HTML file which replaces elements that have nothing to do with what I want to replace
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<script src="http://code.jquery.com/jquery-1.9.1.min.js"></script>
<script type='text/javascript'>
$(document).ready(function() {
var buttonStart = $("body").html().replace(/\[Button\]/ig,'<a class="button">');
$("body").html(buttonStart);
var buttonEnd = $("body").html().replace(/\[\/Button\]/ig,'</a>');
$("body").html(buttonEnd);
});
</script>
<style>
li{
list-style:none;
padding-top:10px;
padding-bottom:10px;}
.button, .button:visited {
background: #222 url(overlay.png) repeat-x;
display: inline-block;
padding: 5px 10px 6px;
color: #fff;
text-decoration: none;
-moz-border-radius: 6px;
-webkit-border-radius: 6px;
-moz-box-shadow: 0 1px 3px rgba(0,0,0,0.6);
-webkit-box-shadow: 0 1px 3px rgba(0,0,0,0.6);
text-shadow: 0 -1px 1px rgba(0,0,0,0.25);
border-bottom: 1px solid rgba(0,0,0,0.25);
position: relative;
cursor: pointer
}
</style>
</head>
<body>
<div>
<ul>
<li>[Button]Test[/Button]</li>
<li></li>
<li>Sample Text</li>
</ul>
</div>
</body>
</html>
Upvotes: 2
Views: 1916
Reputation: 4339
The problem stems from the way the replacement occurs - please consider the following fiddle: http://jsfiddle.net/GYrYa/
As you can see there are two buttons in the end, even though there's only one [Button][/Button] statement - it's because first you're replacing [Button] with <a class='button'>
which creates an unmatched tag. This causes an </a>
to be added at the end. Then you're replacing [/Button] with </a>
, which creates another unmatched tag - this time <a>
, at the end.
A better solution would be this: http://jsfiddle.net/GYrYa/1/
EDIT: http://jsfiddle.net/GYrYa/2/ to omit script tag matching
EDIT 2: http://jsfiddle.net/GYrYa/5/ - final solution, incorporating @Rain Diao non-greedy matching
EDIT 3: Added performance test cases: http://jsperf.com/eithed-rsc3, please read the discussion below @Rain Diao's answer for the genesis of it
Upvotes: 1
Reputation: 926
In actually, I did a quick testing, but cannot reproduce your problem. Please offer me more details, like an example.
two tips, ccouldimprove the performance:
remove the star in your RegExp. I think it was unneccessary.
call $('body').html(buttonReplaced) only once:
var buttonReplaced = $("body").html()
.replace(/\[Button\]/ig,'<a class="button">')
.replace(/\[\/Button\]/ig,'</a>');
$('body').html(buttonReplaced);
another solution:
var buttonReplaced= $('body').html().replace(/\[Button\](.*?)\[\/Button\]/gi, '<a class="button">$1</a>');
$('body').html(buttonReplaced);
Upvotes: 1
Reputation: 1469
Use + instead of a star in your regex. As the first will match nothing as well
$(document).ready(function() {
var buttonStart = $("body").html().replace(/\[Button\]/ig,'<a class="button">');
$("body").html(buttonStart);
var buttonEnd = $("body").html().replace(/\[\/Button\]/ig,'</a>');
$("body").html(buttonEnd);
});
Upvotes: 0
Reputation: 1199
I thinks this code $("body").html(buttonEnd)
; will replace buttonStart. Mybe you shout try append() method, like this: $("body").append(buttonEnd);
Upvotes: 0