How to return the specific element, when using multiple custom share buttons on the same page, using querySelectorAll?

Asked

Viewed 264 times

1

This custom Facebook share button works great when you put only one button on each page. (This is an excellent way to make Ajax and Javascript projects traceable to search engines and social networks).

When placing multiple buttons on the same page I had problems with the querySelector (The documentation states that the querySelector returns the first element inside the document...), but I still don’t know how to return only the element that was clicked.

I would like an educated orientation, so I can complete a part of this long search, to make the shares traceable.

@Sergio thanks for the introduction in the comment , but, I still could not put in harmony the querySelectorAll with the iteration with the for, then I asked the question how you guided.

This is the part corresponding to the source file, edited and adapted to my project, you may be seeing the original post on this site: Facebook share button customizable

Html

            <div id="fb-root"></div>
<a fb-share ng-href="http://www.exemplo.com/{{item.href}}" data-image="{{item.img}}" data-title="{{item.titulo}}" data-desc="{{item.descricao}}" class="fb_share"  >
    <div class="botao-fb"></div>
</a>

CSS: to insert the image more practically

.botao-fb {
 width: 101px;
 height: 20px; 
background-image:url(/images/fb-icone.png);
background-repeat:no-repeat;  
margin-bottom: 3px;
}

Directive with the script

    .directive('fbShare', ['$window', function ($window) {
      return {
        scope:{
            fbShare: '='
        },
        restrict: 'AE',

        link: function (scope, element, attrs) {
            window.fbAsyncInit = function() {
        FB.init({
            appId: '1405211842504456', //esse AppId é apenas demonstrativo, substitua com o seu
            status: true,
            cookie: true,
            xfbml: true
        });
    };

    (function(d, debug){var js, id = 'facebook-jssdk', ref = d.getElementsByTagName('script')[0];if   (d.getElementById(id)) {return;}js = d.createElement('script'); js.id = id; js.async = true;js.src = "//connect.facebook.net/pt_BR/all" + (debug ? "/debug" : "") + ".js";ref.parentNode.insertBefore(js, ref);}(document, /*debug*/ false));

    function postToFeed(title, desc, url, image) {
        var obj = {method: 'feed',link: url, picture: 'http://www.exemplo.com/images/'+image,name: title,description: desc};
        function callback(response) {}
        FB.ui(obj, callback);
    }

    var fbShareBtn = document.querySelectorAll('.fb_share');
    for (var i = 0; i < fb_share.length; i++) {
        console.log(fb_share[i]);
    };
    fbShareBtn.addEventListener('click', function(e) {
        e.preventDefault();
        var title = fbShareBtn.getAttribute('data-title'),
            desc = fbShareBtn.getAttribute('data-desc'),
            url = fbShareBtn.getAttribute('href'),
            image = fbShareBtn.getAttribute('data-image');
        postToFeed(title, desc, url, image);

        return false;
    });
}]);

2 answers

3


If you use the querySelectorAll You have to iterate the elements and add the Event Handler like this:

function fbShareBtnFn(e) {
    e.preventDefault();
    var title = this.getAttribute('data-title'),
        desc = this.getAttribute('data-desc'),
        url = this.getAttribute('href'),
        image = this.getAttribute('data-image');
    postToFeed(title, desc, url, image);
    return false;
};
var fbShareBtns = document.querySelectorAll('.fb_share');
for (var i = 0; i < fbShareBtns.length; i++) {
    fbShareBtns[i].addEventListener('click', fbShareBtnFn);
};

And once the Event Handler is called for each element the this within that function corresponds to the clicked element.

  • It worked almost perfectly, only the second element is opening repeatedly; open two facebook dialogues when I click the button, which is the second element of the list in paging. I’ll be analyzing right here might be something in the other codes.

  • I left 3 items on the same page in the pagination, to make the test better, it happened that when you click on 1°3 dialogues of the same article were opened, when you click on 2°2 dialogues of the same article were opened, and when you click on the third opened 1, which is the ideal.

  • @Sergio, just a hint, when you want to access an attribute data-*, give preference to dataset instead of getAttribute, I believe this improves readability.

  • @Thiagojem I’m not in the office... you’ve already solved the mistakes?

  • @Tobymosque the dataset is only supported in IE11, although this is the correct way in the future, I suggested the safe cross-browser way.

  • @Sergio, I had forgotten this detail, I hope that with Spartan to MS can force the update of Browser.

  • @Tobymosque this would be excellent (if MS adopts mandatory browser update)... would save a lot of headache :)

Show 2 more comments

1

In addition to @Sergio’s reply I needed to add the event.stopImmediatePropagation(); (that keeps the rest of the handlers from running and prevents the event from bubbling the DOM tree.),

Because, I use multiple facebook buttons in a pagination and was opening several dialogs by clicking the button. Now it’s working fine.

function fbShareBtnFn(event) {
     event.preventDefault();
    var title = this.getAttribute('data-title'),
        desc = this.getAttribute('data-desc'),
        url = this.getAttribute('href'),
        image = this.getAttribute('data-image');
    postToFeed(title, desc, url, image);
// retirei o 'return false;' e coloquei o 'event.stopImmediatePropagation();'
    event.stopImmediatePropagation();
};
var fbShareBtns = document.querySelectorAll('.fb_share');
for (var i = 0; i < fbShareBtns.length; i++) {
    fbShareBtns[i].addEventListener('click', fbShareBtnFn);
};

Browser other questions tagged

You are not signed in. Login or sign up in order to post.