我正在使用angularjs,并希望为不同的社交网站添加共享按钮到我的页面。到目前为止,我发现了Angular-socialshare和Socialitejs,但我不知道选择哪一个,或者是否存在其他非常好的,我甚至都不知道。< / p>
答案 0 :(得分:11)
这是目前在GitHub上最受欢迎/最活跃的angular-socialshare(有共享计数器)的替代方案:
http://github.com/esvit/angular-social
这是一个简化的分享按钮(无计数器)。该指令使用Font Awesome作为依赖项。
http://github.com/tinacious/angular-easy-social-share
关于元数据抓取和单页应用的说明
请记住,抓取HTML元数据以获取丰富网页摘要(如OpenGraph链接到图片和说明)的社交网络抓取工具不会评估JavaScript。这可以将标题中的某些元标记呈现为共享框中的{{bracketed}}表达式而不是动态加载的内容...假设您有使用AngularJS动态加载的元数据。
如果您有此要求,请查看此文章,了解如何与Angular共享丰富网页摘要:http://www.michaelbromley.co.uk/blog/171/enable-rich-social-sharing-in-your-angularjs-app
答案 1 :(得分:1)
有一个非常简单的解决方案可以和我一起使用,
您可以将index.html重命名为index.php
并包含一个php页面,其中包含用于解析URL的代码,并且基于URL参数,您可以为twitter和facebook添加标题和描述以及图像
这是我的索引中包含的php页面的代码
<?
function curPageURL() {
$pageURL = 'http';
if ($_SERVER["HTTPS"] == "on") {$pageURL .= "s";}
$pageURL .= "://";
if ($_SERVER["SERVER_PORT"] != "80") {
$pageURL .= $_SERVER["SERVER_NAME"].":".$_SERVER["SERVER_PORT"].$_SERVER["REQUEST_URI"];
} else {
$pageURL .= $_SERVER["SERVER_NAME"].$_SERVER["REQUEST_URI"];
}
return $pageURL;
}
$parse = parse_url(curPageURL());
$urlArray = explode("/",$parse['path']);
$urlPage = $urlArray[2];
if($urlPage == "profile"){
$image = "profile-img.jpg";
$title = "Title of the page ";
$desc = "Description of Profile the page ";
$websiteUrl = "Http://example.com";
}elseif($urlPage == "news"){
$title = "Title of the News page ";
$desc = "Description of the page ";
$websiteUrl = "Http://example.com";
}
?>
<meta http-equiv="content-type" content="text/html; charset=utf-8">
<title><? echo $title; ?></title>
<meta property="twitter:card" content="summary" />
<meta property="twitter:site" content="<? echo $websiteUrl; ?>" />
<meta property="twitter:title" content="<? echo $title; ?>" />
<meta property="twitter:description" content="<? echo $description; ?>" />
<meta property="twitter:image" content="<? echo $image; ?>" />
<meta property="twitter:url" content="<? echo curPageURL(); ?>" />
<meta property="og:title" content="<? echo $title; ?>" />
<meta property="og:description" content="<? echo $description; ?>" />
<meta property="og:image" content="<? echo $image; ?>" />
<meta property="og:type" content="article" />
<meta property="og:site_name" content="<? echo $website_name; ?>" />
<meta property="og:url" content="<? echo curPageURL(); ?>" />
答案 2 :(得分:0)
考虑到sinisterOrange的答案,我想补充一点,关于迈克尔布罗姆利优雅解决方案的一些重要信息。
为了将多个条件重定向到一个能够正确呈现元标记的脚本,您必须为每个规则多次应用条件。
最后,您必须为您的应用访问设置一个负面条件。
<ifModule mod_rewrite.c>
RewriteEngine On
RewriteCond %{HTTP_USER_AGENT} (facebookexternalhit/[0-9]|Twitterbot|Pinterest|Google.*snippet)
RewriteRule ^post/([A-Za-z0-9-]+)/([0-9-]+)$ http://www.example.com/api/renderMetaTags/post/$2 [P,L]
RewriteCond %{HTTP_USER_AGENT} (facebookexternalhit/[0-9]|Twitterbot|Pinterest|Google.*snippet)
RewriteRule ^location/([A-Za-z0-9-]+)/([0-9-]+)$ www.example.com/api/renderMetaTags/location/$2 [P,L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_URI} !index
#this condition for crawlers not to interfere with normal access
RewriteCond %{HTTP_USER_AGENT} !(facebookexternalhit/[0-9]|Twitterbot|Pinterest|Google.*snippet)
#this rule for html5 mode and friendly urls without the #
RewriteRule ^(.*)$ /#/$1 [L]
</ifModule>
就是这样。我知道这有点偏离主题,但我失去了宝贵的时间来达成这个解决方案。
答案 3 :(得分:0)
考虑这个解决方案,因为它对我使用mvc 5和angular js
在索引页面中复制此代码
<!DOCTYPE html>
<html>
<head>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.3.12/angular.min.js"></script>
<link rel="stylesheet" href="style.css" />
<script src="script.js"></script>
<script src='test.js'></script>
<script src="http://platform.twitter.com/widgets.js"></script>
</head>
<body ng-app='testing'>
<div ng-controller='temp'>
<div facebook class="facebookShare" data-title='{{title}}' data-picture-url='http://i.imgur.com/WACv9Cl.jpg' data-url='{{url}}' data-shares='shares' data-callback='callback'>{{ shares }} </div>
<br />
<a twitter data-count='horizontal' data-url='{{url}}' data-size="medium" data-text='{{text}}'></a>
<br /><br />
<div class="linkedinShare" linkedin data-url='{{url}}' data-title='{{title}}' data-summary="{{text}}" data-shares='linkedinshares'>{{linkedinshares}}</div>
<br /><br />
<div gplus data-size="tall" data-annotation="bubble" data-href='{{url}}' data-action='share'></div>
</div>
</body>
</html>
在script.js中写下以下提到的代码
angular.module('testing', ['djds4rce.angular-socialshare'])
.run(function ($FB) {
$FB.init('Facebook App Id');
});
angular.module('testing').controller('temp', function ($scope, $timeout) {
$timeout(function () {
$scope.url = 'http://google.com';
$scope.text = 'testing share';
$scope.title = 'title1'
}, 1000)
$timeout(function () {
$scope.url = 'https://www.youtube.com/watch?v=wxkdilIURrU';
$scope.text = 'testing second share';
$scope.title = 'title2';
}, 1000)
$scope.callback = function (response) {
console.log(response);
}
});
此代码适用于指令
angular.module('djds4rce.angular-socialshare', [])
.factory('$FB', ['$window', function ($window) {
return {
init: function (fbId) {
if (fbId) {
this.fbId = fbId;
$window.fbAsyncInit = function () {
FB.init({
appId: fbId,
channelUrl: 'app/channel.html',
status: true,
xfbml: true
});
};
(function (d) {
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/en_US/all.js";
ref.parentNode.insertBefore(js, ref);
}(document));
} else {
throw ("FB App Id Cannot be blank");
}
}
};
}]).directive('facebook', ['$http', function ($http) {
return {
scope: {
callback: '=',
shares: '='
},
transclude: true,
template: '<div class="facebookButton">' +
'<div class="pluginButton">' +
'<div class="pluginButtonContainer">' +
'<div class="pluginButtonImage">' +
'<button type="button">' +
'<i class="pluginButtonIcon img sp_plugin-button-2x sx_plugin-button-2x_favblue"></i>' +
'</button>' +
'</div>' +
'<span class="pluginButtonLabel">Share</span>' +
'</div>' +
'</div>' +
'</div>' +
'<div class="facebookCount">' +
'<div class="pluginCountButton pluginCountNum">' +
'<span ng-transclude></span>' +
'</div>' +
'<div class="pluginCountButtonNub"><s></s><i></i></div>' +
'</div>',
link: function (scope, element, attr) {
attr.$observe('url', function () {
if (attr.shares && attr.url) {
$http.get('https://api.facebook.com/method/links.getStats?urls=' + attr.url + '&format=json').success(function (res) {
var count = res[0] ? res[0].total_count.toString() : 0;
var decimal = '';
if (count.length > 6) {
if (count.slice(-6, -5) != "0") {
decimal = '.' + count.slice(-6, -5);
}
count = count.slice(0, -6);
count = count + decimal + 'M';
} else if (count.length > 3) {
if (count.slice(-3, -2) != "0") {
decimal = '.' + count.slice(-3, -2);
}
count = count.slice(0, -3);
count = count + decimal + 'k';
}
scope.shares = count;
}).error(function () {
scope.shares = 0;
});
}
element.unbind();
element.bind('click', function (e) {
FB.ui({
method: 'share',
href: attr.url
}, function (response) {
if (scope.callback !== undefined && typeof scope.callback === "function") {
scope.callback(response);
}
});
e.preventDefault();
});
});
}
};
}]).directive('facebookFeedShare', ['$http', function ($http) {
return {
scope: {
callback: '=',
shares: '='
},
transclude: true,
template: '<div class="facebookButton">' +
'<div class="pluginButton">' +
'<div class="pluginButtonContainer">' +
'<div class="pluginButtonImage">' +
'<button type="button">' +
'<i class="pluginButtonIcon img sp_plugin-button-2x sx_plugin-button-2x_favblue"></i>' +
'</button>' +
'</div>' +
'<span class="pluginButtonLabel">Share</span>' +
'</div>' +
'</div>' +
'</div>' +
'<div class="facebookCount">' +
'<div class="pluginCountButton pluginCountNum">' +
'<span ng-transclude></span>' +
'</div>' +
'<div class="pluginCountButtonNub"><s></s><i></i></div>' +
'</div>',
link: function (scope, element, attr) {
attr.$observe('url', function () {
if (attr.shares && attr.url) {
$http.get('https://api.facebook.com/method/links.getStats?urls=' + attr.url + '&format=json').success(function (res) {
var count = res[0] ? res[0].total_count.toString() : 0;
var decimal = '';
if (count.length > 6) {
if (count.slice(-6, -5) != "0") {
decimal = '.' + count.slice(-6, -5);
}
count = count.slice(0, -6);
count = count + decimal + 'M';
} else if (count.length > 3) {
if (count.slice(-3, -2) != "0") {
decimal = '.' + count.slice(-3, -2);
}
count = count.slice(0, -3);
count = count + decimal + 'k';
}
scope.shares = count;
}).error(function () {
scope.shares = 0;
});
}
element.unbind();
element.bind('click', function (e) {
FB.ui({
method: 'feed',
link: attr.url,
picture: attr.picture,
name: attr.name,
caption: attr.caption,
description: attr.description
}, function (response) {
if (scope.callback !== undefined && typeof scope.callback === "function") {
scope.callback(response);
}
});
e.preventDefault();
});
});
}
};
}]).directive('twitter', ['$timeout', function ($timeout) {
return {
link: function (scope, element, attr) {
var renderTwitterButton = debounce(function () {
if (attr.url) {
$timeout(function () {
element[0].innerHTML = '';
twttr.widgets.createShareButton(
attr.url,
element[0],
function () { }, {
count: attr.count,
text: attr.text,
via: attr.via,
size: attr.size
}
);
});
}
}, 75);
attr.$observe('url', renderTwitterButton);
attr.$observe('text', renderTwitterButton);
}
};
}]).directive('linkedin', ['$timeout', '$http', '$window', function ($timeout, $http, $window) {
return {
scope: {
shares: '='
},
transclude: true,
template: '<div class="linkedinButton">' +
'<div class="pluginButton">' +
'<div class="pluginButtonContainer">' +
'<div class="pluginButtonImage">in' +
'</div>' +
'<span class="pluginButtonLabel"><span>Share</span></span>' +
'</div>' +
'</div>' +
'</div>' +
'<div class="linkedinCount">' +
'<div class="pluginCountButton">' +
'<div class="pluginCountButtonRight">' +
'<div class="pluginCountButtonLeft">' +
'<span ng-transclude></span>' +
'</div>' +
'</div>' +
'</div>' +
'</div>',
link: function (scope, element, attr) {
var renderLinkedinButton = debounce(function () {
if (attr.shares && attr.url) {
$http.jsonp('https://www.linkedin.com/countserv/count/share?url=' + attr.url + '&callback=JSON_CALLBACK&format=jsonp').success(function (res) {
scope.shares = res.count.toLocaleString();
}).error(function () {
scope.shares = 0;
});
}
$timeout(function () {
element.unbind();
element.bind('click', function () {
var url = encodeURIComponent(attr.url).replace(/'/g, "%27").replace(/"/g, "%22")
$window.open("//www.linkedin.com/shareArticle?mini=true&url=" + url + "&title=" + attr.title + "&summary=" + attr.summary);
});
});
}, 100);
attr.$observe('url', renderLinkedinButton);
attr.$observe('title', renderLinkedinButton);
attr.$observe('summary', renderLinkedinButton);
}
};
}]).directive('gplus', [function () {
return {
link: function (scope, element, attr) {
var googleShare = debounce(function () {
if (typeof gapi == "undefined") {
(function () {
var po = document.createElement('script');
po.type = 'text/javascript';
po.async = true;
po.src = 'https://apis.google.com/js/platform.js';
po.onload = renderGoogleButton;
var s = document.getElementsByTagName('script')[0];
s.parentNode.insertBefore(po, s);
})();
} else {
renderGoogleButton();
}
}, 100);
//voodo magic
var renderGoogleButton = (function (ele, attr) {
return function () {
var googleButton = document.createElement('div');
var id = attr.id || randomString(5);
attr.id = id;
googleButton.setAttribute('id', id);
element.innerHTML = '';
element.append(googleButton);
if (attr.class && attr.class.indexOf('g-plusone') != -1) {
window.gapi.plusone.render(id, attr);
} else {
window.gapi.plus.render(id, attr);
}
}
}(element, attr));
attr.$observe('href', googleShare);
}
};
}]);
function debounce(func, wait, immediate) {
var timeout;
return function () {
var context = this,
args = arguments;
var later = function () {
timeout = null;
if (!immediate) func.apply(context, args);
};
var callNow = immediate && !timeout;
clearTimeout(timeout);
timeout = setTimeout(later, wait);
if (callNow) func.apply(context, args);
};
};
function randomString(len, an) {
an = an && an.toLowerCase();
var str = "",
i = 0,
min = an == "a" ? 10 : 0,
max = an == "n" ? 10 : 62;
for (; i++ < len;) {
var r = Math.random() * (max - min) + min << 0;
str += String.fromCharCode(r += r > 9 ? r < 36 ? 55 : 61 : 48);
}
return str;
}