I'm stuck on this code...I'm trying to get the html page to, when you click the link, call the bms function, which should open internet explorer, go to google, and fill the search textbox with the word "test". This isn't exactly the website or word I want to use, but I needed to change it since the actual website/words are sensitive information. I want to use this through IE since our processes go through this browswer, specific with also using the -nomerge function. My code is below. Thanks for the help!
<html>
<head>
<script>
var WshShell = new ActiveXObject("WScript.Shell");
function BMS()
{
WshShell.Run("iexplore.exe -nomerge http://google.com");
WScript.Sleep (5000);
WshShell.SendKeys ("test");
WScript.Quit();
}
</script>
</head>
BMS
<br /><br />
DAY
</html>
Dont be thrown off by jade; it's just quicker. Just note I'm placing scripts just before the closing body tag.
html
head
title foo
body // body tag added
p notice that i've not declared script yet. Preference/good practice.
a#bsdTrigger(href='#') foo
a#ssddTrigger(href='#') bar
//- scripte here
The Important-ish part: here's a pen
(function() {
// now the variable will not pollute your global ns
var WshShell = {}; //ignore the OR only because there is no Active thing
WshShell.log = function() { // fake behavior for testing
console.log(arguments);
}
var bsd = function BSD() {
WshShell.log("foo");
window.alert('foo!');
return false;
}
document.getElementById("bsdTrigger").addEventListener('click', bsd);
})();
I hope this helps... It's very generic and contrived, but you'd employ the exact same methods in doing what you're trying to do.
Related
from an issue I am experiencing I understand how it works, but I can't find any formal reference that helps me to clarify the behaviour.
<head>
<title>Chapter 7: Example 7</title>
<script type="text/javascript">
var formWeek = document.form1;
var weekDays = new Array();
weekDays = formWeek.theDay.options;
function btnRemoveWed_onclick()
{
console.log("In btnRemoveWed_onclick");
}
</script>
</head>
<body>
<form action="" name="form1">
<select name="theDay" size="5">
<option value="0" selected="selected"></option>
With this code I receive an error on line "weekDays = formWeek.theDay.options;" because "theDay" is not defined. So I believe that while the JS code is executed the browser has not parsed and loaded the DOM (hence it doesn't know about form1).
If I move the variable definition inside the function, everything works fine.
function btnRemoveWed_onclick()
{
console.log("In btnRemoveWed_onclick");
var formWeek = document.form1;
var weekDays = new Array();
weekDays = formWeek.theDay.options;
}
At function execution the browser knows about form1 (load all the HTML code).
So... from the code the behaviour is clear but still it has not 'clicked' on my mind how it works.
I thought that the link below was a good reference to understand the behaviour.
Where should I put <script> tags in HTML markup?
Can you point me to some good reading that explains HTML-JS loading?
For what i know, javascript is loaded in line with HTML. So if you have an element <foo> and then a script that uses <foo> after that, it works. Turn them around, and the script is loaded first, after that the foo element. This way your script cannot find the element.
Change your javascript to:
function init()
{
var formWeek = document.form1;
var weekDays = new Array();
weekDays = formWeek.theDay.options;
function btnRemoveWed_onclick()
{
console.log("In btnRemoveWed_onclick");
}
}
document.addEventListener('DOMContentLoaded', init, false);
this way you make sure the javascript is loaded when the DOM is ready.
When you have an inline script tag in HTML, it blocks the parsing of HTML and it is executed immediately. Anything written after it has not been parsed yet.
It's common practice to put script tags at the end of the body tag, because at that point the DOM has been parsed and JS can safely execute.
As far as the error you pointed out is concerned, you can wait for the browser to finish loading the page by using something like window.onload. Notice lower in the documentation, in the Notes section
The load event fires at the end of the document loading process. At this point, all of the objects in the document are in the DOM, and all the images, scripts, links and sub-frames have finished loading.
This means by the time the code is run, your HTML has been parsed and put into the DOM. Your script tag, then, will be:
<script type="text/javascript">
window.onload = function() {
var formWeek = document.form1;
var weekDays = new Array();
weekDays = formWeek.theDay.options;
}
function btnRemoveWed_onclick()
{
console.log("In btnRemoveWed_onclick");
}
</script>
I am trying to get html of newly open window after activating a link that uses javascript by zombie.js.
Here is the html code
<html>
<head>
<script type="text/javascript">
function newin(id)
{
var url="page.php?id="+id;
window.open(url,id,"toolbar=no,location=top,directories=no,status=no,scrollbars=yes,hscroll=no,resizable=yes,copyhistory=no,width=1025,height=1250");
}
</script>
</head>
<body>
<div>
123<br/>
234<br/>
345<br/>
</div>
</body>
The Script I am using is:
var Browser = require("zombie");
var browser = new Browser();
browser.visit("http://localhost:8000/testpage.html", function () {
browser.wait(function(){
var selector = "a[href*='newin']";
var elements = browser.queryAll(selector);
for (var e=0;e<elements.length;e++){
browser.clickLink(elements[e],function(){
browser.wait(function(){
console.log(browser.html());
});
});
}
});
});
I am not able to get HTML of any window.Any ideas what is wrong in this code ? Or is this possible with phantomjs??
Finally I come to know that if a link contains JavaScript directly in the href or action, Zombie seems to understand that as opening a new page like a normal hyperlink would. While the JavaScript is still executed correctly, the DOM is lost as a result of Zombie trying to load the invalid target as a new page.
A problematic link would be e.g.
test
There’s no support for javascript:links, it is still an open issue:
https://github.com/assaf/zombie/issues/700
I have been working on a complex project for the past few weeks when I encountered this bizarre bug. I have since isolated my problem in the code below, which is the smallest possible valid HTML and JS that reproduces it:
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>Chat</title>
<script type="text/javascript">
//<![CDATA[
function refresh()
{
var old = document.getElementById("conversation").innerHTML;
var message = '<img/>';
if(old != message) {
alert("Old:\n" + old);
alert("New:\n" + message);
//alert("Refreshed!");
document.getElementById("conversation").innerHTML = message;
}
}
//]]>
</script>
</head>
<body onload="refresh()">
<div id="conversation"></div>
<script type="text/javascript">var myVar = setInterval(function(){refresh();},1000);</script>
</body>
</html>
Every second, the function refresh() checks to see if the code in the div is different than the stored string. If it is different, it replaces the div's contents with the string. However, each time it checks, it sees the contents and the stored string are different. Although the string is <img/>, the innerHTML is returned as <img>. I figured out that for any self-closing tag, it automatically removes the slash. For a tag that isn't supposed to be self-closing (like <i>), it automatically splits it into two tags (like <i></i>). For any other tag or text, it does nothing.
I don't really understand why the div's contents are changing at all. If anyone can explain why, I would appreciated it. If someone can even provide a possible solution, I would be grateful.
That's because the browser is using an HTML parser, not an XML parser for the page, that's why it will remove the closing slash.
I'm a relative novice myself but I think what Matt Ball is referring to is the fact that you are creating a string when you should be creating a new DOM element So one simple change to your function would be:
var convo = document.getElementById("conversation");
function refresh() {
var old = convo.innerHTML;
var message = document.createElement("IMG");
if (old != message) {
alert("Old:\n" + old);
alert("New:\n" + message);
//alert("Refreshed!");
convo.innerHTML = message;
}
}
Here is a FIDDLE
Note: I added the global convo variable to reduce keystrokes and use document.createElemet instead of innerHTML to add the new image element to the DOM. You can then call upon that image element inside or outside your function using the firstChild method like this:
convo.firstChild;
This is a piece of code that links to a javascript file that generates some fake tweets, along with some self made comments that attempt to explain to myself what is happening. I was wondering what the purpose of $body.html(''); was. It seems like it just clears the contents of the body, which is already empty except for the javascript that is present. Wouldn't this also clear the actual script that inside the body as well? i.e., why doesn't the whole script just vanish when we reach that line. I'm guessing that the function is executed in its entirety before the body is cleared? Just looking for a little illumination, I guess, on function execution.
<!DOCTYPE html>
<html>
<head>
<script src="jquery.js"></script>
<script src="data_generator.js"></script>
</head>
<body>
<script>
$(document).ready(function(){ // calls function only after dom is loaded
var $body = $('body'); // selects html body tag, stores in $body
$body.html(''); // clears body?
var index = streams.home.length - 1; // sets index to length of streams array
while(index >= 0){
var tweet = streams.home[index]; // gets a tweet string
var $tweet = $('<div></div>'); // $tweet is a div element
$tweet.text('#' + tweet.user + ': ' + tweet.message); // add formatted tweet to div
$tweet.appendTo($body); // add tweet to body
index -= 1; // rinse, repeat
}
});
</script>
</body>
</html>
EDIT: To be clear, I didn't write the code, only the comments. I am just trying to break it down and understand each line.
When the Javascript is run the function context is stored in memory, and closed-over variables are stored in the context. They don't go away. Globals are attached to window. They don't go away either.
I think it is a better idea to append the script to the header (where all the other scripts reside) than to the body.
If you want to completely eliminate the script that is being called, you could use:
<script>
(function foo(){
var b=function moo(){
var c=document.getElementsByTagName('script');
alert(document.body.innerHTML);
c[0].parentElement.removeChild(c[0]);
alert(document.body.innerHTML);
}
var a=setTimeout(b,1000);
b=null;
})();
foo=null;
</script>
Keep in mind, that will COMPLETELY remove any functionality of the script and any reference to it in the DOM.
Basically, because the script has already loaded, you can't just remove it from the DOM.
Is there really any reason to get rid of it, now that it's already loaded...???
This is a bit of an oddball use case, but I have my reasons:
I'd like to be able to write
<script type="text/javascript" src="first.js"></script>
<script type="text/javascript" src="second.js"></script>
in my markup and, using the code in first.js, prevent or delay the execution of second.js. Is this possible, in any browser? What if the contents of first.js are inlined? (If it helps, assume that the second script tag has an id attribute.)
Since I've gotten a couple of answers that missed what I'm getting at, I should clarify:
The solution must be entirely within first.js. Anything that require changes to the original HTML of the page, or to second.js, is not acceptable.
It is acceptable to load second.js via Ajax and execute it using eval. That's the easy part. The hard part is preventing the immediate execution of second.js.
Assume that you don't know what's in second.js. So, you can't just replace each global function called by second.js with a no-op function. (Plus, this would almost certainly lead to errors.)
If you know of a solution that works in some browsers but not in others, I'd love to hear it.
Example: To make this a little more concrete, let's say that the code
<script type="text/javascript">
function func() {
window.meaningOfLife = 42;
window.loadSecond();
};
setTimeout(func, 10);
</script>
precedes the two script includes, and that second.js contains the line
if (window.meaningOfLife !== 42) {throw new Error();}
first.js should be able to prevent this error by delaying second.js from executing until window.loadSecond is run. (Assume the implementation of window.loadSecond is also in first.js.) It is not allowed to touch window.meaningOfLife.
Update: Alohci's answer meets these requirements, but only on the condition that the second script tag comes immediately after the first, with nothing but whitespace in between. If someone could extend his hack to avoid that requirement, without introducing other unwanted consequences, that would be amazing...
Given your specific requirements set, this is actually quite simple and should work completely cross-browser. It does require however, that first.js immediately precedes second.js without anything between them except white space.
First, let's assume that the HTML looks like this:
<!DOCTYPE html>
<html>
<head>
<title>Test Case</title>
<meta charset="UTF-8" />
<script type="text/javascript">
function func() {
window.meaningOfLife = 42;
window.loadSecond();
};
</script>
<script type="text/javascript" src="first.js"></script>
<script type="text/javascript" src="second.js"></script>
</head>
<body>
<p>Lorem ipsum dolor sit amet ...</p>
Run Func()
</body>
</html>
I've removed the setTimeout because that can cause func() to run before start.js runs causing a "loadSecond is not defined" error. Instead, I've provided an anchor to be clicked on to run func().
Second, let's assume that second.js looks like this:
document.body.appendChild(document.createTextNode("second.js has run. "));
if (window.meaningOfLife !== 42) {throw new Error();}
Here, I've just added a line to append some text to the document body, so that it is easier to see when second.js actually runs.
Then the solution for first.js is this:
function loadSecond()
{
var runSecond = document.createElement("script");
runSecond.setAttribute("src", "second.js");
document.body.appendChild(runSecond);
}
document.write("<script type='application/x-suppress'>");
The loadSecond function is just there to run second.js when func() runs.
The key to the solution is the document.write line. It will inject into the HTML <script type='application/x-suppress'> between the close script tag of first.js and the open script tag of second.js.
The parser will see this and start a new script element. Because the type attribute has a value which is not one that the browser recognises as being JavaScript, it will not attempt to run its content. (So there are an infinite number of possible type attribute values you could use here, but you must include a type attribute, as in its absence, the browser will assume that the script's content is JavaScript.)
The second.js script's opening tag will then be parsed as text content of the new script element and not executed. Finally the second.js script's closing tag will be re-purposed to close the new script element instead, which means that the remainder of the HTML is parsed correctly.
You can see a working version at http://www.alohci.net/static/jsprevent/jsprevent.htm
In first.js, set var shouldILoad = true
Then, load second.js this way:
<script>
if (shouldILoad) {
(function() {
var myscript = document.createElement('script');
myscript.type = 'text/javascript';
myscript.src = ('second.js');
var s = document.getElementById('myscript');
s.parentNode.insertBefore(myscript, s);
})();
}
</script>
(where 'myscript' is the ID of some element before which you'd like to insert the new Script element)
As far as I know, you can't. If the markup looks like
<script type="text/javascript" src="first.js"></script>
<script type="text/javascript" src="second.js"></script>
you can't access the second script element from within first.js, as it hasn't been added to the DOM at the moment the first script runs (even not if you assign an id to the second element). It doesn't matter whether the code of second.js is put inline or in an external file.
The only thing I don't understand is your second point. First you say that you can't control the markup of the document, but then you state it is possible to load second.js dynamically (using AJAX).
Following article describes the way you could block (3-rd party) scripts loading/execution from your script (including the both tag in the page head and dynamically added tags).
To handle existing tags on a page:
Use a MutationObserver to observe script elements insertion and inside the MutationObserver callback backup the script (to enable/insert it later) and change the script type to "javascript/blocked" (not works in IE, Edge, Firefox). Also you could handle deprecated (but working) beforescriptexecute event in Firefox to prevent script load.
Manually set type "javascript/blocked" (works everywhere including IE and Edge) like
<script type="text/javascript" type="javascript/blocked" src="second.js"></script>, then backup it in MutationObserver callback and re-add it later.
To handle dynamically added tags
Monkey-patch the document.createElement.
Override ‘src’ and ‘type’ descriptors on the HTMLScriptElement prototype.
Also this guys provide a yett library with the approach described in the article.
All <script> tags have their own execution context, which makes it nearly impossible to interfere with each other. Of course you've got the (infamous) global object (referenced by window in browsers).
Preventing the execution of second.js is rather simple: break it!
Assuming that second.js tries to call document.getElementById for example:
Working example of breaking jQuery, then loading later (with dependecies).
Tested on: IE 6+, FF 3.6+, Chrome
end of first.js
var execute;
// saving our position
var scripts = document.getElementsByTagName("script");
var i = scripts.length;
// breaking getElementById
var byId = document.getElementById;
document.getElementById = null;
var interval = setInterval(function () {
if (i != scripts.length) {
var second = scripts[i];
// stop polling
clearInterval(interval);
// fix getElementById
document.getElementById = byId;
// set the delayed callback
execute = function (onload) {
var script = document.createElement("script");
script.src = second.src;
script.onload = script.onreadystatechange = onload;
document.getElementsByTagName("head")[0].appendChild(script);
};
}
}, 100);
anytime you wanna execute second.js
execute(function(){
// second.js dependant code goes here...
});
Note: the onload parameter for execute is optional.
Just to see if this was possible, I had first.js send a synchronous XHR to a PHP file, and had the PHP file delete second.js. When the readyState reached '4', I had the JS alert something, to stop the thread. Then I went and checked the server... Yeah, second.js was deleted. And yet, it wouldn't work. I'd close the alert box, and the code that was in second.js would still be executed, despite the fact that the file was gone.
I don't really know what this means, but the answer to your question is probably, "No, it's not possible."
you may use setTimeout() to delay the execution of some code