1

I am writing a script that changes up the message system for a website I use a lot. It adds a button to the top of each message thread. When clicked, it automatically moves to the most recent message in the thread.

The issue I am having is that the messages are loaded by php and the script fires before the messages are loaded. The site also doesn't load all of the message threads at the same time. It will load 10 or so, and then as you scroll down it loads more. Is there a way to get the button to load for each of the message threads, or am I shooting for an unreachable goal?

// ==UserScript==
// @name          Imgur - Message Viewer
// @namespace     Basion
// @description   It skips to the bottom of the most recent message
// @author        Basion
// @include       http://imgur.com/*
// @include       https://imgur.com/*
// @include       http://*.imgur.com/*
// @include       https://*.imgur.com/*
// @run-at        document-end
// ==/UserScript==
var messages = document.getElementsByClassName("thread-wrapper");

var newA = document.createElement('a');

for (var i = 0; i < messages.length; i++) {
    newA.addEventListener("click", scrollToMessage(i), true);
    newA.innerText = "Go to Newest Message";
    messages[i].appendChild(newA);
}
function scrollToMessage(id) {
    var newMessages = document.getElementsByClassName('thread-wrapper');
    newMessages[id].scrollIntoView(false);
}
  • Can you add some source code from you? – Reporter May 27 '13 at 11:24
  • 1
    Can we look at the site you actually want to use the script on? How the new contents are loaded? You can consider to set it wait for 1 second before execution. Or perhaps, after clicking a button, the script counts the thread number every second. If the thread number increases (i.e. succesfullly loaded), then scroll to it. – kevinamadeus May 27 '13 at 11:34
  • @kevinamadeus I want to use it on [Imgur](http://www.imgur.com) You would have to make an account to see the message system. I believe you can send messages to yourself as well if that helps you figure things out a bit. – user2424715 May 27 '13 at 11:51
  • In general, see ["Run Greasemonkey script on the same page, multiple times?"](http://stackoverflow.com/q/11195658/331508). Other than that, it's not clear from the code exactly how many buttons you want and which post(s) they should jump to. Post a sketch or annotated screenshot to clear that up. – Brock Adams May 27 '13 at 12:37
  • The amount of buttons depends on how many message threads there are. As you can see [here](http://i.imgur.com/Vf8SHsS.jpg) each thread has it's own section. The button is going to be in the top grey box next to the subject. When you hit the button, it will scroll the page down to the most recent message which is always at the bottom of the thread. When you get long threads, scrolling down get's difficult. That's why I want to put this in. – user2424715 May 27 '13 at 12:59

1 Answers1

1

To handle elements added via AJAX, use jQuery and waitForKeyElements as shown in "Run Greasemonkey script on the same page, multiple times?".
Here's a handy jQuery reference.

Also, you can't send id's to event listeners that way.

Here's a complete working, post-jump script, adapted to the question's code and the Imgur target page(s):

// ==UserScript==
// @name          Imgur - Message Viewer
// @namespace     Basion
// @description   It skips to the bottom of the most recent message
// @author        Basion
// @include       http://imgur.com/*
// @include       https://imgur.com/*
// @include       http://*.imgur.com/*
// @include       https://*.imgur.com/*
// @run-at        document-end
// @require       http://ajax.googleapis.com/ajax/libs/jquery/1.8.3/jquery.min.js
// @require       https://gist.github.com/raw/2625891/waitForKeyElements.js
// @grant         GM_addStyle
// ==/UserScript==
/*- The @grant directive is needed to work around a design change
    introduced in GM 1.0.   It restores the sandbox.
*/

waitForKeyElements ("div.thread-wrapper", addJumpButton);

/*-- Prepend a button to the top of each thread.  Don't add in the header, to
    avoid conflicts with the open/close toggle.
*/
function addJumpButton (jNode) {
    jNode.prepend (
        '<a href="#" class="gmThreadJmpBtn">Go to Newest Message in thread</a>'
    );
}

//-- Activate *all* the jump buttons with one jQuery function.
$("div.notifications").on (
    "click", "div.thread-wrapper a.gmThreadJmpBtn", jumpToEndOfThread
);

function jumpToEndOfThread (zEvent) {
    //-- The last (newest) message will be just above the "reply bar".
    var thisThreadHdr   = $(zEvent.target);
    var targetDiv       = thisThreadHdr.nextAll ("div.reply.striped");
    targetDiv[0].scrollIntoView (false);

    //-- Block the page handlers from also firing for this link.
    zEvent.stopPropagation ();
    zEvent.preventDefault ();
}
Community
  • 1
  • 1
Brock Adams
  • 90,639
  • 22
  • 233
  • 295
  • This works great. I guess I didn't think about the open/close thing that much. I guess I should also look into jquery more. I'm fairly new to all of this, as you might imagine. Thanks a ton! – user2424715 May 27 '13 at 14:55
  • You're welcome. You can still add the link to the header, but it complicates things. I showed the simpler/easier answer. – Brock Adams May 28 '13 at 00:58