1

I'm having a go a little Chrome extension to add a button to each of the "following" users on the Following page on twitter.com.

So far, I've got the content script working enough to add the button to each of the 'following' users, both on page load, and when more users are added when the page is ajax-appended to by twitter.com when you scroll down. I've added an onclick event to each button, wrapped in a closure, so that when you click it, it console.logs which user's button you clicked. That all works fine.

However, when you click between (for example) the Followers page and back to the Following page, the onclick events no longer fire, even though the button is still there in the DOM. It's as if the onclick event has been lost. What could have happened to the onclick event?

Note that after returning to the 'following' page and noting the lost events on my existing buttons, scrolling down to add more users to the list correctly appends more buttons with their onclick events in place. I could remove and re-add the buttons when you click back to the 'following' page, but it'd be nice to know why the events aren't there.

manifest.json:

{
   "name": "Twitter Button",
   "version": "0.1",
   "permissions": ["tabs"],
   "content_scripts": [{
       "matches": ["https://twitter.com/*"],
       "css": ["style.css"],
       "js": ["content_script.js"],
       "run_at": "document_end" 
   }],
   "manifest_version": 2
}

content_script.js:

function addButtons(){

    // Only act on the 'following' page
    // Note that I did try just setting the 'matches' attribute in the manifest file
    // to just the 'following' page, but that didn't seem to fire consistently
    // hence matching on any twitter page, and only acting on the 'following' page
    if (document.URL.indexOf("twitter.com/following") > -1){

        // Get a list of btn-group elements
        var btnGroups = document.querySelectorAll(".btn-group");

        for(var i = 0; i < btnGroups.length; i++){
            var btnGroup = btnGroups[i];
            var grandParent = btnGroup.parentNode.parentNode.nodeName;

            // Only add note elements to list items that have not aleady had a note element added
            if(btnGroup.children.length === 2 && grandParent === 'LI'){

                var followedUser = btnGroup.getAttribute("data-screen-name");

                // Create a closure for each btnGroup so that the correct handle is available to the current clicked button
                var closure = (function(followedUser){
                    return function(){

                        var button = document.createElement("button");
                        button.innerHTML = "Click me";
                        button.className = "btn primary-btn";

                        button.onclick = function(){
                            console.log("Clicked " + followedUser + " button");
                            return false;
                        };

                        btnGroup.appendChild(button);
                    }
                })(followedUser);

                closure();              
            }
        }
    }
}

// Fire immediately (manifest is set to fire on document_end)
addButtons();

// Register a MutationObserver for further DOM changes
var observer = new MutationObserver(function(mutations, observer){
    addButtons();
});
observer.observe(document, {
    subtree: true,
    attributes: true
});

Thanks

4

0 回答 0