I'm trying to write some JavaScript that once the page has finished loading will create a div in the place where the is placed.
Here is a stripped-back version of the code...
window.addEventListener('load', function () {
var content = document.createElement('div');
content.id = 'div-ID';
document.getElementsByTagName('body')[0].appendChild(content);
});
It works outside of the addEventListener(), however, when inside the event listener it always puts the created div below the rest of the page content not in the place the <script> tag is placed.
I'm certain the issue is to do with this line...
document.getElementsByTagName('body')[0].appendChild(content);
I need an alternative version to this which doesn't appendChild() but my JS isn't that good and everything I've tried hasn't worked.
Its most likely simple to achieve, I've tried searching Google and Stack Overflow but my search terms don't seem to be producing the desired results.
Any help on this would be much appreciated
You could do it with Node.insertBefore
As such, your code would be something like:
document.body.insertBefore( content, document.body.childNodes[0] );
The second parameter is the referenceNode, that has following comment:
referenceNode is not an optional parameter -- you must explicitly pass a Node or null. Failing to provide it or passing invalid values may behave differently in different browser versions.
I'm trying to get the value of a textarea with Shopify Product Options by Bold and it is currently not working. I am able to get the value of a textarea locally, but I can not get the value when I move the code over to Shopify. I have looked here and here to no avail.
Here's the relevant code:
document.getElementById("248832").onkeyup=function(){getVal()};
var textbox = document.getElementsByName("properties[Message Body]")[0].value;
and here's the textarea I'm trying to get the value of
<textarea data-option-key="ta_248832" id="248832" class="bold_option_child shapp_full_width " name="properties[Message Body]"></textarea>
When I try to run this on Shopify, I get an error saying "Uncaught TypeError: Cannot set property 'onkeyup' of null", although I did notice that at one point shopify runs the following jQuery code, which might be what's causing my problem:
<script>
jQuery('#248832').change(function (){conditional_rules(7437760391);})
</script>
I am trying to get the value of the textarea so I can run get the amount of words in said textarea.
Any help would be greatly appreciated!
Look to see if the element that is returned as null has loaded yet. Others in similar situations fixed this by loading the script last. Hope this is helpful :)
https://stackoverflow.com/a/25018299/1305878
https://stackoverflow.com/a/31333349/1305878
https://stackoverflow.com/a/23544789/1305878
Solution
You are trying to use something similar to jQuery methods without jQuery:
document.getElementById("248832").onkeyup=function(){getVal()};
while DOM elements don't have the onkeyup method. It should be
jQuery("#248832").on("keyup",function(){getVal()});
Extra notes
even without using the recommended '.on' method, you have to write it as
jQuery("#248832").keyup(function(){getVal()});
(docs), not as
jQuery("#248832").onkeyup(function(){getVal()});
If you'd like to use DOM methods, that would be
document.getElementById("248832").addEventListener("keyup",function(){getVal()});
Also, may be you have wrote this as a minimal example, but the fact that you only call getVal() and don't pass the value somewhere sounds strange, although I don't know if what getVal() does exactly.
I am using CKEditor for my website's blog posts but have an issue where after loading all the bog posts via .load() they no longer get replaced by CKEditors.
This is done example:
$("#container #postholder").load("http://url.com/viewblog.php?id=155 #container #postholder");
First, I had issues with the scripts that were called upon by items that were loaded via the .load() method. I solved this by changing the button call to this:
$(document).on('click','.edity',function(){ });
The buttons now work, but the CKEditor isnt.
Lets say I have 5 different instances that are on the page, they all have the generic class of ckeditor so they all work.
However, after the .load() of the items, they are not changed to CKEditors and instead stay text areas.
To solve this I tried this when clicking the 'edit' button:
$(document).on('click','.edity',function(){
CKEDITOR.replace('.ckeditor');
});
That does not work, I then tried using the name of the CKEditors so:
$(document).on('click','.edity',function(){
CKEDITOR.replace('editorName');
});
This works, even after the .load(), but it only works for the first instance. All of the other CKEditors are not changed into the CKEditor.
I cant see how to get around this...
Any one understand?
Editors are created like so:
This is in a foreach loop for each blog post result. The ckEID variable is the posts ID + 1.
<div class="editor">
<textarea name="muffin" id="'.$ckEID.'" class="ckeditor">'.$text.'</textarea>
</div>
I use this:
$(document).on('click','.edity',function(){
$(this).parent().find('.editor').toggle();
CKEDITOR.replace('ckeditor');
});
To convert the text area when the edit button is clicked.
Just tried using replaceAll and the error console showed e.g.
uncaught exception: The editor instance "message" is already attached to the provided element.
I have other text areas on the page and it seems that everything is getting messed up when using replaceAll.
Can't seem to get this one to work...
I have a page that hides certain links. When the DOM is loaded, I'm using jQuery to toggle some of those elements. This is driven by using a data attribute like so:
<div class="d_btn" data-usr='48'>
<div class="hidden_button">
Then, I have the code:
$.each($(".d_btn"), function() {
var btn = $(this).data('usr');
if ( btn == '48' ){
$(this).children('.hidden_button').toggle();
}
The above all works as planned. The problem is that I am trying to remove the data-usr from the class .d_btn once the if statement is evaluated. I've tried the following and nothing works (i.e., after the page is loaded, the source still shows the data-usr attribute:
$(this).removeAttr("data-usr");
$(this).removeData("usr");
I've been working on this for a couple of hours now and...nothing! Help is greatly appreciated!
UPDATE
I've tried the great suggestions of setting the data attribute to an empty string but I'm still not getting the desired result.
To explain a little further, The reason I'm trying to remove the attribute is so when an ajax response adds another item to the page, the previously added items would already have the button either shown or hidden. Upon AJAX response, I'm calling the same function once the DOM is loaded.
Currently, when something is added via AJAX, it toggles all the buttons (showing the ones that were hidden and vice versa.) Ugh...
I'm also fully willing to try alternatives to my approach. Thanks!
UPDATE
Well, the light bulb just flashed and I am able to do what I want to do by just using .show() instead of .toggle()
Anyway, I'd still like to find an answer to this question because the page will be potentially checking hundreds of items whenever something is added - this seems horribly inefficient (even for a computer, hahaha.)
Why don't you set the value to a random value or empty variable instead if removeAttr does not work..
$(this).attr("data-usr" , '');
$(this).prop("data-usr" , '');
Changing the DOM doesn't affect the source. It affects the DOM, which you can view with the Inspector/Developer Tools. Right click => View Source will give you the original source of the page, not the actual current source as modified by JavaScript.
Set it to a blank string:
$(this).attr("data-usr", "");
I second what Kolink said: check the DOM, not the source. (Chrome: Ctrl + Shift + i).
As others have stated. Checking the source will only show the original unedited source for the webpage. What you need to do is check the DOM using developer tools.
I've just checked everything in Chrome's inspector on jsfiddle here and the attribute is definitely being removed as well as the data.
How exactly does it relate to jQuery? I know the library uses native javascript functions internally, but what exactly is it trying to do whenever such a problem appears?
It means you've tried to insert a DOM node into a place in the DOM tree where it cannot go. The most common place I see this is on Safari which doesn't allow the following:
document.appendChild(document.createElement('div'));
Generally, this is just a mistake where this was actually intended:
document.body.appendChild(document.createElement('div'));
Other causes seen in the wild (summarized from comments):
You are attempting to append a node to itself
You are attempting to append null to a node
You are attempting to append a node to a text node.
Your HTML is invalid (e.g. failing to close your target node)
The browser thinks the HTML you are attempting to append is XML (fix by adding <!doctype html> to your injected HTML, or specifying the content type when fetching via XHR)
If you are getting this error due to a jquery ajax call $.ajax
Then you may need to specify what the dataType is coming back from the server. I have fixed the response a lot using this simple property.
$.ajax({
url: "URL_HERE",
dataType: "html",
success: function(response) {
$('#ELEMENT').html(response);
}
});
Specifically with jQuery you can run into this issue if forget the carets around the html tag when creating elements:
$("#target").append($("div").text("Test"));
Will raise this error because what you meant was
$("#target").append($("<div>").text("Test"));
This error can occur when you try to insert a node into the DOM which is invalid HTML, which can be something as subtle as an incorrect attribute, for example:
// <input> can have a 'type' attribute
var $input = $('<input/>').attr('type', 'text');
$holder.append($input); // OK
// <div> CANNOT have a 'type' attribute
var $div = $('<div></div>').attr('type', 'text');
$holder.append($div); // Error: HIERARCHY_REQUEST_ERR: DOM Exception 3
#Kelly Norton is right in his answer that The browser thinks the HTML you are attempting to append is XML and suggests specifying the content type when fetching via XHR.
It's true however you sometimes use third party libraries that you are not going to modify. It's JQuery UI in my case. Then you should provide the right Content-Type in the response instead of overriding the response type on JavaScript side. Set your Content-Type to text/html and you are fine.
In my case, it was as easy as renaming the file.xhtml to file.html - application server had some extension to MIME types mappings out of the box. When content is dynamic, you can set the content type of response somehow (e.g. res.setContentType("text/html") in Servlet API).
You can see these questions
Getting HIERARCHY_REQUEST_ERR when using Javascript to recursively generate a nested list
or
jQuery UI Dialog with ASP.NET button postback
The conclusion is
when you try to use function append, you should use new variable, like this example
jQuery(function() {
var dlg = jQuery("#dialog").dialog({
draggable: true,
resizable: true,
show: 'Transfer',
hide: 'Transfer',
width: 320,
autoOpen: false,
minHeight: 10,
minwidth: 10
});
dlg.parent().appendTo(jQuery("form:first"));
});
In the example above, uses the var "dlg" to run the function appendTo.
Then error “HIERARCHY_REQUEST_ERR" will not come out again.
I encountered this error when using the Google Chrome extension Sidewiki. Disabling it resolved the issue for me.
I'm going to add one more specific answer here because it was a 2 hour search for the answer...
I was trying to inject a tag into a document. The html was like this:
<map id='imageMap' name='imageMap'>
<area shape='circle' coords='55,28,5' href='#' title='1687.01 - 0 percentile' />
</map>
If you notice, the tag is closed in the preceding example (<area/>). This was not accepted in Chrome browsers. w3schools seems to think it should be closed, and I could not find the official spec on this tag, but it sure doesn't work in Chrome. Firefox will not accept it with <area/> or <area></area> or <area>. Chrome must have <area>. IE accepts anything.
Anyway, this error can be because your HTML is not correct.
I know this thread is old, but I've encountered another cause of the problem which others might find helpful. I was getting the error with Google Analytics trying to append itself to an HTML comment. The offending code:
document.documentElement.firstChild.appendChild(ga);
This was causing the error because my first element was an HTML comment (namely a Dreamweaver template code).
<!-- #BeginTemplate "/Templates/default.dwt.php" -->
I modified the offending code to something admittedly not bulletproof, but better:
document.documentElement.firstChild.nodeType===1 ? document.documentElement.firstChild.appendChild(ga) : document.documentElement.lastChild.appendChild(ga);
If you run into this problem while trying to append a node into another window in Internet Explorer, try using the HTML inside the node instead of the node itself.
myElement.appendChild(myNode.html());
IE doesn't support appending nodes to another window.
This ERROR happened to me in IE9 when I tried to appendChild an dynamically to a which already existed in a window A. Window A would create a child window B. In window B after some user action a function would run and do an appendChild on the form element in window A using window.opener.document.getElementById('formElement').appendChild(input);
This would throw an error. Same with creating the input element using document.createElement('input'); in the child window, passing it as a parameter to the window.opener window A, and there do the append. Only if I created the input element in the same window where I was going to append it, it would succeed without errors.
Thus my conclusion (please verify): no element can be dynamically created (using document.createElement) in one window, and then appended (using .appendChild) to an element in another window (without taking maybe a particular extra step I missed to ensure it is not considered XML or something). This fails in IE9 and throws the error, in FF this works fine though.
PS. I don't use jQuery.
Another reason this can come up is that you are appending before the element is ready e.g.
<body>
<script>
document.body.appendChild(foo);
</script>
</body>
</html>
In this case, you'll need to move the script after the . Not entirely sure if that's kosher, but moving the script after the body doesn't seem to help :/
Instead of moving the script, you can also do the appending in an event handler.
I got that error because I forgot to clone my element.
// creates an error
clone = $("#thing");
clone.appendTo("#somediv");
// does not
clone = $("#thing").clone();
clone.appendTo("#somediv");
Just for reference.
IE will block appending any element created in a different window context from the window context that the element is being appending to.
e.g
var childWindow = window.open('somepage.html');
//will throw the exception in IE
childWindow.document.body.appendChild(document.createElement('div'));
//will not throw exception in IE
childWindow.document.body.appendChild(childWindow.document.createElement('div'));
I haven't figured out how to create a dom element with jQuery using a different window context yet.
I get this error in IE9 if I had disabled script debugging (Internet Explorer) option. If I enable script debugging I don't see the error and the page works fine. This seems odd what is the DOM exception got to do with debugging either enabled or disabled.