在 DOM 被反应模板数据更改后流星调用 JS
Meteor call JS after DOM changed by reactive template data
我正试图在一个更大的项目中想办法解决这个问题,但我把这个小例子放在一起希望找到解决方案..
该示例是通过创建一个新的流星项目(使用流星 1.0.3.1)并添加 mizzao:bootstrap-3 并使用以下文件组合在一起的:
test.html
<head>
<title>test</title>
</head>
<body>
<div class="container-fluid">
<div class="row">
{{> example}}
</div>
{{> controls}}
</div>
</body>
<template name="example">
<div class="col-xs-{{zoom}}">
<div class="panel panel-default">
<div class="panel-heading">
<h3 class="panel-title"><span data-toggle="tooltip" data-placement="auto" title="Some text that will appear in the tooltip (which should be centered above or below this span) when hovering over the this span">Text that can spill out</span></h3>
</div>
<div class="panel-body">
<p>Foo</p>
</div>
</div>
</div>
</template>
<template name="controls">
<button id="in">+</button>
<button id="out">-</button>
</template>
test.css
.panel-title > span {
display: inline-block;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
.panel-title div.tooltip {
white-space: initial;
}
test.js
if (Meteor.isClient) {
var minZoom = 1;
var maxZoom = 4;
Session.setDefault('zoom', 4);
Template.example.helpers({
zoom: function () {
return Session.get('zoom');
}
});
Template.controls.events({
'click button': function(event) {
switch(event.currentTarget.id) {
case 'in':
if (Session.get('zoom') < maxZoom)
Session.set('zoom', Session.get('zoom') + 1);
break;
case 'out':
if (Session.get('zoom') > minZoom)
Session.set('zoom', Session.get('zoom') - 1);
break;
}
}
})
test = function() {
$('.panel-heading').each(function(index) {
var h3 = $(this).find('h3');
var span = $(this).find('span');
span.width('initial');
if (span.width() > h3.width()) {
span.width('100%');
}
});
$('[data-toggle="tooltip"]').tooltip();
}
Template.example.rendered = function() {
test();
}
}
希望它很清楚(ish)我想要实现的是跨度(在悬停时切换到工具提示)设置为与 h3 相同的宽度,否则跨度将超过 h3 的宽度h3 - 或者如果 h3 更大,则跨度设置为其默认值(内联/初始宽度)。这样做的原因是,当工具提示被初始化时,工具提示应该居中显示在跨度文本的上方(或下方)。
呈现模板时对 test() 的调用按预期工作(您可以更改 'zoom' 会话的默认值以在首次加载页面时更改面板的宽度 - 我一直在使用 1 和4 进行测试。
但是,当 DOM 由于反应性会话变量 'zoom' 发生更改而更新时,我需要调用 test() ,这在单击 + 或 - 按钮时发生。发生这种情况时,面板 class col-md-# 发生变化,其中 # 是缩放会话变量的值。
总而言之,DOM 发生了变化,但这并不是对我直接发出的 JavaScript 调用的响应,也不是由于订阅的数据发生变化,所以我不相信我可以使用 Tracker.afterFlush 回调。
由于缩放助手必须在 DOM 更新之前 return,我看不到调用任何特定事件触发的 'test()' 并向按钮的点击添加内容的方法发生得太早了有人有什么想法吗?
此外,据我所知,Mutation Observers 尚未得到广泛支持,因此这可能不是一个选项。
谢谢
如果我没听错的话,您实际上是在更改会话变量,并且希望在更改时进行回调?如果这是正确的,那么将该变量包装在自动运行函数中将在每次变量更改时执行它。
此外,如果仍然存在赛车问题,您可以在调用 test() 之前使用 setTimeout 并稍作延迟。
Tracker.autorun(function () {
Session.get('zoom');
test();
});
这是我在 Meteor 论坛上发帖后的无耻回答。
进行更改以引起反应性更改后,将 javascript 放入 Tracker.afterFlush
回调中。
我正试图在一个更大的项目中想办法解决这个问题,但我把这个小例子放在一起希望找到解决方案..
该示例是通过创建一个新的流星项目(使用流星 1.0.3.1)并添加 mizzao:bootstrap-3 并使用以下文件组合在一起的:
test.html
<head>
<title>test</title>
</head>
<body>
<div class="container-fluid">
<div class="row">
{{> example}}
</div>
{{> controls}}
</div>
</body>
<template name="example">
<div class="col-xs-{{zoom}}">
<div class="panel panel-default">
<div class="panel-heading">
<h3 class="panel-title"><span data-toggle="tooltip" data-placement="auto" title="Some text that will appear in the tooltip (which should be centered above or below this span) when hovering over the this span">Text that can spill out</span></h3>
</div>
<div class="panel-body">
<p>Foo</p>
</div>
</div>
</div>
</template>
<template name="controls">
<button id="in">+</button>
<button id="out">-</button>
</template>
test.css
.panel-title > span {
display: inline-block;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
.panel-title div.tooltip {
white-space: initial;
}
test.js
if (Meteor.isClient) {
var minZoom = 1;
var maxZoom = 4;
Session.setDefault('zoom', 4);
Template.example.helpers({
zoom: function () {
return Session.get('zoom');
}
});
Template.controls.events({
'click button': function(event) {
switch(event.currentTarget.id) {
case 'in':
if (Session.get('zoom') < maxZoom)
Session.set('zoom', Session.get('zoom') + 1);
break;
case 'out':
if (Session.get('zoom') > minZoom)
Session.set('zoom', Session.get('zoom') - 1);
break;
}
}
})
test = function() {
$('.panel-heading').each(function(index) {
var h3 = $(this).find('h3');
var span = $(this).find('span');
span.width('initial');
if (span.width() > h3.width()) {
span.width('100%');
}
});
$('[data-toggle="tooltip"]').tooltip();
}
Template.example.rendered = function() {
test();
}
}
希望它很清楚(ish)我想要实现的是跨度(在悬停时切换到工具提示)设置为与 h3 相同的宽度,否则跨度将超过 h3 的宽度h3 - 或者如果 h3 更大,则跨度设置为其默认值(内联/初始宽度)。这样做的原因是,当工具提示被初始化时,工具提示应该居中显示在跨度文本的上方(或下方)。 呈现模板时对 test() 的调用按预期工作(您可以更改 'zoom' 会话的默认值以在首次加载页面时更改面板的宽度 - 我一直在使用 1 和4 进行测试。 但是,当 DOM 由于反应性会话变量 'zoom' 发生更改而更新时,我需要调用 test() ,这在单击 + 或 - 按钮时发生。发生这种情况时,面板 class col-md-# 发生变化,其中 # 是缩放会话变量的值。
总而言之,DOM 发生了变化,但这并不是对我直接发出的 JavaScript 调用的响应,也不是由于订阅的数据发生变化,所以我不相信我可以使用 Tracker.afterFlush 回调。 由于缩放助手必须在 DOM 更新之前 return,我看不到调用任何特定事件触发的 'test()' 并向按钮的点击添加内容的方法发生得太早了有人有什么想法吗?
此外,据我所知,Mutation Observers 尚未得到广泛支持,因此这可能不是一个选项。
谢谢
如果我没听错的话,您实际上是在更改会话变量,并且希望在更改时进行回调?如果这是正确的,那么将该变量包装在自动运行函数中将在每次变量更改时执行它。
此外,如果仍然存在赛车问题,您可以在调用 test() 之前使用 setTimeout 并稍作延迟。
Tracker.autorun(function () {
Session.get('zoom');
test();
});
这是我在 Meteor 论坛上发帖后的无耻回答。
进行更改以引起反应性更改后,将 javascript 放入 Tracker.afterFlush
回调中。