Keep Body while changing the title - javascript

I am working with JS bookmarklets and I am playing around withjavascript:document.title = "WHATEVAH". However, when I use that by itself, it removes all content on the page. So then I tried javascript:document.title = "WHATEVAH";document.body.innerHTML = document.body; but that didn't work either. Please explain what I am doing wrong, and how I can fix it.

You have to return undefined at the end, otherwise it's going to navigate to a blank page. A common way of doing it is to do:
javascript:document.title = "WHATEVAH"; void 0;

Related

New to Javascript: Popup Menu

I'm trying to make a website and I'm stuck now that I'm in JS territory. I am OK with HTML and CSS, but I feel like a total moron when it comes to JS.
Here's what I have (and I'm sure it's dead wrong) so far...
var clicked = getElementById('loginIcon').clicked;
function showHideLogin() {
if (clicked) {
getElementById('loginField').visibility = "visible";
}
else {
getElementsById('loginField').visibility = "hidden";
}
}
Please, be kind... I'm just starting to learn JS and I'm ripping my hair out and feeling like a complete idiot...
I'm trying to make a login that only shows when an icon (png) is clicked. Otherwise, it's hidden.
EDIT: Thanks for the replies so far. This is how much of a noob I am: Atom says " Node is not recognized as an internal or external command" which, by Googling, I've found out means I don't have Node JS (which I have to research more to understand).
Thanks guys. I'll let you know if it's still not working.
Try
getElementById('loginField').style.visibility = "visible";
You're not setting the visibility correctly. It should be:
getElementById('loginField').style.visibility = "visible";
Also, I'm not sure when showHideLogin is expected to be called, but the norm for setting an event handler is to register a function. Something like:
getElementById('loginIcon').onclick = function() {
// perhaps some conditions or other logic
getElementById('loginField').visibility = "visible";
};

Making a Chrome extension for a site that uses React. How to persist changes after re-rendering?

I want my extension to add elements to a page. But the site uses React which means every time there's a change the page is re-rendered but without the elements that I added.
I'm only passingly familiar with React from some tutorial apps I built a long time ago.
I implemented #wOxxOm's comment to use MutationObserver and it worked very well.
static placeAndObserveMutations (insertionBoxSelector) {
let placer = new Placement ();
placer.place(insertionBoxSelector);
placer.observeMutations(insertionBoxSelector);
}
place (insertionBoxSelector) {
let box = $(insertionBoxSelector)
this.insertionBox = box; //insertionBox is the element that the content
// will be appended to
this.addedBox = EnterBox.addInfo(box); //addedBox is the content
// Worth noting that at this point it's fairly empty. It'll get filled by
// async ajax calls while this is running. And all that will still be there
// when it's added back in the callback later.
}
observeMutations(insertionBoxSelector) {
let observer = new MutationObserver (this.replaceBox.bind(this));
// this.insertionBox is a jQuery object and I assume `observe` doesn't accept that
let insertionBox = document.querySelector(insertionBoxSelector);
observer.observe(title, {attributes: true});
}
replaceBox () {
this.insertionBox.append(this.addedBox);
_position (this.addedBox);
}
That being said someone suggested adding the content above the React node (i.e. the body) and just positioning the added content absolutely relative to the window. And as this will actually solve a separate problem I was having on some pages of a site I'll probably do that. Also, it's far simpler.
But I thought this was still an interesting solution to a rare problem so I wanted to post it as well.

Disqus's count.js script doesn't run properly in index.html with react.js website

I've been having a hell of a time getting the comment count script to work on my react pages. To start, they recommend putting the script in my index.html file, at the bottom of the <body> tag. I've done this, and seen no result.
<body>
<div id="app">
</div>
<script src="static/index.js"></script>
<script id="dsq-count-scr" src="//mtg-hunter.disqus.com/count.js" async></script>
</body>
I have an index.js file which is loading all my components, including the component (let's call it ResultComponent.js) which I want to have the comment count <span> tags in. The <span> tags themselves look like this:
var commentCount = <span className="disqus-comment-count" onClick={function() {this.setState({currentSelectedTab: 4})}.bind(this)}
data-disqus-identifier={idGoesHere}
style={{fontVariant:"small-caps"}}>0 Comments</span>
So far, so simple. I'm not using any <a> tags so I haven't got #disqus_thread anywhere. When I load my page, I expect my comment count to go up, but no such luck. To test this, I copied the raw script, unaltered, from the raw count.js script (which is located here). I then pasted it straight into Chrome's devtools console, and it worked; all the relevant comment counters went to their appropriate values.
EDIT: a day later, more prodding; I added breakpoints in the actual code in the disqus.com domain. The script in the script tag is running just fine at the right time, except it's missing variables when it enters the displayCount() function. There's several variables that just aren't given values so it can't go in and populate the comment counts, it always fails out. I have no idea why this fails when it's called from within my index.html but not when I paste the raw count.js code into my console and do it there. No idea why.
To clarify, this is the relevant code:
e.displayCount = function(b) {
for (var c, a, d, e = b.counts, b = b.text.comments; c = e.shift(); )
if (a = j[c.id]) {
switch (c.comments) {
case 0:
d = b.zero;
break;
case 1:
d = b.one;
break;
default:
d = b.multiple
}
c = d.replace("{num}", c.comments);
a = a.elements;
for (d = a.length - 1; d >= 0; d--)
a[d].innerHTML = c
}
}
;
When it runs properly, from my pasting the script into the console, the j variable is defined. When it runs called from index.html, j is undefined, so it fails at the first if. The calling url is exactly the same in both situations: http://mtg-hunter.disqus.com/count-data.js?1=19767&1=235597&1=373322&1=382310&1=382841&1=382866&1=383023&1=397543&1=397682&1=398434. That gives the b parameter, and when I run the script locally it defines j so that the assignment operator in the if can work (which is a really weird way of doing it, but ok).
edit again: I should point out I'm doing this on a local test server (localhost:3000), not sure if that makes a difference or not?
edit more: The answer to my above question turns out to be 'no'. I uploaded my code to my server and the production site also showed that the script wasn't running properly. This is absurd... I'm out of ideas by now.
edit again more: Partial breakthrough... I added this code to ResultComponent.js:
componentDidMount() {
DISQUSWIDGETS.getCount();
},
componentDidUpdate() {
DISQUSWIDGETS.getCount();
},
Good news; when I refresh the page, it shows the right comment count! Hooray! Bad news: when I change parts of the page that hide the Result component, and then bring it back (triggering componentDidUpdate), the DISQUSWIDGETS.getCount() call doesn't work. It still gets called, but the displayCount part of the script never does, so the DOM is never updated with the new information. It's yet another example of this horrid script behaving differently despite being called in exactly the same way...
OK, after much back and forth with the support guy at Disqus I finally found an answer; I was close. The solution is:
componentDidMount() {
DISQUSWIDGETS.getCount({reset:true});
},
componentDidUpdate() {
DISQUSWIDGETS.getCount({reset:true});
},
Turns out I had to pass the reset:true param, which enabled a chunk of code in getCount to actually do something. I suppose I could've figured that out from the code, but I blame the intensely minified formatting (even with chrome dev tools helping to prettify it) for me missing that. It was also in their knowledge base article for how to add comment counters, but I missed the context of it (and got absorbed by the 'fact' that 'it obviously had to be the script not working, clearly').
And so ends one of my most frustrating few days of coding. And a useful lesson... step back and look at the big picture every now and again, because the answer can be staring you in the face.

Running multiple Javascript scripts only when certain HTML elements exist?

Here's the situation. I'm building a site which uses lots of scripts looking somewhat like this:
function getRandomArrayIndex(source_array) {
return Math.floor(Math.random() * source_array.length);
}
function getRandomArrayEntry(source_array) {
var random_index = getRandomArrayIndex(source_array);
return source_array[random_index];
}
function getRandomBlah() {
var blahs = [
["A"],
["B"],
["C"],
["D"],
["E"],
["F"],
["G"],
["H"],
["I"],
["L"],
["M"],
["N"],
["O"],
["P"],
["R"],
["S"],
["T"],
["V"],
["W"],
["Y"],
]; var random_blah = getRandomArrayEntry(blahs);
return random_blah;
}
function displayBlah(blah) {
const TEXT_ROW = 0;
const LINK_ROW = 1;
var blah_text = blah[TEXT_ROW];
var blah_link = blah[LINK_ROW]; if (blah_link != null) {
document.getElementById("blah").innerHTML = '' + blah_text + '';
} else {
document.getElementById("blah").innerHTML = blah_text;
}
}
function generateRandomBlah(){
var random_blah = getRandomBlah();
displayBlah(random_blah);
}
And this will, when called with <body onload="generateRandomBlah()">, insert one of the letters at random into <span id="blah"></span>.
So there's about 15 of these scripts, each with their own functions named slightly differently for different uses - generateRandomBlah2, etc, with a corresponding different place in the HTML for each script to do its work.
Because I'm not a very good coder, the way the whole thing works is that in the 'body onload' tag, there's about 15 different 'generateRandomBlah()' functions just within this one tag. The nature of the site means that on any one page, I will only need 2 or 3 of these scripts at once, but I require the ability to call any of them on any page. As you can see, my current tactic is to just call them all at once, and if the corresponding doesn't exist for a script, it'll just ignore that fact and move onto the next one.
Except that it doesn't ignore the fact that there's no corresponding <span>.
As soon as one isn't present, the rest of the scripts break and don't actually do what they're supposed to do. Looking at the code in Chrome's 'inspect code' shows an error at the first script which happens to break: "Uncaught TypeError: Cannot set property 'innerHTML' of null". I see a couple of potential solutions, but I might be completely off:
1) Add some code into each script which tells it that, if there's no <span id> on the page to insert its code, it ends gracefully and moves onto the next one - gradually (obviously in less than a second speed-wise) going through the scripts and only running them if actually exists. (As you can see, the problem is that a script will get 'snagged' on the fact that there's no place to insert its code and doesn't just end gracefully if that happens.
2) Get rid of the 'onload' stuff and just make each script self-containing, calling its own function. I don't know if this would fix the problem, though.
Anyway, some help would be much appreciated, as I'm stumped.
As you said in your first solution, testing for null before trying to "do" anything is probably your best bet short of completely recoding.
function getRandomArrayIndex(source_array) {
if(source_array === null) return; // similar lines in each function should fix everything
return Math.floor(Math.random() * source_array.length);
}
That said, a much better approach than your current solution of making a bunch of very similar functions and running them all is to create a single function that can take parameters indicating what it should be doing. If they really are quite similar, it shouldn't be difficult and will result in a lot fewer lines of code. It would also be nice if you can find a way for your page to not call all of the functions every time, though with fixing the null pointers that's a much smaller issue.
Not sure if I'm missing something here, but since even the error message complains about the value being null the obvious solution is to check for null:
var element = document.getElementById("blah");
if( element !== null ) {
element.innerHTML = '' + blah_text + '';
}
If you need to do that often you can make a function for it:
function updateIfExists( id, content ) {
var element = document.getElementById( id );
if( element !== null ) {
element.innerHTML = content;
}
}
updateIfExists( 'blah', '' + blah_text + '' );

jquery programmatic popup window

I'm new to Jquery, so please bear with me. I'm trying to create a function that will programmatically open popup windows. I'm running the following code in Firefox, and it seems to work except that the popup windows disregards the toolbar/menubar/scrollbars/resizable/location parameters (they are still visible/functional and I would like to disable all of them):
wparams[0] = {windowURL:"site.html",height:100,width:100,left:500,top:500,toolbar:0,menubar:01,scrollbars:0,resizable:0,location:0}
var launchWindow = function(p)
{
$('.popup').popupWindow(wparams[p]).trigger("click");
}
var begin = function()
{
launchWindow(0);
}
I would like the popups I'm using jQuery-swip popup plugin (http://swip.codylindley.com/popupWindowDemo.html), am wondering what's wrong with the above code.
Also, when I try to run this code in chrome/safari (typing begin(); in the console) it returns undefined, whereas in Firefox it runs. I'm also confused as to why this is happening.
Thanks.
I didn't understand 'when' you want to open the popup, if when the page complete loading, so it should be
$(document).ready(function() {
launchWindow(0);
});
Also can you explain to me why use trigger(click)??? As of the plugin documentation, this should work like that
var launchWindow = function(p)
{
$('.popup').popupWindow(wparams[p]);
}
Does this work?
wparams[0] = {windowURL:"site.html","height:100,width:100,left:500,top:500,toolbar:0,menubar:01,scrollbars:0,resizable:0,location:0"}
That's a weird way to define the "wparams" array - what happens if you do this:
var wparams = [
{windowURL:"site.html", height:100, width:100, left:500, top:500, toolbar:0, menubar:01, scrollbars:0, resizable:0, location:0}
];
It's not really clear why you're setting that up as an array; I guess maybe there might be other popup configurations stored in it. If that's the case, you'd just write them inside those square brackets, separated by commas.

Categories

Resources