Javascript 如何在<;头>;文件的一部分?
我不熟悉Javascript 如何在<;头>;文件的一部分?,javascript,html,angularjs,angularjs-directive,html-head,Javascript,Html,Angularjs,Angularjs Directive,Html Head,我不熟悉angular.js。我试图创建一个指令,在html文档的部分添加一些标题和元标记,但遇到了一些问题 我的index.html文档如下所示: <!DOCTYPE html> <html ng-app="myApp"> <head> <meta charset="UTF-8"> <base href="/"> <seo-title></seo-title> <scrip
angular.js
。我试图创建一个指令,在html文档的
部分添加一些标题和元标记,但遇到了一些问题
我的index.html
文档如下所示:
<!DOCTYPE html>
<html ng-app="myApp">
<head>
<meta charset="UTF-8">
<base href="/">
<seo-title></seo-title>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.4.1/angular.min.js"></script>
<script src="https://code.angularjs.org/1.4.1/angular-route.min.js"></script>
<script src="/incl/js/myApp.js"></script>
</head>
<body >
<div ng-view></div>
</body>
</html>
我的javascript是:
var app = angular.module ('myApp', ['ngRoute']);
app.config(['$routeProvider', '$locationProvider', function($routeProvider, $locationProvider) {
$routeProvider
.when('/', { templateUrl: 'routes/home.html'})
.when('/pageA', { templateUrl: 'routes/pageA.html'})
.when('/pageB', { templateUrl: 'routes/pageB.html'})
.otherwise({ redirectTo: '/' });
$locationProvider.html5Mode({
enabled: true
});
}]);
app.directive('seoTitle', function() {
return {
restrict: 'E',
template: '<title>{{seo.title}}</title>'
};
});
var-app=angular.module('myApp',['ngRoute']);
app.config(['$routeProvider','$locationProvider',函数($routeProvider,$locationProvider){
$routeProvider
.when('/',{templateUrl:'routes/home.html'})
.when('/pageA',{templateUrl:'routes/pageA.html'})
.when('/pageB',{templateUrl:'routes/pageB.html'})
。否则({重定向到:'/'});
$locationProvider.html5模式({
已启用:true
});
}]);
应用指令('seoTitle',函数(){
返回{
限制:'E',
模板:“{seo.title}”
};
});
当我打开inspector时,指令已移动到
,且未替换为模板:
如何在标题中创建指令
p.S.:一个代码示例将非常棒 您的答案是:,在您的代码中实现它可以是:
<!DOCTYPE html>
<html ng-app="myApp">
<head>
<meta charset="UTF-8">
<base href="/">
<title seo-title>doesn't work</title>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.4.1/angular.min.js"></script>
<script src="https://code.angularjs.org/1.4.1/angular-route.min.js"></script>
<script src="/incl/js/myApp.js"></script>
</head>
<body >
<div ng-view></div>
</body>
</html>
你只需要添加一个控制器或一些逻辑来设置你想要的标题。首先:我在inspector中查看,是的,不知怎么的,标题标签出现在正文中。但它似乎并不影响它的功能 现在来看解决方案:乍一看,似乎只有
seoTitle
指令的声明中缺少replace:true
。
添加它可以解决问题,并且seo title
按计划被替换为title
标记,但Angular会在创建新范围时将内容包装在一个额外的span
元素中(即使seoTag
的范围声明为隔离范围:{}
)
我提出了以下解决方案:
app.directive('seoTitle', function() {
function compile(elem, attrs, transclude) {
return function ($scope) {
transclude($scope, function (clone) {
elem.empty();
elem.append(clone[0].innerText);
});
};
}
return {
restrict: 'E',
replace: true,
transclude: true,
scope: {},
compile: compile,
template: '<title ng-transclude></title>',
};
});
app.directive('seoTitle',function(){
函数编译(elem、attrs、transclude){
返回函数($scope){
转移($范围、功能(克隆){
elem.empty();
元素追加(克隆[0].innerText);
});
};
}
返回{
限制:'E',
替换:正确,
是的,
作用域:{},
编译:编译,
模板:“”,
};
});
用法:
<seo-title>My Title</seo-title>
我的标题
如前所述,使用replace:true
可以删除包装seo标题
标签
要删除额外创建的span
元素,
我提供了compile
函数,返回postLink
函数
我真的无法解释,为什么我需要在postLink
函数中使用transclude
函数。
这似乎是一个非常常见的问题,在这种情况下,Angular会创建一个额外的span
元素。
通过一点尝试和错误,我发现摆脱
span
的最简单方法是emtpy()
元素并只附加内部文本
您的指令不需要进入标题来设置标题。只需让您的指令注入$window
并设置$window.document.title='your title'
更新这是更新元标记的方法
对于更新元标记,我将使用如下指令:
mmMetaTags.$inject = ['metaTags'];
function mmMetaTags(metaTags) {
return {
restrict: 'A',
link: function(scope, element) {
metaTags.metaTags.forEach(function(tag) {
addMetaTag(tag.name, tag.content)
});
metaTags.subscribe(addMetaTag);
function addMetaTag(name, content) {
var tag = element[0].querySelector('meta[name="' + name + '"]');
if (tag) {
tag.setAttribute('content', content);
} else {
element.append('<meta name="' + name + '" content="' + content + '">');
}
}
}
}
}
directive('mmMetaTags', mmMetaTags);
mmMetaTags.$inject=['metaTags'];
函数mmMetaTags(metaTags){
返回{
限制:“A”,
链接:功能(范围、元素){
metaTags.metaTags.forEach(函数(标记){
addMetaTag(tag.name、tag.content)
});
订阅(addMetaTag);
函数addMetaTag(名称、内容){
var tag=element[0]。querySelector('meta[name=“”+name+””);
如果(标签){
tag.setAttribute('content',content);
}否则{
元素。追加(“”);
}
}
}
}
}
指令(“mmMetaTags”,mmMetaTags);
以及设置元标记的服务:
function MetaTags() {
// private
this._tags = [];
// private
this._subscriber;
var self = this;
Object.defineProperty(this, 'metaTags', { get: function() {
return self._tags;
}});
}
MetaTags.prototype.addMetaTag = function(name, content) {
this._tags.push({ name: name, content: content });
this._updateSubscriber(name, content);
}
MetaTags.prototype.subscribe = function(callback) {
if (!this.subscriber) {
this._subscriber = callback;
} else {
throw new Error('Subscriber already attached. Only one subscriber may be added as there can only be one instance of <head>');
}
}
// private
MetaTags.prototype._updateSubscriber = function(name, content) {
this.subscriber(name, content);
}
service('metaTags', MetaTags);
函数元标记(){
//私人的
这个。_标签=[];
//私人的
这是您的订户;
var self=这个;
defineProperty(这是'metaTags',{get:function(){
返回self.\u标签;
}});
}
MetaTags.prototype.addMetaTag=函数(名称、内容){
this.\u tags.push({name:name,content:content});
此._更新订阅程序(名称、内容);
}
MetaTags.prototype.subscribe=函数(回调){
如果(!this.subscriber){
这。_subscriber=callback;
}否则{
抛出新错误('订阅服务器已连接。只能添加一个订阅服务器,因为只能有一个实例');
}
}
//私人的
MetaTags.prototype.\u updateSubscriber=函数(名称、内容){
此。订户(名称、内容);
}
服务(‘元标签’、元标签);
因此,在您的头
标记中,您将包含属性mm元标记
。然后在控制器中注入metaTags
服务并调用addMetaTag
更新标记 你可以试试图书馆。除了title之外,它还支持其他元标记(description、author、og:、twitter:,等等)angular.directive('ngHead',function(){
设strHtml='';
strHtml+='';
strHtml+='';
strHtml+='';
strHtml+='';
strHtml+='';
strHtml+=“标题”;
strHtml+='';
返回{
限制:“A”,
链接:函数(范围、元素、属性){
元素。追加(strHtml);
}
}
});
在您的html
为我工作。为什么您需要一个指令来添加元标记?从一开始就把它们放进去?标题可以从控制器eas设置
function MetaTags() {
// private
this._tags = [];
// private
this._subscriber;
var self = this;
Object.defineProperty(this, 'metaTags', { get: function() {
return self._tags;
}});
}
MetaTags.prototype.addMetaTag = function(name, content) {
this._tags.push({ name: name, content: content });
this._updateSubscriber(name, content);
}
MetaTags.prototype.subscribe = function(callback) {
if (!this.subscriber) {
this._subscriber = callback;
} else {
throw new Error('Subscriber already attached. Only one subscriber may be added as there can only be one instance of <head>');
}
}
// private
MetaTags.prototype._updateSubscriber = function(name, content) {
this.subscriber(name, content);
}
service('metaTags', MetaTags);
angular.directive('ngHead', function () {
let strHtml = '';
strHtml += '<meta charset="utf-8">';
strHtml += '<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">';
strHtml += '<meta http-equiv="x-ua-compatible" content="ie=edge">';
strHtml += '<meta name="google" content="notranslate" />';
strHtml += '<title>';
strHtml += ' title';
strHtml += '</title>';
return {
restrict: 'A',
link: function (scope, element, attrs) {
element.append(strHtml);
}
}
});