Any idea why the piece of code below does not add the script element to the DOM?
var code = "<script></script>";
$("#someElement").append(code);
The Good News is:
It's 100% working.
Just add something inside the script tag such as alert('voila!');. The right question you might want to ask perhaps, "Why didn't I see it in the DOM?".
Karl Swedberg has made a nice explanation to visitor's comment in jQuery API site. I don't want to repeat all his words, you can read directly there here (I found it hard to navigate through the comments there).
All of jQuery's insertion methods use
a domManip function internally to
clean/process elements before and
after they are inserted into the DOM.
One of the things the domManip
function does is pull out any script
elements about to be inserted and run
them through an "evalScript routine"
rather than inject them with the rest
of the DOM fragment. It inserts the
scripts separately, evaluates them,
and then removes them from the DOM.
I believe that one of the reasons jQuery
does this is to avoid "Permission
Denied" errors that can occur in
Internet Explorer when inserting
scripts under certain circumstances.
It also avoids repeatedly
inserting/evaluating the same script
(which could potentially cause
problems) if it is within a containing
element that you are inserting and
then moving around the DOM.
The next thing is, I'll summarize what's the bad news by using .append() function to add a script.
And The Bad News is..
You can't debug your code.
I'm not joking, even if you add debugger; keyword between the line you want to set as breakpoint, you'll be end up getting only the call stack of the object without seeing the breakpoint on the source code, (not to mention that this keyword only works in webkit browser, all other major browsers seems to omit this keyword).
If you fully understand what your code does, than this will be a minor drawback. But if you don't, you will end up adding a debugger; keyword all over the place just to find out what's wrong with your (or my) code. Anyway, there's an alternative, don't forget that javascript can natively manipulate HTML DOM.
Workaround.
Use javascript (not jQuery) to manipulate HTML DOM
If you don't want to lose debugging capability, than you can use javascript native HTML DOM manipulation. Consider this example:
var script = document.createElement("script");
script.type = "text/javascript";
script.src = "path/to/your/javascript.js"; // use this for linked script
script.text = "alert('voila!');" // use this for inline script
document.body.appendChild(script);
There it is, just like the old days isn't it. And don't forget to clean things up whether in the DOM or in the memory for all object that's referenced and not needed anymore to prevent memory leaks. You can consider this code to clean things up:
document.body.removechild(document.body.lastChild);
delete UnusedReferencedObjects; // replace UnusedReferencedObject with any object you created in the script you load.
The drawback from this workaround is that you may accidentally add a duplicate script, and that's bad. From here you can slightly mimic .append() function by adding an object verification before adding, and removing the script from the DOM right after it was added. Consider this example:
function AddScript(url, object){
if (object != null){
// add script
var script = document.createElement("script");
script.type = "text/javascript";
script.src = "path/to/your/javascript.js";
document.body.appendChild(script);
// remove from the dom
document.body.removeChild(document.body.lastChild);
return true;
} else {
return false;
};
};
function DeleteObject(UnusedReferencedObjects) {
delete UnusedReferencedObjects;
}
This way, you can add script with debugging capability while safe from script duplicity. This is just a prototype, you can expand for whatever you want it to be. I have been using this approach and quite satisfied with this. Sure enough I will never use jQuery .append() to add a script.
I've seen issues where some browsers don't respect some changes when you do them directly (by which I mean creating the HTML from text like you're trying with the script tag), but when you do them with built-in commands things go better. Try this:
var script = document.createElement( 'script' );
script.type = 'text/javascript';
script.src = url;
$("#someElement").append( script );
From: JSON for jQuery
It is possible to dynamically load a JavaScript file using the jQuery function getScript
$.getScript('http://www.whatever.com/shareprice/shareprice.js', function() {
Display.sharePrice();
});
Now the external script will be called, and if it cannot be loaded it will gracefully degrade.
What do you mean "not working"?
jQuery detects that you're trying to create a SCRIPT element and will automatically run the contents of the element within the global context. Are you telling me that this doesn't work for you? -
$('#someElement').append('<script>alert("WORKING");</script>');
Edit: If you're not seeing the SCRIPT element in the DOM (in Firebug for example) after you run the command that's because jQuery, like I said, will run the code and then will delete the SCRIPT element - I believe that SCRIPT elements are always appended to the body... but anyway - placement has absolutely no bearing on code execution in this situation.
This works:
$('body').append($("<script>alert('Hi!');<\/script>")[0]);
It seems like jQuery is doing something clever with scripts so you need to append the html element rather than jQuery object.
Try this may be helpful:
var fileref=document.createElement('script');
fileref.setAttribute("type","text/javascript");
fileref.setAttribute("src","scriptAnalytics.js");
document.getElementsByTagName("head")[0].appendChild(fileref);
I want to do the same thing but to append a script tag in other frame!
var url = 'library.js';
var script = window.parent.frames[1].document.createElement('script' );
script.type = 'text/javascript';
script.src = url;
$('head',window.parent.frames[1].document).append(script);
<script>
...
...jQuery("<script></script>")...
...
</script>
The </script> within the string literal terminates the entire script, to avoid that "</scr" + "ipt>" can be used instead.
Adding the sourceURL in the script file helped as mentioned in this page:
https://blog.getfirebug.com/2009/08/11/give-your-eval-a-name-with-sourceurl/
In the script file, add a statement with sourceURL like "//# sourceURL=foo.js"
Load the script using jQuery $.getScript() and the script will be available in "sources" tab in chrome dev tools
Your script is executing , you just can't use document.write from it. Use an alert to test it and avoid using document.write. The statements of your js file with document.write will not be executed and the rest of the function will be executed.
This is what I think is the best solution. Google Analytics is injected this way.
var (function(){
var p="https:" == document.location.protocol ? "https://" : "http://";
d=document,
g=d.createElement('script'),
s=d.getElementsByTagName('script')[0];
g.type='text/javascript';
g.src=p+'url-to-your-script.js';
s.parentNode.insertBefore(g,s); })();
You don't need jQuery to create a Script DOM Element. It can be done with vanilla ES6 like so:
const script = "console.log('Did it work?')"
new Promise((resolve, reject) => {
(function(i,s,o,g,r,a,m){
a=s.createElement(o),m=s.getElementsByTagName(o)[0];
a.innerText=g;
a.onload=r;m.parentNode.insertBefore(a,m)}
)(window,document,'script',script, resolve())
}).then(() => console.log('Sure did!'))
It doesn't need to be wrapped in a Promise, but doing so allows you to resolve the promise when the script loads, helping prevent race conditions for long-running scripts.
Append script to body:
$(document).ready(function() {
$("<script>", { src : "bootstrap.min.js", type : "text/javascript" }).appendTo("body");
});
Another way you can do it if you want to append code is using the document.createElement method but then using .innerHTML instead of .src.
var script = document.createElement( 'script' );
script.type = 'text/javascript';
script.innerHTML = 'alert("Hey there... you just appended this script to the body");';
$("body").append( script );
I tried this one and works fine. Just replace the < symbol with that \x3C.
// With Variable
var code = "\x3Cscript>SomeCode\x3C/script>";
$("#someElement").append(code);
or
//Without Variable
$("#someElement").append("\x3Cscript>SomeCode\x3C/script>");
You can test the code here.
Can try like this
var code = "<script></" + "script>";
$("#someElement").append(code);
The only reason you can't do "<script></script>" is because the string isn't allowed inside javascript because the DOM layer can't parse what's js and what's HTML.
I wrote an npm package that lets you take an HTML string, including script tags and append it to a container while executing the scripts
Example:
import appendHtml from 'appendhtml';
const html = '<p>Hello</p><script src="some_js_file.js"></script>';
const container = document.getElementById('some-div');
await appendHtml(html, container);
// appendHtml returns a Promise, some_js_file.js is now loaded and executed (note the await)
Find it here: https://www.npmjs.com/package/appendhtml
Just create an element by parsing it with jQuery.
<div id="someElement"></div>
<script>
var code = "<script>alert(123);<\/script>";
$("#someElement").append($(code));
</script>
Working example: https://plnkr.co/edit/V2FE28Q2eBrJoJ6PUEBz
I extensively use the "executeJavaScript(String queryText)" method of the HtmlPage class (HTMLUnit). It works nice, but it does not recognize jQuery or $ symbols inside queryText. I assume I need either initialize the internal jQuery support or include jQuery library. Does anybody know how to do this?
Thank you
Make sure you have script tag that downloads jquery script before you execute that statement. Best place for it is within the head element of the page. Another possibility is that you have another third-party script redefining $ (it's a common thing): then you can try using jQuery in place of $ within your query-text.
String jQueryInjector = 'eval(
function loadJQuery(){
var newJQueryLib = document.createElement("script");
newJQueryLib.type = "text/javascript";
newJQueryLib.src="https://ajax.googleapis.com/ajax/libs/jquery/3.2.1
/jquery.min.js";
(document.getElementsByTagName("head")[0]||document
.getElementsByTagName("body")[0])
.appendChild(newJQueryLib););
loadJQuery();';
ScriptResult sr = page.executeJavaScript(jQueryInjector);
The problem:
I execute this script on the My Saves page of Google Images but it selects only one element.
According to the JQuery Documentation:
Note: most jQuery methods that return a jQuery object also loop through the set of elements in the jQuery collection — a process known as implicit iteration. When this occurs, it is often unnecessary to explicitly iterate with the .each() method:
Which means that my code should work on all the elements which have the specified class. But unfortunately, it is carrying out all of the work only on the first element:
$('.col-cv-select').click();
I have also tried using explicit iteration with the .each() method but the browser console throws an error when I use this script:
$('.col-cv-select').each(function (index, element) { element.click(); });
Uncaught TypeError: $(...).each is not a function(…)
I am sure that the page uses JQuery because the first code works quite well, but only selects one element.
Reproducing the problem:
I think you need to be logged in to Google before proceeding.
Go to Google and search for 'unicorns' (or anything you prefer).
Click on the Images tab.
Select any image. Click on Save in the Pop-up.
Repeat the above step with another image.
Next visit the My Saves page.
Fire up your browser console and try the codes above.
Test Environment:
Opera 37.0.2178.43 - Stable (Since it's based on Chromium, hopefully, using Chrome will yield similar behavior)
Windows 8.1 Pro
Hope you can help me out :) Thanks in advance.
Just because the $ variable is defined doesn't mean that jQuery is loaded on the page.
When you run $('.col-cv-select') on that page you're actually running document.querySelector('.col-cv-select') which by design only returns one element.
The reason you're seeing the TypeError about $(...).each not being a function is because the return value of the first function is a DOM node, not a jQuery object.
You can inject the jQuery library into the page by running this code in the developer console: (Taken and adapted from this page)
(function() {
// more or less stolen form jquery core and adapted by paul irish
function getScript(url) {
var script = document.createElement('script');
script.src = url;
var head = document.getElementsByTagName('head')[0],
done = false;
// Attach handlers for all browsers
script.onload = script.onreadystatechange = function() {
if (!done && (!this.readyState ||
this.readyState == 'loaded' ||
this.readyState == 'complete')) {
done = true;
script.onload = script.onreadystatechange = null;
head.removeChild(script);
}
};
head.appendChild(script);
}
getScript('https://code.jquery.com/jquery.min.js');
})();
Once you execute that code, the $ variable will be aliased to jQuery and you'll be able to use its .each method and everything else that comes with it.
Just remember that once you reload the page the jQuery library will be unloaded, and to load it again you'll need to re-run the code above.
You need to import jquery into your chrome browser before testing
use the following block of code, before calling your test code
var jq = document.createElement('script');
jq.src = "https://ajax.googleapis.com/ajax/libs/jquery/2.1.4/jquery.min.js";
document.getElementsByTagName('head')[0].appendChild(jq);
// ... give time for script to load, then type.
jQuery.noConflict();
I need some scripts inside an existing site's scripts.js.
This site has been online for ages, and I can not touch the scripts file.
I am including it standardly in another page. There are numerous jQuery calls in the scripts file. The place I include it does not have jQuery.
I want to void all $() type things. I tried this...
$ = function() { };
before I included scripts.js and it didn't seem to work. I am still getting errors like
$(document) is undefined
Is there a way to void all these jQuery calls?
Thanks
Even if you do get that working, you'll still have problems because the code was written with the assumption that jQuery was present. Yes, you can avoid $ is null or not defined errors on lines like this:
$('div.foo');
But there's no point in just writing that line: there will always be actions on the returned object:
$('div.foo').html('blah');
After the NOP jQuery function, you'll get a "html" is not a function error, and so on. The only way you could do it would be to fill out a skeleton of every possible jQuery method, making sure each one returns itself when appropriate.
...or just rewrite it properly...
try
window.$ = function(selector, context) {alert('eating the calls to $');}
in your file that you're including before the scripts.js file. This is how it's defined in jquery so should take care of the selector syntax.
You may need to define other overrides to cater for the $.method() type calls tho
Well, it's no surprise that $(document) is undefined, since you're not returning a value from your placeholder function. Thus, things like $(document).ready(function(){}); will naturally be errors.
Basically, if I understand right, you need $ to be a function that does nothing and returns another object where calling any member function does nothing. Further, calling member functions of $ itself (e.g. $.ajax()) should have the same behavior.
You can do this with __noSuchMethod__, which is unfortunately non-standard:
window.$ = function()
{
var doNothingObj = new (function()
{
this.__noSuchMethod__ = function()
{
return doNothingObj;
}
})();
return doNothingObj;
};
window.$.__noSuchMethod__ = window.$;
This will allow arbitrary chains:
$(document).ready(function(){});
$("#foo").animate().animate();
$.ajax({ url: "file.html"});
etc.
Of course, a much saner solution is to refactor the code that uses jQuery.
I recently transferred a site to a new host. Reloaded everything, and the javascript that worked fine before is breaking at an element it can't find. $('#emailForm') is not defined.
Now, the #emailform isn't on the page, but it wasn't before either, and JS used to skip this and it would just work. Not sure why this is happening. Any clues
Here is the site I am having the prblem:
http://rosecomm.com/26/gearwrench/
jQuery will return an empty jQuery object from $('#emailForm') if there isn't an element with the id='emailForm'.
One of the following is likely true:
You forgot to include jQuery - therefore $ is undefined.
There is another library included that uses $ - in which case you can wrap your code in a quick closure to rename jQuery to $
The Closure:
(function($){
// $ is jQuery
$('#emailForm').whatever();
})(jQuery);
You could console.log(window.$,window.jQuery); in firebug to check for both of these problems.
You have mootools-1.2.2-core-yc.js installed as well, and it is conflicting with jQuery.
http://docs.jquery.com/Using_jQuery_with_Other_Libraries
$(document).ready(function() {
(function($){
// bind 'myForm' and provide a simple callback function
$('#emailForm').ajaxForm(function() {
var txt=document.getElementById("formReturn")
txt.innerHTML="<p>Thank You</p>";
});
...
$(document).ready is being called against the moo tools library instead of jQuery.
I'm not sure why it would be skipped before, but to avoid the error, wrap the statement(s) that reference $('#emailForm') in an if statement that checks to see if it is present:
if ( $('#emailForm').length ) {
// code to handle $('#emailForm') goes here...
}