Reputation: 1
I manage a forum that is hosted software so I don't have access to the source code, I can only add JavaScript to the page to achieve what I need done.
I'm trying to replace the first instance of certain text keywords on all pages with hyperlinks. I'm also geo-targeting those links based on country code.
I managed to piece together the code below by reading other answers on this site, and it actually works and does exactly what I want it to do, but it seems to be messing up other JavaScript (or jQuery?) Already loaded on the page previously.
Can anyone see anything wrong with this code that would cause it to affect other JavaScript code?
var c = null;
$.get("https://pro.ip-api.com/json/?key=XXXXXXXXXX", function(data) {
c = data.countryCode;
if (c == "GB") {
var thePage = $(".MessageList");
thePage.html(thePage.html().replace('KEYWORD1 ', '<a href="http://www.exampleGBlink1.com">KEYWORD1</a> '));
thePage.html(thePage.html().replace('KEYWORD2 ', '<a href="http://www.exampleGBlink2.com">KEYWORD2</a> '));
} else {
var thePage = $(".MessageList");
thePage.html(thePage.html().replace('KEYWORD1 ', '<a href="http://www.exampleELSElink1.com">KEYWORD1</a> '));
thePage.html(thePage.html().replace('KEYWORD2 ', '<a href="http://www.exampleELSElink2.com">KEYWORD2</a> '));
}
console.log(data.countryCode);
}, "jsonp");
Another problem I have with this code: it's also replacing instances of the keywords in my HTML code, so I added the extra blank space at the end of the keywords as a hack around this.
EDIT:
If I add the code below underneath the code above then everything works properly and my problems are gone, what gives? This file doesn't exist and I get a console error: "Failed to load resource: net::ERR_INSECURE_RESPONSE"
<script src="https://www.RandomDomain.com/test.js"></script>
Upvotes: 0
Views: 240
Reputation: 61
One problem I see is with the method you are using to replace the page content. When you extract html elements as a string by using "x.html()", you end up with the html elements in string form, but all of the attached event handlers are not included. When you then update the html elements by calling thePage.html(updatedHtmString), the html elements are restored as expected, but all of the attached event handlers are now lost. This could easily cause issues many js ui frameworks that heavily use event handlers.
Personally, I would traverse the DOM tree using jquery selectors, find the elements having html text content with those keywords, and replacing the keyword with a newly inserted element.
Instead of replacing the entire ".MessageList" DOM tree, you are only changing the text in the elements and adding a new element. No attached events will be lost.
I've added an example FIDDLE and function below. In the fiddle, you can see how your use of .html is removing event handlers. In the function below, I adjusted it to only change the first occurrence by adding ':first' jquery selector.
// Ugly but functional function to do the replacement.
function GoodReplaceOnlyFirstOccurence(findText, replaceWith) {
var $targElem = $(".MessageList1");
$targElem.children().each(function() {
var $elem = $(this);
$( ":contains('"+findText+"'):first", $elem ).html(function () {
return $(this).html().replace(findText, replaceWith);
});
});
}
Upvotes: 0
Reputation: 942
Try wrapping your JavaScript in an immediately invoked function expression (IIFE). This will avoid variables you use being registered on the global namespace. It's very likely for a variable name like c
to be used by a minified script that is loading on your page.
IIFE:
(function () {
// Your JavaScript here.
})();
Upvotes: 3