document.getElementsByClassName() works, but inconsistent - facebook

I was trying to create a greasemonkey script which removes Facebook and twitter from a website.
In my case 9gag.
I looked and I need to hide the classes:
1. 'social-action' (works fine)
2. 'badge-sticky-social sticky-social' (every second post)
3. 'post-afterbar-a in-list-view' (every second post)
my Code so far (differing classes)
(function() {
var ads=document.getElementsByClassName('badge-sticky-social sticky-social');
for (var i=0; i<ads.length; i++) {
ads[i].parentNode.removeChild(ads[i]);
}
})()
I don't know why it only works on half the post and not all of them

Because you're removing the very elements that you're iterating over, the iteration ends up in the wrong place. That is, you look at the first one and then remove it, and then try to look at the second one. But the one that had been the second one is now the first one, so that one gets skipped.
The solution, as CBroe says, is to run the loop from high to low, so that you're not trying to count things that already have been removed:
for (var i=ads.length-1; i>=0; i--)

Related

Javascript DOM addressing into a sub-window DOM element

Given this screenshot of a Firefox DOM rendering, I'm interested in reading that highlighted element down a ways there and writing to the "hidden" attribute 3 lines above it. I don't know the Javascript hierarchy nomenclature to traverse through that index "0" subwindow that shows in the first line under window indexed "3" which is the root context of my code's hierarchy. That innerText element I'm after does not appear anywhere else in the DOM, at least that I can find...and I've looked and looked for it elsewhere.
Just looking at this DOM, I would say I could address that info as follows: Window[3].Window[0].contentDocument.children[0].innerText (no body, interestingly enough).
How this DOM came about is a little strange in that Window[0] is generated by the following code snippet located inside an onload event. It makes a soft EMBED element, so that Window[0] and everything inside is transient. FWIW, the EMBED element is simply a way for the script to offload the task of asynchronously pulling in the next .mp4 file name from the server while the previous .mp4 is playing so it will be ready instantly onended; no blocking necessary to get it.
if (elmnt.contentDocument.body.children[1] == 'undefined' || elmnt.contentDocument.body.children[1] == null)
{
var mbed = document.createElement("EMBED");
var attsrc = document.createAttribute("src")
mbed.setAttributeNode(attsrc);
var atttyp = document.createAttribute("type")
mbed.setAttributeNode(atttyp);
var attwid = document.createAttribute("width")
mbed.setAttributeNode(attwid);
var atthei = document.createAttribute("height")
mbed.setAttributeNode(atthei);
elmnt.contentDocument.body.appendChild(mbed);
}
elmnt.contentDocument.body.children[1].src=elmnt.contentDocument.body.children[0].currentSrc + '\?nextbymodifiedtime'
elmnt.contentDocument.body.children[1].type='text/plain'
I know better than to think Window[3].Window[0]...... is valid. Can anyone throw me a clue how to address the DOM steps into the contentDocument of that Window[0]? Several more of those soft Windows from soft EMBED elements will eventually exist as I develop the code, so keep that in mind. Thank you!
elmnt.contentWindow[0].document.children[0].innerText does the trick

Echo counter always on the same screen location?

I am looking for a way to have a counter (which is giving user feedback during a lengthy process). That is easy enough, but the thing is that the counter should display its digits always in the same screen location.
The process consists of about 50,000 repeated steps. Is such a counter possible in PHP? Or in a combination with Javascript? I would so much love to get a working example.
This is the rough logic:
$Counter = 0;
While ($counter < 50000) {
$x = DoSomething();
echo $counter; // **always in the same location!**
Counter++;
} ;
Hoping for the best!
Obviously, all (PHP) problems have their solution, hidden somewhere here on StackOverflow. My thingy about having Echo use always the same location on screen, has been answered here:
Show progress for long running PHP script . About halfway down, there is a beautiful neat solution, without Javascript of Ajax, only in PHP. For me it does the trick!
Thanks, Stack.

AG-Grid get page number with infinite scrolling

I'm using the AG-Grid infinite scrolling row model in Angular, by following the example from Here
When running the above example, I can see in the developer tools that the page number gets logged out:
However I cannot seem to find a way to get the page number in my code. I've tried paginationGetCurrentPage(), however that doesn't appear to work with the infinite scrolling row model.
Is there any way to get the page number being requested when the getRows functions is fired? My api expects a page number to retrieve data, rather than a start and end row number.
It's just simple math you need to do to get the page number inside getRows.
let pageNo = 1;
if (this.paginationPageSize != undefined)
pageNo = params.startRow / this.paginationPageSize + 1;
// use pageNo to make API request
console.log('pageNo: ' + pageNo);
Check this plunk I've created. Observe the browser logs.

DevExpress VerticalGrid in unbound mode with MultiRecordLayout

EDIT: As it turns out, the grid does not support unbound mode in MultiRecordView layout.
I will try to ask this question a different way since my last one was downvoted without comment, so I don't know what the downvoter was objecting to.
I've worked quite a lot with the DevExpress VerticalGrid in unbound mode in SingleRecordView. We use it in all of our desktop applications that involve lots of data-entry. All data-entry forms are consistent in look-and-feel and so user training is minimal. I think it is a great control.
However, I don't understand how to use it in unbound mode in MultiRecordView layout. I cannot even figure out how to populate the unbound grid with the data for several records. In SingleRecord layout, I use the RowsIterator to move data from my data object in memory into the corresponding row/cell in the VerticalGrid's single record.
But in MultiRecordView layout, I can't figure out how to add the second record and the third record, etc etc, and position the current record pointer so that the RowsIterator is working with the rows of the correct record.
A small code snippet, showing how to move the current record pointer when adding the second and subsequent records in MultiRecordView, would be very helpful.
I've tried AddNewRecord() and setting the FocusedRecord but without success:
for (int i = 0; i < MyTable.Rows.Count; i++)
{
vGridControl1.AddNewRecord();
vGridControl1.FocusedRecord = i;
vGridControl1.RowsIterator.DoOperation(new DataPuller(MyTable.Rows[i]));
}
and here's a relevant snippet from my DataPuller object:
public override void Execute(DevExpress.XtraVerticalGrid.Rows.BaseRow brow)
{
//<snip>
if (brow is DevExpress.XtraVerticalGrid.Rows.EditorRow)
{
string fieldname = brow.Properties.FieldName;
if (table.Columns.Contains(fieldname))
{
brow.Properties.Value = (table[fieldname] == DBNull.Value) ? null : table[fieldname];
}
}
//<snip>
}
The vertical grid doesn't support unbound mode when in MultiRecordView layout.

What is better approach to wait for elements on a page Waitforcomplete() or system.threading.thread.sleep()

I am Using WaitforComplete() in watiN but it doesnt seems to work well. As it executes the next statement even if you have given longer time to wait. I am using thread.sleep() to stop my application until it gets the desired page or element. But the thing is pages are so much dynamic that sometimes it takes much longer time as specified.
Any better solution. Any thing that will catch the page return dynamically and dont go to execute next statments in application.
Sample of Code
'Show Details page
Assert.AreEqual("Confirmation", _internetExplorer.Title)
If (_internetExplorer.Button(Find.ById(New Regex("btnFinish"))).Exists) Then
_internetExplorer.Button(Find.ById(New Regex("btnFinish"))).Click()
Else
Assert.Fail("Could not Find Finish Booking Button on Confirmation Page")
End If
System.Threading.Thread.Sleep(100000)
'Show Booking Summary page
Assert.AreEqual("Display Booking", _internetExplorer.Title)
I want something that detect the return of page dynamically. instead of giving some constant value.
WaitForComplete only works well if there is a postback after some action. Otherwise you have to find something else to wait for. Following an example on how to wait for the specified title:
_internetExplorer.Element("title", "Confirmation").WaitUntilExists();
I would always prefer to use one of the WaitXXX methods instead of Thread.Sleep cause the WaitXXX methods do only wait until the contraint is met. Where as Sleep waits for the time you specified. If its to long, time is waisted. If its to short, problems arise.
HTH,
Jeroen
The WaitForComplete method esentially moves on once the browser has set it's readystate to comllete and the busy state to false.
What I typically do is to try and access what you need to, then perform a thread.sleep for say half a second, then try again. I also have a global timeout that quits after say 10 seconds.
int timeout = 20;
bool controlFound = false;
for (int i = 0; i < timeout; i++)
{
if (_internetExplorer.Button(Find.ById(New Regex("btnFinish"))).Exists)
{
_internetExplorer.Button(Find.ById(New Regex("btnFinish"))).Click();
controlFound = true;
break;
}
else
{
System.Threading.Thread.Sleep(500);
}
}
if (!controlFound)
{
Assert.Fail("Control not found");
}
If it is executing the next statement, it should be finding the corresponding element. I suggest posting a sample of the code you are trying.