How to run script in v-html - javascript

I get embed codes (Instagram, Twitter and so on) from database. How to bind them to a vue component? Is there any way for executing script tag in v-html?

Short answer: You can't. Your browsers blocks the execution of script tags once the dom has loaded.
Long answer: You could try matching the src attribute of the script and fetch + evaluate it, or match the inner content of the div and evaluate it, but this is not recommended.

For the purpose of the title, the browser will block you.
However, for the purpose of the question, you can easily predict/list the embed codes you want to support, so this is something you could do:
if (window.twttr) {
// The script is already loaded, so just reload the embeds
window.twttr.widgets.load();
} else if (!document.getElementByID('twttr-widgets')) {
const embed = document.createElement('script');
embed.id = 'twttr-widgets'
embed.src = 'https://platform.twitter.com/widgets.js';
document.body.appendChild(embed);
// And when the script loads, the embeds will load too
}
This can easily be replicated for most embed libraries that allow you to "reload" all the widgets on the page:
Facebook FB.XFBML.parse
Twitter twttr.widgets.load
Instagram instgrm.Embeds.process

Related

Access CURRENT src in embed object HTML

I have created an embed object in HTML and this code in Javascript:
function mainLoop() {
var browser = document.getElementById("browser");
console.log(browser.src);
}
//call main loop
setInterval(mainLoop, 1000);
<embed src="https://en.wikipedia.org/wiki/Main_Page" id=browser>
When I run the webpage, the console constantly prints "https://en.wikipedia.org/wiki/Main_Page", which is what is expected. However, when I click on a link inside the embed HTML to change the webpage inside the embed HTML, the console continues to print "https://en.wikipedia.org/wiki/Main_Page".
How do I access the current URL of the content inside of the embed HTML?
(I cannot use browser.contentWindow because of a Security Error)
Unfortunately due to CORS, this is impossible. Perhaps find a different way of doing this, or make a page similar to the one shown.
You cannot access the src of an iframe that is from another domain.

Terminate an HTML script element

My site has a page loading system to load only the necessary content of the next page that the user is navigating to, and it keeps the top navigation and footer, and only fetches the new content. In order to execute the script tags that are in the new HTML content that's loaded with fetch(), all the script tags are appended with document.body.appendChild(scriptElementToRun). The script elements are added to an array so that they can be removed when the user navigates to another page which will require different scripts. The problem is that removing the script elements from the DOM is not enough to terminate them. They still continue to execute. Is it possible to stop the execution of only the scripts that are in the array, even asynchronous code such as setInterval, setTimout, WebSockets etc. that don't run in the main event loop, without adding anything to the script tags I want to stop?
This is the code that adds the scripts:
let result = new TextDecoder("utf-8").decode(data); // decode the binary response data
$('mn').innerHTML = result; // a div that contains the main body content of the page
for (script of $('mn').getElementsByTagName('script')) {
let activeScriptElement = document.createElement('script');
pageScripts.push(activeScriptElement);
if (script.src) {
activeScriptElement.src = script.src;
console.log('run script: ' + script.src);
} else { // inline script
activeScriptElement.appendChild(document.createTextNode(script.innerHTML));
console.log('run script: inline');
}
document.body.appendChild(activeScriptElement);
}
I then remove the scripts when loading a new page:
for (script of pageScripts){
script.remove();
}
EDIT:
What I ended up doing is putting all the page HTML content in an iFrame and communicating between the iFrame and the parent window with window.postMessage()
It would be helpful to see the code you're talking about. I'm guessing that you are using event listeners, which will still be active, even if you remove script-tags from the DOM.
You can remove events like this:
document.getElementById("your-elements-id").removeEventListener();
var myTimeout = setTimeout(...);
clearTimeout(myTimeout);
var myInterval = setInterval(...);
clearInterval(myInterval);

Remake page while loading

I'm writing an extension for chrome. The problem is I need to insert an iframe of loading page into DOM instead of loading itself.
Here is a code of the content script which is not working:
window.stop();
var body = document.createElement("body");
body.src = window.location.href;
document.documentElement.appendChild(body);
Why browser generate body in DOM but don't show it on the page?
Have got no idea why is it happen, but window.stop blocks the DOM from changes after calling. In order to reset this state I should do this:
document.documentElement.innerHTML = "";
And as a bonus head and body will be appended automatically)

Javascript set title onload?

Is there anyway to set the title of a website via JS onload? I wrote this but I'm not sure where it's incorrect:
function my_code(){
document.title = "The new title goes here.";
}
window.onload=my_code();
The page title is static by the way.
Edit: The reason why I want to do it this way is because I'm writing a Safari Extension for a website that does not include tags so I wanted to insert one via JS.
You don't need to wait for the load event.
Just write document.title = ... anywhere.
If you want to change the title after the page loaded, you have to assign a function reference to onload (your function assigns the return value of my_code):
window.onload = my_code;
However, you most certainly can set the title without waiting for the load event.
I'm not familiar with Safari extensions, but you should also make sure that window actually refers to the page's window.

Browser refresh on AJAX with script tags in the response

I'm having some issues with a jQuery AJAX call. My code works fine when I request a page with no javascript in it, but when I have script tags in my code, things start to get weird.
It seems that any script tags referencing external URLs cause the browser to redirect. In firefox, the page goes blank. In safari, the page clears and loads with the content of the AJAX response. In both browsers, the URL doesn't change.
To be specific about my problem; I have a tab control in which I'm trying to embed the walkscore widget. Since it's pretty heavy on the client side, I only want to actually load it once the user clicks the tab it's in. The walkscore AJAX page looks like this:
<script type="text/javascript">
var ws_address = "1 Market St, San Francisco";
var ws_width = "500";
</script>
<script type="text/javascript" src="http://www.walkscore.com/tile/show-tile.php?wsid=MY_WSID">
</script>
Is there some restriction on script tags referencing external sites on AJAX calls? Is there any nice way around this?
-- Edit --
OK I've been playing with it for a bit and have narrowed down the problem a little. Let me try give a better explanation at the same time:
I have two files, index.html and walkscore.html
index.html
function widget() {
var widget = $('#walkscore');
$.get('/walkscore.html', function(data) {
$('#loading').slideUp(function() {
widget.html(data);
loaded[name] = true;
widget.slideDown();
});
});
}
walkscore.html - as shown in the top code block
In index.html, I have a link that calls the widget function. Whenever I click this link, the whole page is replaced by the output of the js file. It happens regardless of the domain the js file is from. It only seems to happen with js files that have document.write in them. It behaves in exactly the same way when I use the $.getScript function, even when it's in index.html
-- Edit --
It seems it has everything to do with the document.write. I made a copy of the walkscore javascript and replaced all occurrences of document.write with jquery.html, and it seems to work properly. I'm (obviously) a js noob. Is this the expected behavior of document.write? How come it doesn't do it when I include the script on a page load?
Load script separately from html content, you can use $.getScript( ).
It has to do with the document.write in the response.. I was able to fix this in Firefox by doing this:
<script type="text/javascript">
// save default document.write function so we can set it back
var write_func_holder = document.write;
// redefine document.write to output text target div
document.write = function(text) {
$('#ad_container').html($('#ad_container').html() + text);
}
</script>
<script language="JavaScript" type="text/javascript" src="javascriptfile">
</script>
<script type="text/javascript">
// reset document.write function
document.write = write_func_holder;
</script>
I'm still getting an issue in Safari where the browser refreshes to a blank page with just the content of the document.write and IE6, IE7 doesn't do anything at all. Firefox works though.
I hope this helps someone figure out what wrong and they in turn can fix the IE6/7 and Safari issues
It happens because of the document.write call. Here's some info on what's going on:
Writing After A Page Has Been Loaded
If document.write() is invoked after a page has finished loading, the entire static (non-script generated) content of a page will be replaced with the write method's parameter. This scenario is most often played out when the write method is invoked from an event handler - whether the method is in a function called by the event handler or alone inside the handler - because event handlers are triggered after a page has finished loading. This is important to know because static content replacement is not always the desired result. Another common scenario for content overwite has to do with writing content to a new window. In this case, the overwrite of blank page is the goal.
(source)
The solution I went with was to eliminate the document.write commands, and replace the content of a div instead. If you're loading an external script, and have no control over it, you can replace the document.write function with your own. It's discussed here:
http://www.webxpertz.net/forums/showthread.php?threadid=11658
Hope that helps someone out there!
Replacing document.write is the way to go. This is shameless self promotion, but if you have a non-trivial case, writeCapture.js handles all the edge cases.
I would first check the response of that script source, maybe something in that causes the unwanted behavior.
I am experiencing the EXACT same behaviour and spent some frustrating hours last night trying to figure out what the problem was and searching for answers to no avail. I'm surprised this is mentioned anywhere in the jquery docs as it seems like a plausible problem not some crazy never-to-be-encountered bug.
Anyway, here's my story in case anyone searches for something related.
I have a jquery enabled page that loads some content into a div using $.ajax(), it all works perfectly. What I needed to do was include one of those twitter retweet buttons that shows a count and enables you to tweet about the content on the page. To do this a simple piece of javascript from them should be included on the page.
<script type="text/javascript" src="http://www.retweet.com/static/retweets.js"></script>
So in theory, that script tag should be returned in the ajax call and jquery should execute it and include the result of it, as I specified the data type as html in the $.ajax() call.
The external script on closer inspection does:
if(!url)
{
var url=window.location.href;
}
if(!size)
var size="big";
var height="75";
var width="54"
if(size=="small")
{
height="22";
width="120";
}
if(!username)
var username="none";
url=url.replace("?", "*");
var src="http://www.retweet.com/widget/button/"+size+"/"+username+"/"+url;
document.write('<iframe src="'+src+'" height="'+height+'" width="'+width+'" frameborder="0" scrolling="no"></iframe>');
Which obviously bombs out on the document.write.
Tonight i'll try the methods in this post and see if they work, thanks for the info.

Categories