Is Greasemonkey not capable of using jQuery's full power? - javascript

I'm trying to find an element using jQuery, but it is not working.. I found out that this kind of selector can't be done in Greasemonkey:
($("#app7019261521_hover_container > [id^=app7019261521_the_coin]"))
Please help me translate this into raw Javascript. This kind of selector is hardcore to do in Javascript. Please help me Javascript gurus!

This should do it, and now I remember why I started using jQuery:
var children = document.getElementById('app7019261521_hover_container').childNodes;
var ids = []; //to store the IDs of all matching elements
for(var i = 0; i < children.length; i++)
{
//indexOf returns zero is subject starts with passed string
if(children.item(i).id.indexOf('app7019261521_the_coin') == 0)
{
alert('Got One!');
ids.push(children.item(i).id);
}
}

Since you are targeting directly to Firefox, you may want to give a look to the Selectors API implemented on Firefox 3.5.
Check the document.querySelectorAll function:
var elements = document.querySelectorAll("#app7019261521_hover_container > [id^=app7019261521_the_coin]")

Related

Onclick doesn't work in userscript [duplicate]

I am trying to run a function onclick of any button with class="stopMusic". I'm getting an error in Firebug
document.getElementByClass is not a function
Here is my code:
var stopMusicExt = document.getElementByClass("stopButton");
stopButton.onclick = function() {
var ta = document.getElementByClass("stopButton");
document['player'].stopMusicExt(ta.value);
ta.value = "";
};
You probably meant document.getElementsByClassName() (and then grabbing the first item off the resulting node list):
var stopMusicExt = document.getElementsByClassName("stopButton")[0];
stopButton.onclick = function() {
var ta = document.getElementsByClassName("stopButton")[0];
document['player'].stopMusicExt(ta.value);
ta.value = "";
};
You may still get the error
document.getElementsByClassName is not a function
in older browsers, though, in which case you can provide a fallback implementation if you need to support those older browsers.
Before jumping into any further error checking please first check whether its
document.getElementsByClassName() itself.
double check its getElements and not getElement
As others have said, you're not using the right function name and it doesn't exist univerally in all browsers.
If you need to do cross-browser fetching of anything other than an element with an id with document.getElementById(), then I would strongly suggest you get a library that supports CSS3 selectors across all browsers. It will save you a massive amount of development time, testing and bug fixing. The easiest thing to do is to just use jQuery because it's so widely available, has excellent documentation, has free CDN access and has an excellent community of people behind it to answer questions. If that seems like more than you need, then you can get Sizzle which is just a selector library (it's actually the selector engine inside of jQuery and others). I've used it by itself in other projects and it's easy, productive and small.
If you want to select multiple nodes at once, you can do that many different ways. If you give them all the same class, you can do that with:
var list = document.getElementsByClassName("myButton");
for (var i = 0; i < list.length; i++) {
// list[i] is a node with the desired class name
}
and it will return a list of nodes that have that class name.
In Sizzle, it would be this:
var list = Sizzle(".myButton");
for (var i = 0; i < list.length; i++) {
// list[i] is a node with the desired class name
}
In jQuery, it would be this:
$(".myButton").each(function(index, element) {
// element is a node with the desired class name
});
In both Sizzle and jQuery, you can put multiple class names into the selector like this and use much more complicated and powerful selectors:
$(".myButton, .myInput, .homepage.gallery, #submitButton").each(function(index, element) {
// element is a node that matches the selector
});
It should be getElementsByClassName, and not getElementByClass. See this - https://developer.mozilla.org/en/DOM/document.getElementsByClassName.
Note that some browsers/versions may not support this.
My solutions is:
Change:
document.getElementsByClassName('.className')
To:
document.querySelector('.className')
you spelt it wrongly, it should be " getElementsByClassName ",
var objs = document.getElementsByClassName("stopButton");
var stopMusicExt = objs[0]; //retrieve the first node in the stack
//your remaining function goes down here..
document['player'].stopMusicExt(ta.value);
ta.value = "";
document.getElementsByClassName - returns a stack of nodes with more than one item, since CLASS attributes are used to assign to multiple objects...
it should be getElementsByClassName NOT getElementByClassName ==> you missed "s" in Elements
const collectionItems = document.getElementsByClassName('.item');
document.querySelectorAll works pretty well and allows you to further narrow down your selection.
https://developer.mozilla.org/en-US/docs/Web/API/Document/querySelectorAll
document.getElementByClass is not a function
Yes, it is not a function nor method because it should be document.getElementsByClassName
enter code here
var stopMusicExt = document.getElementByClass("stopButton").value;
stopButton.onclick = function() {
var ta = document.getElementByClass("stopButton");
document['player'].stopMusicExt(ta.value);
ta.value = "";
};
// .value will hold all data from class stopButton
The getElementByClass does not exists, probably you want to use getElementsByClassName. However you can use alternative approach (used in angular/vue/react... templates)
function stop(ta) {
console.log(ta.value) // document['player'].stopMusicExt(ta.value);
ta.value='';
}
<input type="button" onclick="stop(this)" class="stopMusic" value='Stop 1'>
<input type="button" onclick="stop(this)" class="stopMusic" value='Stop 2'>
If you wrote this "getElementByClassName" then you will encounter with this error "document.getElementByClass is not a function" so to overcome that error just write "getElementsByClassName". Because it should be Elements not Element.

What is by.js locator for in Protractor/WebDriverJS?

Recently, I've noticed a new locator being added to the Protractor documentation - the by.js():
Locates an elements by evaluating a JavaScript expression, which may be either a function or a string.
I understand what this locator provides, but I am missing the real-world use cases when this locator can be useful. When should I prefer to use by.js instead of other built-in locators like by.css?
I feel the use case is to get elements using core javascript functions, whenever css and other element locators won't help or are don't have properties that we could use. Scenarios -
If you are getting an element using core javascript functions passing it to browser.executeScript then by.js can be used to replace it.
Example: -
Suppose if you had to get an element that appears on top between the two, you could get it this way -
var ele = element(by.js(function(){
var ele1 = document.getElementById('#ele1');
var ele2 = document.getElementById('#ele2');
var val = ele1.compareDocumentPosition(ele2);
if(val === 4) return ele1;
else return ele2;
}));
If you want to get element using its css values like color, font, etc... Though filter can be used in this case, but by.js also supports it.
If the elements are not accessible by css or xpath or any other locators, for example pseudo-elements that have animations or transitions.
Example: -
Suppose if there's element which has :before and :after transitions -
.element:before {
color: rgb(255, 0, 0);
}
To verify the color of the element, we could use by.js passing in a javascript statement to get the element -
var ele = element(by.js(function(){
return window.getComputedStyle(document.querySelector('.element'), ':before');
}));
expect(ele.getCssValue('color')).toEqual('rgb(255, 0, 0)');
Hope it helps.
I think the cases for this are pretty slim, but I can see this being of use when there's data on the client that is not available (or unreliably so) through selenium.
The example on the docs page includes a reference to offsetWidth:
spans[i].offsetWidth > 100
Used in context:
var wideElement = element(by.js(function() {
var spans = document.querySelectorAll('span');
for (var i = 0; i < spans.length; ++i) {
if (spans[i].offsetWidth > 100) {
return spans[i];
}
}
}));
expect(wideElement.getText()).toEqual('Three');
Alternatively, there may be a use case if there's a third party API on the window or some other service that can help locate an element.

Finding the index of the element with class in native Javascript

Is there a way to get the index of class name (I.e. the third element with the class "className" would be 3 without using jQ?
I don't know jQ, and I don't have time to learn it right now, and I don't want to include code into my code that I don't understand at least some.
Thanks.
BTW, I've used jQ instead of spelling it out so those results can be filtered out in Google should somebody have the same question. If I spelled it out, and somebody used the NOT operator in Google, this one would also disappear.
You could do something like:
// the element you're looking for
var target = document.getElementById("an-element");
// the collection you're looking in
var nodes = document.querySelectorAll(".yourclass");
var index = [].indexOf.call(nodes, target);
See: Array's indexOf.
If you have already a proper array as nodes instead of a NodeList, you can just do nodes.indexOf(target).
you can use document.getElementsByClassName
var el = document.getElementsByClassName('className');
for (var i = 0; i < el.length; i++) {
// your index is inside here
}
el[i] is the element in the current iteration, i is the index
(I.e. the third element with the class "className" would be 3)
if (i == 3)
return el[i]
JsFiddle: here.
Just use getElementsByClassName, it returns a list of elements with the specified classes.
elements = document.getElementsByClassName("test")
element = elements[2] //get the 3rd element
Hope this helps!
these work as of es6:
Array.from(document.querySelectorAll('.elements')).indexOf(anElement)
or
[...document.querySelectorAll('.elements')].indexOf(anElement)

Prepend some innerHTML to a div in Native Javascript

Please bear with me on this question; I have only recently started coding in Javascript and for this reason I would like a strong foundation before breaking into jQuery.
I have the following Javascript code:
var app = {
text: document.getElementById('text'),
output: document.getElementById('output'),
createDiv: document.createElement('div')
};
function postData(){
app.output[0].appendChild(app.createDiv.firstChild);
app.createDiv.classname = 'text';
document.getElementsByClassName('username').innerHTML += app.text.value;
}
onClick I want the value of app.text to print (using innerHTML) ABOVE the output div. Any ideas or questions? Sorry if I am being vague or not making sense, I have been staring at this for 4 hours now and am probably just burned out!
You'll have to create a text node and insert it before each element in the NodeList returned by document.getElementsByClassName:
var node = document.createTextNode(app.text.value);
var elements = document.getElementsByClassName('username');
for (var i = 0; i < elements.length; i++) {
var elem = elements[i];
elem.parentNode.insertBefore(node.cloneNode(), elem)
}
And just to tempt you with the jQuery version:
$('.username').before(app.text.value);
I'm not sure what you're asking, but I see the following problems with your code:
app.output[0]: there should be no [0], app.output is already an element (you got it by id). So use app.output.appendChild(app.createDiv.firstChild);. Still, this makes no sense; as Barmar said, you just created that div, so it doesn't have any children at that point.
app.createDiv.classname: should be className
document.getElementsByClassName('username').innerHTML: this returns multiple elements, maybe you want document.getElementsByClassName('username')[0].innerHTML?

Remove element created by JavaScript on load

How can I remove elements which are created by JavaScript, I tried using CSS by setting display:none; but that doesn't seem to solve my problem, also I can't remove them since I don't have them in HTML, any other ways? Thank you
UPDATE:
Can't use any JavaScript such as jQuery, MooTools, ExtJS etc, and actual elements I want to remove are divs, with a specified class so I can't use getElementById.
I found this script on Google, but it doesn't seem to work but this is what I need:
HERE
This is fairly simple to do this using jQuery.
$("#myId").remove();
will remove
<div id="myId"></div>
Edit: You can also do it with "old school" javascript.
The function you're looking for is removeChild()
Example:
function removeElement(divNum) {
var d = document.getElementById('myDiv');
var olddiv = document.getElementById(divNum);
d.removeChild(olddiv);
}
You will want something like this to take advantage of browser support where you can:
if(document.getElementsByClassName){
// Safari 3+ and Firefox 3+
var itms = document.getElementsByClassName('your_class');
for(var i = 0; i<itms.length; i++){
var it = itms[i];
if(it.tagName == "DIV"){
it.parentNode.removeChild(it);
i = i - 1; //It actually gets removed from the array, so we need to drop our count
}
}
} else {
// All other browsers
var itms = document.getElementsByTagName('div');
for(var i = 0; i<itms.length; i++){
var it = itms[i];
// Test that className contains your class
if(/your_class/.test(it.className)) it.parentNode.removeChild(it);
}
}
JavaScript handles all memory mangement for you using garbage collection so once all references to an object cease to exist that object will be handled by the browsers specific implementation.
If you have the dom element itself:
if(node && node.parentNode){
// return a ref to the removed child
node.parentNode.removeChild(node);
}
Since you say you can't use Javascript, you're pretty stuck. Have you tried this CSS:
.classname {
display: none !important;
}
It's possible that the created elements have inline styles set on them, in which case normal CSS is overridden. I believe the !important will override inline styles.
Of course, the best solution is not to add the element in the first place... but I'm guessing you're in one of those (unfathomably common) scenarios where you can't change or get rid of the JS?
Not all browsers have a
document.getElementsByClassName
method, but for your purpose you can
fake it well enough- This method does
not work like the native
HTMLElement.getElementsByClassName- it
returns an array, not a live nodelist.
You can specify a parent element and a
tag name to speed it up.
function getElementsByClass(css, pa, tag){
pa= pa || document.body;
tag= tag || '*';
css= RegExp('\\b'+css+'\\b');
var A= [], elements, L, i= 0, tem;
elements= pa.getElementsByTagName(tag);
L= elements.length;
while(i<L){
tem= elements[i++];
if(css.test(tem.className)) A[A.length]= tem;
}
return A;
}
// test
var A= getElementsByClass('removeClass'), who;
while(A.length){
who= A.pop(); // remove from the end first, in case nested items also have the class
if(who.parentNode) who.parentNode.removeChild(who);
who= null;
}
If you have assigned event handlers to
the elements being removed, you should
remove the handlers before the
elements.
You will probably have to be more specific.
The general answer is 'with JavaScript'. As long as you have a way of navigating to the element through the DOM, you can then remove it from the DOM.
It's much easier if you can use a library like jQuery or prototype, but anything you can do with these you can do with JavaScript.
marcgg has assumed that you know the ID of the element: if you don't but can trace it in the DOM structure, you can do something like this (in prototype - don't know jQuery)
var css_selector = 'table#fred tr td span.mydata';
$$(css).invoke('remove');
If you can't use a JS library, you'll have to do the navigation through the DOM yourself, using Element.getElementsByTagName() a lot.
Now you've specified your question a bit: use Element.getElementsByTagName, and loop through them looking at their className property.
Use:
document.removeChild('id_of_element');

Categories

Resources