Please bear with me; Im very new to JS- as in barely started a beginners course.
I know this is possible in html, but I want to know if its doable in js.
var a = document.createElement('a');
const link = document.querySelector(`.logoImg`);
a.href(link) = `https://website.com`;
Sorry if this is infuriatingly simple but I can't seem to see where i'm going wrong, thanks in advance!
EDIT: .logoImg is a class that already exists, that I want to add the link to.
var a = document.createElement('a'); gives you an element (a brand new <a> that isn't attached to the DOM yet).
const link = document.querySelector(`.logoImg`); also gives you an element (assuming that the selector matched something in the document) which is already in the DOM.
Now you have two variables pointing to two different elements.
You probably only want one of those two lines. Which one depends on which of the elements you want to modify.
a.href(link) is nonsense. It takes the href of the newly created element (off the top of my head I can't remember if it is undefined or '' by default) and tries to execute it as a function (passing link as an argument). Neither undefined nor '' is a function so this will error.
You need a.href = or link.href = depending on which element you want modify the href property of.
Things get more complicated if the element with class="logoImg" isn't a <a> but something else that you want to put inside a new <a>.
Related
I'm writing a chrome extension, part of the functionality of which requires me to hide every html element at times with the exception of one div which I've created. (I hide everything and add the div to the current website in javascript) Because setting document.body.style.display = "none" will not allow any of the body's children to be seen, I need to add the child that I want to be seen somewhere else. (I also tried using style.visibility but for some reason that didn't hide certain HTML elements/backgrounds on certain pages.) My fix is to add the div to document.documentElement, outside of document.body. This fix actually works perfectly, but seems strange. Is there anything wrong with adding a new child to the elements? Am I doing something wrong?
EDIT: A few answers have used the children of document.body, so I thought I should note that my code has to run at document_start, and though I wait for document.body to load before executing, I can't wait for all of its children to load. Hence I can't use/store the children of document.body.
Also, I'm grateful for all the answers providing alternate solutions, they're quite useful. But out of curiosity, does anybody know if there's anything wrong with what I'm currently doing? Why is it working, if so?
The W3C specification of HTML document structure says that it consists of the <head> and <body> elements, and the <body> contains the content that's intended to be rendered. Nothing is stated about elements outside these two elements.
If it seems to work it's probably just an accident of implementation -- for instances, many implementations are forgiving of things like malformed HTML.
It's perfectly fine to append elements or text nodes directly to document.documentElement.
DOM is not HTML, it has its own specification, which - being an Object Model - is naturally quite permissive:
document.documentElement is an Element [spec]:
The document element of a document is the element whose parent is that document, if it exists, and null otherwise.
Elements are allowed to have these children [spec]:
Zero or more nodes each of which is Element, Text, ProcessingInstruction, or Comment.
Create a new DIV to hold the children of the body, and hide that.
var saveDiv = document.createElement("DIV");
saveDiv.id = "saveDiv";
saveDiv.style.display = "none";
Array.from(document.body.children).forEach(el => saveDiv.appendChild(el));
document.body.appendChild(saveDiv);
A potential solution:
const body = document.querySelector('body');
body.innerHTML = `<div class="my-div"></div><div class="content">${body.innerHTML}</div>`;
Now you have the body content all snug alongside your div, both of which you can hide/show. As pointed out below, I completely spaced that this will destroy your listeners. If you want to preserve listeners, try the following:
const body = document.querySelector('body');
const fragment = document.createDocumentFragment();
const hideBody = () => {
for (let el of [...body.children]) (fragment.append(el))
}
const showBody = () => {
for (let el of [...fragment.children]) (body.append(el))
}
Attach the appropriate one to whatever your event is. This will preserve all your listeners. If you need any functionality, DocumentFragment has the querySelector() and querySelectorAll() methods.
Another method is the modal method, where you just have a div that covers the whole page. Check out the Bootstrap modals, for example. If you initialize it with data-backdrop="static" and data-keyboard="false" then it won't disappear by clicking outside or hitting esc. The element can be selected with document.querySelector('.modal-backdrop'). Set the opacity to 1 and the background to white or whatever aesthetic you're going for.
Trying to learn some Javascript now that I have a few months of Python under my belt. Having trouble with HTML elements on a page which uses Javascript (not sure that is the right wording).
I have a simple Chrome Extension which I am trying to tell it to click a button when the page loads.
The DOM shows this code more or less:
<body class="skin-mark toolbar-open table-active">
<div class="tile-tables"></div>
</body>
My attempt at clicking the button has been multiple ways similar to this:
document.querySelector('#tile-tables').click();
Any help in understanding the process here and what I am doing wrong would be great! Thanks in advance! Feel free to correct me at any place and I will fix my language.
When you use getElementById you have to pass an element's id to it. There is only one element with an id in your HTML, the outer userActActions-51 - so, if you were to select by ID first, you would do
document.getElementById('userActActions-51')
and then you would access the second nested child:
const userActions = document.getElementById('userActActions-51');
const span = userActions.children[0].children[0];
span.click();
But it would be more convenient to use querySelector for this, which will allow you to use a selector string to select the span descendant of the element with the id userActActions-51 at once:
document.querySelector('#userActActions-51 span').click();
If the element might not exist, then make sure that it exists before trying to click on it:
const span = document.querySelector('#userActActions-51 span');
if (span) span.click();
In a nutshell I'm trying to target an element within the DOM, then inject a class on the fly to later alter that element.
The situation is as follows, I am working with an application that has predetermined mark up (Manage Engine). It's a tool for system work flows, creating a centralized portal for ticket logging, asset management blah blah. So I use the tool to create templates for end users to log service requests. This is accessed via a web interface portal which in turn obviously has mark up.
So far I have been able to alter specific things such as background colors on table headers for example. I achieve this by creating a rule to fire within that template upon load time. So essentially I am allowing the template to load with its predetermined code and then I am applying a for loop to alter the code once it has loaded. (Hacky I know, however its working really well).
The issue I'm running into now is that certain things within the mark up are generic (no class or id associated to the element). My plan is to target that specific generic element as a variable then add my own class to it upon load. Is there a way to target an element that has a class and then target the child elements within, save that child as a variable to then add a class on the fly with javascript. Please see example below.
<tr class=test1>
<td>
<input>
<input>
<input>
</td>
<tr/>
So with the example above what I am trying to achieve is add my own class with JavaScript to the <td> element. Obviously if i target just <td> it will alter all <td> elements within the markup. Can i get to that specific <td> via the <tr> parent with the test1 class. I am currently unable to use any jquery requests as the base code can not be touched.
Again I know this is a little backwards and hacky but it does work with anything I can specifically target (has a class or id). I need to be able to do this with pure JavaScript. Any suggestions or help is greatly appreciated, apologies if this is a noob approach or question, first time posting in a forum. Let me know if further examples or information is required.
document.querySelector("body").children can get all child elements of body
step1: Select the class. The variable t1 will contain an Array of tr elements.
var t1 = document.querySelector('.test1');
step2: Get the first value from the array t1. So, tr_el1 contains one tr element.
var tr_el1 = t1[0];
step3: Get the children of tr. td_el contains an Array of td elements.
var td_el = tr_el1.children;
Now you can use the td from the td_el array
var tr = document.getElementsByClassName('test1')[0]
var td = tr.children[0]
var inputs = Array.prototype.slice.apply(td.children)
Now you got your inputs inside an array. You're welcome ;-)
Thanks a lot for the assistance, really appreciate it. The examples above helped me build a hybrid that although not exact has given me the outcome i needed.
var parent = document.querySelector(".roweven").children;
var nS;
for (nS = 0; nS < parent.length; nS++) {
parent[nS].style.position = "absolute";
parent[nS].style.width = "100%";
}
I am yet to wrap this up in a function but working as intended. Thanks again :) :)
This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
jquery select iframe children
I have many frames in my asp.net website. Since I don't know its layout and I need to update a <span> value in a diferent diferent frame where my jquery code is, I do the following:
$('#myspan').text('sometext');
but anything changes. So I don't know if it's because jquery didn't manage to catch the element with this selector because is not in its scope or why.
However this:
alert($('#myspan')); it shows an alert with [object][object] as result.
The jQuery function ($('someSelector')) will always return an object, even if no elements match the selector.
If you really are using multiple frames, you have a problem: jQuery can't find elements across frames, only in the current document/frame – unless you pass a proper context object for the specific document you want to target.
For example, if you have an <iframe id="myframe">, you can look for #myspan inside it with this:
var frameDoc = $('#myframe')[0].contentWindow.document;
var mySpan = $('#myspan', frameDoc);
For that to work, the iframe's source must be hosted in the same domain as the main page. There's also the following cleaner options, suggested in the comments below:
var mySpan = $("#myframe").contents().find('#myspan')
or
var mySpan = $('#myspan', $("#myframe").contents());
A good way to debug jQuery problems is this pattern:
var e = $(...);
console.log(['Explanation', e.get()]);
get() without arguments will convert the strange jQuery selector result to a normal JavaScript array which you can expand in your browser's console. That should help to see what the selector returned.
If it doesn't match anything, then your selector is wrong somehow. Check the current DOM in your browser's development tools if the element is really there.
So, say I have selected, in JQuery, a singular DOM div.
I then proceed to create a new DIV like so:
var DIV = $("<div>Hello, world</div>");
After that, I attempt to place that DIV inside the original one like so:
$(OriginalDiv).append(DIV);
Okay, that works.
Now I want to edit DIV further.
Calls to .click, .html, .addClass, (And likely more) do not work!
Okay, instead I do:
var OriginalDiv = $("someSelector");
var DIV = $("<div>Hello, world</div>");
DIV = $(OriginalDiv).append(DIV);
That appears to work at first; However, instead, it sets DIV to reference the same DOM object as OriginalDiv and NOT the newly appended DOM object. Naturally, this does not allow me to edit DIV.
So, then, I try two more methods:
var OriginalDiv = $("someSelector");
var DIV = $("<div>Hello, world</div>");
$(DIV).appendTo(OriginalDiv);
and
var OriginalDiv = $("someSelector");
var DIV = $("<div>Hello, world</div>");
DIV = $(DIV).appendTo(OriginalDiv);
Not even these work.
If I haven't done a very good job explaining, here is my exact dilemma
I am trying to create a DOM object in jquery, then append it to another DOM object using jquery. The problem is, once it gets appended, there seems to be no way for me to directly access it without using somethign like .children.
I'd like very much to be directly returned somewhere along in that process a reference to the DOM object which I am appending. As in the one that actually gets appended.
I'm not sure how to do this in JQuery. Anybody know a solution?
Thanks
--G
Yes, append won't work as it returns a reference to the element the new element was appended to. jQuery supports method chaining, so this should work easily:
$("<div>Hello, world</div>")
.click(function() {
// something
})
.appendTo('someSelector');
But even
var $ele = $("<div>Hello, world</div>").appendTo('someSelector');
will work. appendTo returns a reference to the element which was appended. If this does not work for you, you have your problem elsewhere.
Comments on your code: This is not your problem, however it is important for you to know what is going on here.
This part
var OriginalDiv = $("someSelector");
var DIV = $("<div>Hello, world</div>");
$(DIV).appendTo(OriginalDiv);
is the same as
$($("<div>Hello, world</div>")).appendTo($("someSelector"));
You see, you have a nested call to jQuery, because DIV is already a jQuery object. There is no need to pass it again to jQuery.
You can also pass a selector directly to appendTo.
you could try this;
var DIV = document.createElement('div');
then you can use;
$(div).html('Test!');
or what ever you want to use with.
You don't have to get anything back from the DOM. Once you create the element with jQuery, you already have a reference to the DOM element. Inserting it into the document does not do anything special.
// this will create the DOM element, and the jQuery
// object wrapping that newly created DOM object
// is assigned to DIV.
var DIV = $("<div>Hello, world</div>");
// Don't worry about getting a return value from this
// append() call. What we need is already available inside
// the variable DIV.
$(OriginalDiv).append(DIV);
// continue using DIV as you normally would. It is referring
// to the same DOM object that was just appended to the document.
DIV.addClass('green');