I want this code to replace all ':)'s with my smiley emoji. Although when I run the code I get Uncaught TypeError: Cannot read property 'replace' of undefined at ?v=0.02:10 any help would be greatly appreciated!
Code:
<!DOCTYPE html>
<html>
<head>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
<title>SVG Emoji</title>
</head>
<body>
<script>
var html = document.getElementsByTagName("html").innerHTML;
html.replace(":)", "<img src='https://csf30816.github.io/svg-emoji/emojis/smile.svg'>");
document.getElementsByTagName("html").innerHTML = html;
</script>
<h1>:) Test</h1>
</body>
</html>
Replace
document.getElementsByTagName("html").innerHTML
with
document.getElementsByTagName("html")[0].innerHTML
as getElementsByTagName returns an array.
Also, the string.replace() method returns a new string without mutating / modifying the given one. You would need to re-assign the returned string to html = html.replace(...).
Also, you need to move your <script> to the bottom. Otherwise it can't access DOM elements that appear beneath it in your HTML document, such as the <h1> element:
<!DOCTYPE html>
<html>
<head>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
<title>SVG Emoji</title>
</head>
<body>
<h1>:) Test</h1>
<script>
var html = document.getElementsByTagName("html")[0].innerHTML;
html = html.replace(":)", "<img src='https://csf30816.github.io/svg-emoji/emojis/smile.svg'>");
document.getElementsByTagName("html")[0].innerHTML = html;
</script>
</body>
</html>
See also How to get the <html> tag HTML with JavaScript / jQuery?
For a more robust approach to replacing text within the DOM see jQuery replace all occurrences of a string in an html page
Your code and the problem you are trying to solve are doing different things. This will give you the solution you are seeking, i.e. replace all ':)'s with my smiley emoji
function replaceTextByImage(pattern, src) {
document.body.innerHTML = document.body.innerHTML.replace(
new RegExp(pattern, 'g'),
'<span style="background-size: 100% 100%; background-image: url(\'' + src + '\');">    </span>'
);
}
replaceTextByImage(':\\)', 'https://csf30816.github.io/svg-emoji/emojis/smile.svg');
replaceTextByImage(':P', 'https://s0.wp.com/wp-content/mu-plugins/wpcom-smileys/twemoji/2/svg/1f61b.svg');
replaceTextByImage(':D', 'https://what.thedailywtf.com/plugins/nodebb-plugin-emoji-one/static/images/1f603.svg');
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<html>
<body>
<p>
Hello World! How are you? :). Do you like this emoji :)
</p>
<div style="font-size:50px;">How about now :)</div>
<div style="font-size:25px">You can also do this :P and this :D now!</div>
</body>
</html>
PROS
Emoji will resize according to font used.
Replaces all occurrences of a pattern
CONS
If you have an inline script in the body of your html, it may be re-executed every time the function replaceTextByImage is called because it is setting the body's innerHTML.
If you want to use jquery then don't read this answer.
But for those who can allow their script not be jquery,
Here is your code.
document.getElementsByTagName("H1")[0].innerHTML = '<img src="https://csf30816.github.io/svg-emoji/emojis/smile.svg">';
<h1>:) Test</h1>
What the problem is:
You are returning an array.
Use one element with [0]:
document.getElementsByTagName("html")[0].innerHTML = html;
Related
is there a way of getting all the content of the page HTML , CSS , but exclude all the java script functions and script src?
var htmlPage = $("html").html();
console.log(htmlPage);
I know that will give me all of it. but I need to exclude the JS from the results
EDIT: fixed the regex (non-greedy version)
You can try this:
var htmlPage = $("html").html().replace(/<script[\s\S]*?<\/script>/mig, "");
The regular expression should match all <script> ... </script> tags and replace them with nothing.
BTW this is kind of a lucky shot because the regex itself requires the ending </script> to be escaped with a \ backslash like this: <\/script>.
This escape character is why the regex doesn't match itself, which would cause it to fail. So, it works because by escaping it correctly it isn't self-similar anymore.
Another option is to use Element.innerHTML and include the content that you want to get. For example:
<!doctype html>
<html>
<head>
<!--Css links goes here-->
</head>
<body>
<!--Your content-->
<p>Hello World</p>
</body>
<script>
//Js
</script>
<html>
var body = document.body.innerHTML;
var head = document.head.innerHTML;
Then you can concadenate or whatever you want.
I am working with HTML, CSS, jQuery, and JavaScript, all on one HTML page. Generally, I trying to figure out for the first time how to access information from the HTML body for use in my JavaScript code.
I want to set a variable in JavaScript equal to the string contained in the data attribute of one of my <div> elements.
Can I use document.getElementsByClassName()[] in my JavaScript to actually pull the information out of the HTML document? In examples on W3schools and elsewhere, I only see it used to change the value of some HTML element, not to actually use its input. Is there something more fundamental that I'm missing, here?
____here's my more specific code (where div.onlyOne is the only div of that class, and has the data-need attribute "string i need"):
var myVar = document.getElementsByClassName("onlyOne")[0].getAttribute("data-need")
Why will this not store "string i need" into myVar?
It works, make sure though, that you run the script after the markup or DOM load, or else the script will not find the element as it has not yet been loaded.
After in markup
<!DOCTYPE html>
<html>
<head>
<style>
</style>
</head>
<body>
<div class="onlyOne" data-need="hey there"></div>
<script type="text/javascript">
var myVar = document.getElementsByClassName("onlyOne")[0].getAttribute("data-need");
alert(myVar);
</script>
</body>
</html>
DOM load
<!DOCTYPE html>
<html>
<head>
<style>
</style>
<script>
document.addEventListener("DOMContentLoaded", function(event) {
var myVar = document.getElementsByClassName("onlyOne")[0].getAttribute("data-need");
alert(myVar);
});
</script>
</head>
<body>
<div class="onlyOne" data-need="hey there"></div>
</body>
</html>
May I suggest you use document.querySelector('.onlyOne') instead in the future. With that you can narrow down the result list in a more efficient way.
Src: https://developer.mozilla.org/en-US/docs/Web/API/Document/querySelector
<div class="onlyOne" data-need="some text">...</div>
var myVar = document.getElementsByClassName("onlyOne")[0].getAttribute("data-need");
alert(myVar);
https://jsfiddle.net/howa6w1o/
since you are using jQuery, you can simplify your code to get the contents of the data-attribute: as follows:
$(document).ready(function(){
var myVar = $(".onlyOne").eq(0).data("need");
})
I'm looking for a way that I can search an entire HTML document for a specific word and then swap each instance of that word with an image.
The problem I have is that I don't know what content is there because it is a dynamic page where the content is edited elsewhere and the site just pulls it in so referencing classes and ids is difficult.
I created a simple example with text that could resemble the content but the problem I have is my script will replace the whole document (I believe because of .html?) and I just want it to replace that specific piece of text.
<p>hi</p>
<p>j</p>
var x = $('body:contains("hi")');
x.html('<img src="/Content/by_car.jpg" />');
Could someone point me in the right direction?
Thanks in advance
You need to replace the original html like so x.html(x.html().replace('hi', '<img src="/Content/by_car.jpg" />'));
Also, this will be bad if, for example you will have <p class="hiblo">hi</p>. In this canse it will replace hi in hiblo and hi inside p tag thus ruining your markup.
Generally you can use some kind of regex but it's still not recommended to parse html with regex.
Here is working code.
This code also makes sure that script and style tags don't get replaced otherwise page logic will be broken. So it is taken care of as well.
<html>
<head>
<script type="text/javascript" src="jquery-1.11.3.min.js" > </script>
<style></style>
</head>
<body>
<h1>hi</h1>
<div>hi</div>
<input type="button" onclick="return replaceWithImage()" value="replace with image"/>
<script type="text/javascript">
function replaceWithImage() {
var x = $('body').find(':contains("hi")');
x.each(function(){
if($(this).prop('tagName') != 'SCRIPT' && $(this).prop('tagName') != 'STYLE')
$(this).replaceWith('<img src="/Content/by_car.jpg" />');
});
return false;
}
</script>
</body>
</html>
I'm using HTML Tidy in PHP and it's producing unexpected results because of a <script> tag in a JavaScript string literal. Here's a sample input:
<html>
<script>
var t='<script><'+'/script>';
</script>
</html>
HTML Tidy's output:
<html>
<script>
//<![CDATA[
var t='<script><'+'/script>';
<\/script>
<\/html>
//]]>
</script>
</html>
It's interpreting </script></html> as part of the script. Then, it adds another </script></html> to close the open tags. I tried this on an online version of HTML Tidy (http://www.dirtymarkup.com/) and it's producing the same error.
How do I prevent this error from occurring in PHP?
After playing around with it a bit I discovered that one can use comment //'<\/script>' to confuse the algorithm in a way to prevent this bug from occurring:
<html>
<script>
var t='<script><'+'/script>'; //'<\/script>'
</script>
</html>
After clean-up:
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 3.2//EN">
<html>
<head>
<script>
var t='<script><'+'/script>'; //'<\/script>'
</script>
<title></title>
</head>
<body>
</body>
</html>
My guess is that as the clean-up algorithm looks through the codes and detects the string <script> twice, it looks for </script> immediately. And separting < with /script> makes the second </script> goes undetected, which is why it decided to add another </script> at the end of the codes and somehow also closed it with antoher </html>. (Poor design indeed!)
So I made a second assumption that there isn't an if-statement in the algorithm to determine if a </scirpt> is in a comment, and I was right! Having another string <\/script> as a javascript comment indeed makes the algorithm to think that there are two </script> in total.
There's no need for string concatenation to avoid the closing </script>. Simply escaping the / character is enough to "fool" the parsers in browsers and, it seems, HTML Tidy's parser as well:
<html>
<script>
var t='<script><\/script>';
</script>
</html>
Try to make the script tag not a full word but a string concatenation
<html>
<script>
var t='<scr'+'ipt><'+'/script>';
</script>
</html>
Resulting cleaned code
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 3.2//EN">
<html>
<head>
<script>
var t='<scr'+'ipt><'+'/script>';
</script>
<title></title>
</head>
<body>
</body>
</html>
This is probably a better practice to create a script tag like this:
(this should also solve your tidy issues)
<script>
script = document.createElement('script');
script.type = 'text/javascript';
script.src = 'http://myserver.com/file.js';
document.getElementsByTagName('head')[0].appendChild(script);
</script>
One way is to make it so tidy doesn't detect the script tag. The "cleanest" way I could come up with is to escape a character in the tag.
<html>
<script>
var t='<\script><'+'/script>';
</script>
</html>
so you could even do this, without having to break the string up as above:
var t='<\script></\script>';
That just works as expected
<html>
<script>
var t='<'+'script><'+'/script>';
</script>
</html>
By the way, string concatenation is not best way to create dynamically HTML to insert in page, look for document.createElement or even templates engines (handlebars.js is my favourite)
How would I go about detecting which HTML element was tapped inside a UIWebView?
It seems a bit hacky, but right now the only way I can think of would be to evaluate JavaScript and use JS to traverse the DOM. Any help with this direction would be appreciated, too.
You could add a javascript function that takes a single argument, an id or whatever you prefer, and then add an onclick to all elements you are interested in that calls this function:
<html>
<head>
<title>Click test</title>
<script type="text/javascript">
function myClickHandler(elm)
{
alert('' + elm + ' element clicked');
}
</script>
</head>
<body>
<h1 onclick="myClickHandler('first');">First element</h1>
<h1 onclick="myClickHandler('second');">Second element</h1>
</body>
</html>
Edit: Ooh - you re not looking for a html/javascript solution. sorry.