Open SuiteLinks in a new tab and Chrome

Open SuiteLinks in a new tab and Chrome

In a previous post I wrote about Open SuiteLinks in a new tab on a solution on how you can extend the SuiteLinks bar in SharePoint by adding some script to the MasterPage. In this script I used the DOMSubtreeModified event, and as it turned out this event is deprecated. Besides that it also seems to expect a slightly different implementation in Chrome. So since Office 365 states that it supports Chrome I figured that I should be looking to a replacement for the mutation events.

While looking into a replacement one of the things that you will see is suggested is the Mutation observer, something that looks really promising though the support is not available in all browsers. As you can see the implementation of the Mutation observer support is a bit scattered across all browsers, but most of the modern browsers will support it. For that reason I made an updated version of the script where we check if we can use the MutationObserver. If that is the case and we can use a MutationObserver object we will leverage that, if not we will do a fallback to the previous solution. That way we can still support all browsers and give the user an experience that is consistent over the different browsers

if(typeof MutationObserver != 'undefined') {    
    var whatToObserve = {childList: true, subtree: true},
    mutationObserver = new MutationObserver(function(mutationRecords) {
      $.each(mutationRecords, function(index, mutationRecord) {
        if (mutationRecord.type === 'childList' && mutationRecord.addedNodes.length > 0) {
             var topLinks = $('ul#Suite_TopMenu li a');
            if(topLinks.length != 0) {
                $(topLinks).attr('target', '_blank');
            };    
        }
      });
    });
    mutationObserver.observe(document.getElementById('suiteLinksBox'), whatToObserve); 
}
else {
    var firstRun = true;        
    $('div#suiteLinksBox').bind("DOMSubtreeModified",function(){
        if(firstRun){
            firstRun = false;
            var topLinks = $('ul#Suite_TopMenu li a');
            if(topLinks.length != 0) {
                $(topLinks).attr('target', '_blank');
            };                                
        }
    });   
}   

If you are working with the MutationObserver you can specify what you would want to observe, and fire actions for all those changes. While in our case we only want to catch new items added it can also be used to monitor deleted items, or to monitor property changes for that matter. Some insights on how you should implement it can be found on MSDN Mutation observers.

There are 6 comments for this article
  1. Mike at 22:20

    This is extremely helpful, thank you. Unfortunately, I can't make mine work in Chrome of Firefox, which means the first part with the MutationObserver is not working. It works great in IE.

    Is there any way someone could give me a hand with this? It has been many years since I've had to dive into some code.

    I have the following script in my master page:

    if(typeof MutationObserver != 'undefined') {
    var whatToObserve = {childList: true, subtree: true},

    var mutationObserver = new MutationObserver(function(mutationRecords) {
    $.each(mutationRecords, function(index, mutationRecord) {
    if (mutationRecord.type === 'childList' && mutationRecord.addedNodes.length > 0) {
    var topLinks = $('ul.ms-core-suiteLinkList li a');
    if(topLinks.length != 0) {
    $(topLinks).attr('target', '_blank');
    };
    }
    });
    });
    var target = document.querySelector('#suiteLinksBox');
    mutationObserver.observe(target, whatToObserve);
    }
    else {
    var firstRun = true;
    $('div#suiteLinksBox').bind("DOMSubtreeModified",function(){
    if(firstRun){
    firstRun = false;
    var topLinks = $('ul.ms-core-suiteLinkList li a');
    if(topLinks.length != 0) {
    $(topLinks).attr('target', '_blank');
    };
    }
    });
    }

    The Top Bar generates the following HTML:

    NewsfeedOneDriveSites

  2. Mike at 04:42

    Hi, thanks for your reply. I spent a lot of time trying to debug this tonight and review it with the developer tools in Chrome, but I can't figure it out. There is no error presented in Chrome Developer Tools. I've also reduced the code down to what is listed below and, unfortunately, I still can't get it to work. I don't have the ability to debug this as my background is in C# programming and I'm having trouble figuring out how to debug the nested functions. Any help would be greatly appreciated! Thanks in advance.

    test

    NewsfeedOneDriveSites

    debugger;
    if(typeof MutationObserver != 'undefined') {
    MutationObserver = window.MutationObserver || window.WebKitMutationObserver;

    var whatToObserve = {childList: true, subtree: true},
    mutationObserver = new MutationObserver(function(mutationRecords) {
    $.each(mutationRecords, function(index, mutationRecord) {
    if (mutationRecord.type === 'childList' && mutationRecord.addedNodes.length > 0) {
    var topLinks = $('ul.ms-core-suiteLinkList li a');
    if(topLinks.length != 0) {
    $(topLinks).attr('target', '_blank');
    };
    }
    });
    });
    mutationObserver.observe(document.getElementById('suiteLinksBox'), whatToObserve);
    }
    else {
    var firstRun = true;
    $('div#suiteLinksBox').bind("DOMSubtreeModified",function(){
    if(firstRun){
    firstRun = false;
    var topLinks = $('ul.ms-core-suiteLinkList li a');
    if(topLinks.length != 0) {
    $(topLinks).attr('target', '_blank');
    };
    }
    });
    }

    • Albert-Jan Schot at 09:14

      My best bet would be that SuiteBar has been changed, however that would not explain why it would work in IE. Could you validate the HTML elements are present? And second, you could use the following snippet to write out some debuggin info with the console.log

      if(typeof MutationObserver != 'undefined') {
      console && console.log('MutationObsever can be enabled');

      MutationObserver = window.MutationObserver || window.WebKitMutationObserver;

      var whatToObserve = {childList: true, subtree: true},
      mutationObserver = new MutationObserver(function(mutationRecords) {
      $.each(mutationRecords, function(index, mutationRecord) {
      console && console.log('We found a mutation record');
      console && console.log(mutationRecord);

      if (mutationRecord.type === 'childList' && mutationRecord.addedNodes.length > 0) {
      console && console.log('mutation record of type childList');

      var topLinks = $('ul.ms-core-suiteLinkList li a');
      if(topLinks.length != 0) {
      console && console.log('We found a suitelinklist');
      $(topLinks).attr('target', '_blank');
      };
      }
      });
      });

      mutationObserver.observe(document.getElementById('suiteLinksBox'), whatToObserve);
      }

  3. Mike at 20:10

    Hi, Thanks for the help with the debugging code. I confirmed that the HTML elements are present. I tried to include them in my comment, but I'm getting an invalid security token error. They were included in my last comment, though I think they were parsed out.

    I ran the code and it produced one message: "MutationObsever can be enabled"

    It seems like the code is not able to find a mutation record.

    It looks like it should work, but for some reason it isn't finding the records. Any help would be greatly appreciated!

    Thanks,
    Mike

Leave a Reply