Javascript jQuery appendTo()而不重新加载嵌入内容
我用jQuery编写了一个堆叠函数,它接受容器元素Javascript jQuery appendTo()而不重新加载嵌入内容,javascript,jquery,twitter,Javascript,Jquery,Twitter,我用jQuery编写了一个堆叠函数,它接受容器元素。搜索结果,收集容器中每个.col元素中的所有.card元素,然后跨多个列重新锁定它们,这些列是根据容器的宽度计算的 加载页面时,所有卡在第一列中初始化,后续列隐藏。然后,脚本取消隐藏它确定应该存在的列的数量,并使用appendTo在列和卡片之间迭代,以便将卡片均匀分布 我创建了一个演示该过程的示例 当在页面加载时调用脚本时,它工作得非常好。如果我想在页面加载后调用脚本,我会遇到一个严重的问题。如果我移除其中一张卡,并希望重新打包它们,以便分布保
。搜索结果
,收集容器中每个.col
元素中的所有.card
元素,然后跨多个列重新锁定它们,这些列是根据容器的宽度计算的
加载页面时,所有卡在第一列中初始化,后续列隐藏。然后,脚本取消隐藏它确定应该存在的列的数量,并使用appendTo
在列和卡片之间迭代,以便将卡片均匀分布
我创建了一个演示该过程的示例
当在页面加载时调用脚本时,它工作得非常好。如果我想在页面加载后调用脚本,我会遇到一个严重的问题。如果我移除其中一张卡,并希望重新打包它们,以便分布保持均匀,我必须再次调用堆叠函数。当我这样做时,会导致卡中的嵌入内容(例如嵌入Tweets)被重新加载,这是不可取的。请注意,当页面加载时,tweet在调用stacking函数之后才会初始化
在我的示例中,我故意使用twttr.widgets.createTweet()
对tweet ID进行迭代,以重新初始化它们,但是如果我忽略了该步骤,则在重新标记卡后tweet将消失。如果我检查这些卡,我可以看到Tweet小部件iframe仍然存在,但是iframe的主体
是空的
现在很明显,我可以在重新打包卡片后简单地重新初始化我的Tweet,但这会提供糟糕的用户体验,因为(重新)初始化嵌入式Tweet时会有延迟。我之前曾提出过与此相关的建议。我发现我可以使用.clone()
和appendTo()
从控制台手动移动卡片,而无需重新加载嵌入的tweet,但是我没有幸重构堆叠函数来利用这种行为,这就是我问这个问题的原因
这是我的堆叠功能:
function resizeColumns(layoutElem, ignoreRank, width) {
if (width === undefined) {
var colMin = 300;
} else {
var colMin = width;
}
var w = layoutElem.width();
var numCols = Math.floor(w / colMin);
if (numCols === 0) numCols = 1;
layoutElem.removeClass('cols-1 cols-2 cols-3 cols-4 cols-5 cols-6 cols-7 cols-8 cols-9 cols-10 cols-11 cols-12');
layoutElem.addClass('cols-' + numCols);
var cols = layoutElem.find('.col');
var cards = cols.find('.card');
var sortedCards = [];
cards.each(function(i) {
var rank;
if (!ignoreRank) {
rank = parseInt($(this).attr('rank'));
if (isNaN(rank)) rank = 1000000;
} else {
var o = parseInt($(this).attr('order'));
if (isNaN(o)) {
rank = i;
$(this).attr('order', i);
} else {
rank = o;
}
}
sortedCards.push({
rank: rank,
element: $(this)
});
});
sortedCards.sort(rankCompare);
var curCol = 0;
for (var i in sortedCards) {
var cardElem = sortedCards[i].element;
cardElem.appendTo($(cols[curCol]));
curCol++;
if (curCol >= numCols) curCol = 0;
}
// hide any additional columns
cols.each(function(i) {
if (i >= numCols) {
$(this).hide();
} else {
$(this).show();
}
});
function rankCompare(a, b) {
if (a.rank < b.rank)
return -1;
if (a.rank > b.rank)
return 1;
return 0;
}
}
在调用resizeColumns
函数后,我在第一次初始化tweet之前设置了一个延迟。这对于twitterwidgets脚本能够在DOM中定位Tweets是至关重要的
一旦Tweets被初始化,我设置了一个4s的延迟,然后移除一张卡并重新打包卡。最后,一旦卡片重新打包,我会重新初始化推文。这最后一步是我想要避免的。我不想重新初始化tweet,因为这是一个缓慢的过程。我希望推特在移动卡片后立即重新出现
$timeout(function() {
// Iterate over the Tweet IDs and initialize them.
ids.forEach(function(id) {
twttr.widgets.createTweet(id, document.getElementById(id));
});
$timeout(function() {
// Wait a few seconds and then remove a card from the DOM.
$('#' + $scope.cards[1].id).detach();
// Restack cards
resizeColumns($('.cards'), true, 250);
$timeout(function() {
// Reinitialize Tweets after cards have been restacked. This is the step I want to avoid.
ids.forEach(function(id) {
twttr.widgets.createTweet(id, document.getElementById(id));
});
}, 500)
}, 4000);
}, 1000);
根据另一个问题的答案,尝试更改:
sortedCards.push({
rank: rank,
element: $(this)
});
致:
或者您可以在appendTo
循环中执行克隆和分离:
for (var i in sortedCards) {
var cardElem = sortedCards[i].element.clone();
cardElem.appendTo($(cols[curCol]));
sortedCards[i].element.detach()
curCol = (curCol + 1) % numCols;
}
关于如何将
.clone()
应用于函数,我有相同的想法,但我无法让它工作。在小提琴上测试,在第二次调用该函数后,tweet仍然消失。也就是说,我必须重新初始化它们,这是我想要避免的。我将我的代码添加到你的小提琴中,如何使它再次调用函数?我刚刚更新了我的问题,更清楚地解释了我堆叠/重新堆叠卡的步骤。让我知道这是否合理。我认为超时函数中的detach()
是问题所在。为什么在调用resizeColumns
之前需要这样做?我正在使用它来模拟用户隐藏其中一张卡。在我的实际应用程序中,这些卡有一个按钮来隐藏它们。这样做会切换一个布尔属性,该属性通过连接到该卡的ng if
块将该卡从DOM中移除。我不想尝试复制小提琴中的所有附加功能,所以我只使用了.detach()
。当然,我确实在实际的应用程序上测试了您的代码,但其行为与在fiddle中相同。
sortedCards.push({
rank: rank,
element: $(this).clone();
});
$(this).detach();
for (var i in sortedCards) {
var cardElem = sortedCards[i].element.clone();
cardElem.appendTo($(cols[curCol]));
sortedCards[i].element.detach()
curCol = (curCol + 1) % numCols;
}