I am looking for way to select element inside of already located element in variable. For example I have selected a container:
let productAttachedFilesModal = document.getElementById('modal_more_information');
I know, that inside are array of a elements, which I want to select as well. Which method should I use? in jQuery there are method find(). So I need the analog for JS.
Or I need to use DOM method again? Like this:
let listOfLinks= document.getElementById('modal_more_information > a');
You should use productAttachedFilesModal.children to get its children, which is the elements inside. It will get you an array of HTML elements.
There are several ways:
let anchors = productAttachedFilesModal.getElementsByTagName("a");
let anchors = document.querySelectorAll("#modal_more_information > a")
let anchors = productAttachedFilesModal.querySelectorAll("a");
You can just query that stored DOM reference:
let productAttachedFilesModal = document.getElementById('modal_more_information');
// Query the stored DOM element for all descendent anchors
let childAnchors = productAttachedFilesModal.querySelectorAll("a");
Related
need to create variables from all elements having id attribute
name of each variable should be just the value of id attribute
for example <div id='btnsave'>SAVE</div> - should be a variable named btnsave
here is my try - without success:
let els = $("*");
els.forEach(function(el){
if(el.hasId()){
console.log(el.attr('id'));
window[el] = $('#' + el);
}
});
If you're using id attributes for your elements then they already have references accessible through the properties of the window object which match their id value:
console.log(window.foo.textContent);
console.log(window.fizz.textContent);
<p id="foo">bar</p>
<p id="fizz">buzz</p>
Given your comment under the question:
I have a lot of divs as buttons and is simpler to write btnsave.on('click'... then $('#btnsave').on('click'...
In that case you simply need to cache the selector at the top of your script (within scope) and use it where required. This is a standard pattern to follow.
Creating jQuery objects from every element in the DOM with an id and storing them in the window object is an anti-pattern, which will cause performance issues and most likely break native code which expects those references to contain DOMElement objects, not jQuery objects.
Do not do it.
To get elements by any attribute you can use query selector.
let elementsWithId = {}
document.querySelectorAll('[id]').forEach(el => {
elementsWithId[el.id] = el
})
console.log(elementsWithId)
You can record a jQuery element to window variable. Example:
window[el.id] = $(el)
But as people mentioned, this is a bad practice.
I am writing a JS, HTML, DOM script ( using Tamper Monkey ) for an ancient website.
The idea is to use bootstrap and format some tables & lists.
These tables, lists etc have no class, id or anything.
So I grab it by tag name and add class name to it.
I could only select 1 tag instance at a time.
Example
document.getElementsByTagName('ul')[0].className = 'list-group';
('ul')[0] gives first instence.
It does not work on just ('ul').
I want to grab every instance of ul at once.
note: I tried document.querySelectorAll('ul').className = '';
Not working. I want to give all ul same class name.
You need to transform the result for querySelectorAll into an array and apply a forEach function on it:
const elementsCollection = document.getElementsByTagName('ul')
const elementsArray = Array.from(elementsCollection)
elementsArray.forEach(el => el.className = 'foo')
Or, if you want to use querySelectorAll:
const elementsArray = document.querySelectorAll('ul')
elementsArray.forEach(el => el.className = 'foo')
I am trying to access child element of an ng-repeat element but I am having troubles doing that.
I have searched around about the problem and the solutions that I have found did not work for me. One of those solutions was to do something like this:
var parent = element(by.repeater(''));
var child = parent.element(by.....);
When I try the child line I cant see the element function on the parent element..
http://prikachi.com/images/11/8338011u.png
If you see the screenshot above you will see the structure of the code of the page that I am trying to test.
I need to access the alt attribute of the image of the avatar and get its value (thats the Username of the User).
One thing that came to my mind is to use .getInnerHTML() on the ng-repeat row which will return a string with all that code. From there I can find the alt attribute and its value with string manipulation but this seems too brute and I am sure that there has to be a better way.
Simply I want to be able to get row 4 from the repeater and get the Username of the user at row 4, that's all I wanna do actually.
Try this,
var parent = element(by.repeater('f in feed'));
var child = parent.all(by.xpath('//img[#alt="Pundeep"]')).first()
(or)
var parent = element(by.repeater('f in feed'));
var child = parent.all(by.xpath('//img[#alt="Pundeep"]')).get(0)
You can get it directly using element.all() and get() locator in protractor. Here's how -
var child = element.all(by.repeater('parent_locator')).get(3); //gets 4th element in repeater. Its a 0 based index.
child.getAttribute('alt').then(function(user){
var username = user; //username contains the alt text
});
Hope this helps.
In Protractor element documentation it gives an example like this to find child elements, which is same as chaining element find:
// Chain 2 element calls.
let child = element(by.css('.parent')).
$('.child');
expect(child.getText()).toBe('Child text\n555-123-4567');
// Chain 3 element calls.
let triple = element(by.css('.parent')).
$('.child').
element(by.binding('person.phone'));
expect(triple.getText()).toBe('555-123-4567');
// Or using the shortcut $() notation instead of element(by.css()):
// Chain 2 element calls.
let child = $('.parent').$('.child');
expect(child.getText()).toBe('Child text\n555-123-4567');
// Chain 3 element calls.
let triple = $('.parent').$('.child').
element(by.binding('person.phone'));
expect(triple.getText()).toBe('555-123-4567');
https://www.protractortest.org/#/api?view=ElementFinder.prototype.$
this example could help :
return element(by.css('select.custom-select:nth-child(1) option[value="12"]'));
you can use nth-child() selector to access to a child element.
In my example i used a plugin with 2 select with same classes and i wanted to click on a defined option in the select 1, and a second in the select 2.
I have a string containing html elements, now I need to select some elements and remove them from the string.
In JQuery I tried the following:
html_string = "<ul><li data-delete>A<li><li>B</li></ul>";
html_clean_string = $(html_string).remove('[data-delete]').html();
This is what I expected:
"<ul><li>B</li></ul>"
But I got the same original string. So how can I use CSS selectors to remove html elements from a string?
You can do it like this:
var html_string = "<ul><li data-delete>A</li><li>B</li></ul>";
var elems = $(html_string);
elems.find('[data-delete]').remove();
var html_clean_string = elems[0].outerHTML;
You had a couple of issues:
.remove() only operates on the elements in the jQuery object, not on child object so you have to .find() the appropriate child elements before you can remove them.
Since you want the host top level HTML too, you will need the .outerHTML.
You had mistakes in your html_string.
Working jsFiddle: http://jsfiddle.net/jfriend00/x8ra6efz/
You can also save a little jQuery with more chaining like this:
var html_string = "<ul><li data-delete>A</li><li>B</li></ul>";
var html_clean_string = $(html_string).find('[data-delete]').remove().end()[0].outerHTML;
Working jsFiddle:http://jsfiddle.net/jfriend00/wmtascxf/
Is there a better way to get the parent of the parent of the parent... like 5 times?
So Instead of using this:
$(this).parent().parent().parent().parent().parent()
I could use something like this:
$(this).goBacktoNthParent(5);
Is it possible?
Using the :eq() selector
The :eq() selector allows you to target the element at the zero-based index of the set that was matched...
$(this).parents(':eq(4)')
Note: use parent(s) selector
Because the selector is zero based, we gave it one less than the number targeted.
DEMO: http://jsfiddle.net/pmMFv/
Using the .eq() method
The .eq() method is effectively the same as its selector counterpart, allowing you to target the element at the zero-based index of the set that was matched...
$(this).parents().eq(4)
Note: use parent(s) selector
DEMO: http://jsfiddle.net/pmMFv/2/
Using parentNode in a loop
For greatest performance, we could use the .parentNode property of the element, and run it in a loop, updating a variable with the newest parent each time...
var el = this, i = 5;
while(i-- && (el = el.parentNode));
$(el)
DEMO: http://jsfiddle.net/pmMFv/1/
You can easily create your own function:
function getNthParentOf(elem,i) {
while(i>0) {
elem = elem.parent();
i--;
}
return elem;
}
var something = getNthParentOf($(this),5);
You can use the .parents traversing function in conjunction with the :nth() selector.
So the result will be something like:
$(this).parents(':nth(5)'));
Notice: the :nth() index starts from 0 so for your case it should be:
$(this).parents(':nth(4)'));
If there are identifying markers on the parent element you want to get - such as an id or class you can use $(this).closest("#grandparentElement")
Hope, this would be of any help.
try using .parentsUntil()
working example: http://jsfiddle.net/ylokesh/wLhcA/
Well you can try
var parentControl = $('#yourcontrol').parent();
var grandParent = parentControl.parent();