我目前正在处理一组代码,每次发生某个ajax调用时都会运行.
要做到这一点,我使用下面的代码片段(它错误,因为我认为没有HTML或CSS,但这是好的,因为我只是试图显示我的代码):
$(document).ajaxStart(function() {
if ($('.spinner').length < 1) { //as there is no ajaxStop, this makes sure there is not already a spinner
$('body').prepend('<div class="spinner" title="Spinner stuck? Click to remove!"></div>');
}
$('body div').not('.spinner').css('opacity', '0.5'); //this is potentially unnecessary
});
//the rest of the ajax call is not included - just the .done()
.done(function(xhr) {
$('body div').not('.spinner').css('opacity', '0');
$('body').one('transitionend', function(e) {
$('body div').not('.spinner').remove();
$('body').append(xhr);
$('body div').not('.spinner').css('opacity', '0.1');
$('body').one('transitionend', function(e) {
$('body div').css('opacity', '1');
$('.spinner').remove();
});
});
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.1.0/jquery.min.js"></script>
正如你所看到的,我嵌套.one(‘transitionend’)s,我试图找出它是否正确(作为注释:该代码用于处理登录和注销ajax调用响应它大部分时间用于我的登录ajax调用,但目前不能用于注销ajax调用 – 我不认为它正在注册结束$(‘body div’).not(‘.spinner’).css( ‘不透明’,’0.1′);过渡,因为它就是冻结的地方).
我已经把this jsfiddle抛在了一起.它只是测试嵌套与未通过的事件处理程序.
它们(嵌套和未嵌套)似乎工作原理相同(如果你点击其中一个太多次就会冻结它们 – 它发生在嵌套和unnested上 – 但在我添加日志位之后似乎已经修复了 – $(‘#log span’).text($(‘#div1’).text());等).
这是一个片段中的jsfiddle:
var newCss = {
backgroundColor: 'blue',
width: '25%',
color: 'white'
};
var disabled = false;
$(document).on('click', '#div1', function(e) {
if (disabled) return;
notNested($(this));
});
$(document).on('click', '#div8', function(e) {
if (disabled) return;
nested($(this));
});
function notNested($this) {
disabled = true;
$this.css(newCss);
$('#log span').text($('#div1').text());
$('#div1').one('transitionend', function() {
$('#div2').css(newCss);
$('#log span').text($('#div2').text());
});
$('#div2').one('transitionend', function() {
$('#div3').css(newCss);
$('#log span').text($('#div3').text());
});
$('#div3').one('transitionend', function() {
$('#div4').css(newCss);
$('#log span').text($('#div4').text());
});
$('#div4').one('transitionend', function() {
$('#div5').css(newCss);
$('#log span').text($('#div5').text());
});
$('#div5').one('transitionend', function() {
$('#div6').css(newCss);
$('#log span').text($('#div6').text());
});
$('#div6').one('transitionend', function() {
$('#div7').css(newCss);
$('#log span').text($('#div7').text());
});
$('#div7').one('transitionend', function() {
$('div').removeAttr('style');
$('#log span').text('');
disabled = false;
});
}
function nested($this) {
disabled = true;
$this.css(newCss);
$('#log span').text($('#div8').text());
$('#div8').one('transitionend', function() {
$('#div9').css(newCss);
$('#log span').text($('#div9').text());
$('#div9').one('transitionend', function() {
$('#div10').css(newCss);
$('#log span').text($('#div10').text());
$('#div10').one('transitionend', function() {
$('#div11').css(newCss);
$('#log span').text($('#div11').text());
$('#div11').one('transitionend', function() {
$('#div12').css(newCss);
$('#log span').text($('#div12').text());
$('#div12').one('transitionend', function() {
$('#div13').css(newCss);
$('#log span').text($('#div13').text());
$('#div13').one('transitionend', function() {
$('#div14').css(newCss);
$('#log span').text($('#div14').text());
$('#div14').one('transitionend', function() {
$('#log span').text('');
$('div').removeAttr('style');
disabled = false;
});
});
});
});
});
});
});
}
body {
display: flex;
align-items: flex-start;
/* Can't remember if flex-start is default anyways*/
}
div {
display: inline-block;
width: 25%;
}
div > div {
border: 4px dotted red;
transition: .25s;
display: block;
width: 10%;
padding: 4px 8px;
margin: 16px 0px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.1.0/jquery.min.js"></script>
<div>
<div id="div1">1</div>
<div id="div2">2</div>
<div id="div3">3</div>
<div id="div4">4</div>
<div id="div5">5</div>
<div id="div6">6</div>
<div id="div7">7</div>
</div>
<div id="log">We got to: <span></span>
</div>
<div>
<div id="div8">8</div>
<div id="div9">9</div>
<div id="div10">10</div>
<div id="div11">11</div>
<div id="div12">12</div>
<div id="div13">13</div>
<div id="div14">14</div>
</div>
So thus, I am trying to figure out, which one is the better to use? Which causes less problems for the code/browser? etc. Is there a better way to control code which depends on transitions (or animations for that matter) to be in a certain state? (Looking for a matter of fact answer, not opinions, 07001)
我已经尝试过研究jQuery的.queue和.delay,但是无法在我的场景中工作(可能我使用它们错了).也许这是另一种可能性?我也知道setTimeout()是一种可能性,但为了保持同步,你需要在它之后嵌套元素(并且.one(‘transitionend’)似乎在大多数情况下都适用于你是否嵌套…)
更新:
基于此问题留下的以下评论:
Some minor pointers on your code, don’t do css in Jquery but append/prepend classes with the opacity value. Use variables instead of going through the DOM with every selector. – 07004
我更新了jsfiddle以更改类而不是直接更改CSS. Here是链接(同样,上面的jsfiddle链接已更新).
虽然,我不重复的意思是:
Use variables instead of going through the DOM with every selector.
如果这可能是我的问题的答案,也许有人明白他的意思可以在下面阐述?
最佳答案 你可以使用.queue(),$.map(); .one(“transitionend”)附加到当前转换元素,其中处理程序设置为next,当前元素转换完成时调用队列中的下一个函数;每个元素列的单个事件处理程序,利用.slice()将元素id以“div”开头的所有元素拆分为数组的两个或多个元素;将数组作为event.data传递给事件处理程序;使用$.grep(),.filil();过滤特定列;将元素.data(/ * name * /)的集合设置为true或false,以防止当转换正在进行时,当元素当前正在队列中转换时,转换效果的默认操作; .promise(),. then()在当前队列完成时执行任务
var newCss = {
backgroundColor: "blue",
width: "25%",
color: "white"
}
// define `log` variable as `"#log span"`
, log = $("#log span")
// define `divs` variable as all elements where `id` begins with`` "div"
, divs = $("[id^=div]")
// define `col1` variable as `divs` at indexes `0` through `7`
, col1 = divs.slice(0, 7)
// define `col2` variable as `divs` at indexes `7` through `div.length`
, col2 = divs.slice(7, divs.length);
function queueColumn(col, name) {
// set current collection of elements `.data("active")` to `true`
return col.data("active", true)
// set a queue name with `name`, call `$.map()` on current collection
.queue(name, $.map(col, function(div) {
// return a function at queue `name` for each element in collection
return function(next) {
// set `log` text
log.text(
// pass reference of `next` function in queue `name`
// as handler for `transitionend` event of current element;
// call `next` function in queue `name`
// at `transitionend` event of element
$(div).one("transitionend", next).css(newCss).text()
)
}
// call first function in queue;
// when all function in queue `name` complete,
// return queue `name` jQuery promise object
})).dequeue(name).promise(name)
}
// handle `click` event at `#div1`, `#div8` elements
function handleQueue(e) {
// define `curr` variable;
// filter array containing `col1`, `col2` collections
// to match collection containing `#div1` or `#div8`
var curr = $.grep(e.data, function(col) {
return col.filter(e.target).length
}).pop();
// create `name` for queue
var name = `col${$.inArray(curr, e.data) + 1}-${$.now()}`;
// check if `curr` `.data("active")` is `undefined`
// at first click of element, if true,
// set `curr` `.data("active")` to `false`
if (curr.data("active") === undefined) {
curr.data("active", false);
}
if (curr.data("name") === undefined) {
curr.data("name", name);
}
console.log(`queue ${curr.data("name")} is active:`
, `${!curr.queue(name).length
|| curr.data("active")}`);
// define `inprogress` as `curr.data().active`
var inprogress = curr.data().active;
// check if `inprogress` is `false`, if true, call call `queueColumn`
// with `curr`, `name` as parameters
// if `#div1` or `#div8` element are clicked during
// during queue, while `inprogress` is `true`,
// return `false` from event handler to prevent
// multiple queues to be set at `curr` at same time
return !inprogress
? queueColumn(curr, name)
// do stuff when current queue `name` completes
// calling all functions in queue array
.then(function() {
console.log(`${this.data("name")} queue complete`);
// remove element `style`, reset `.data()`
this.removeAttr("style")
.data({"active": false, "name": void 0});
})
// else return `false`
: inprogress
}
// at `click` of `#div1`, `#div8`, call `handleQueue`,
// pass array containing `col1`, `col2` as `event.data`
$("#div1, #div8").click([col1, col2], handleQueue);
body {
display: flex;
align-items: flex-start;
/* Can't remember if flex-start is default anyways*/
}
div {
display: inline-block;
width: 25%;
}
div > div {
border: 4px dotted red;
transition: .25s;
display: block;
width: 10%;
padding: 4px 8px;
margin: 16px 0px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.1.0/jquery.min.js">
</script>
<div>
<div id="div1">1</div>
<div id="div2">2</div>
<div id="div3">3</div>
<div id="div4">4</div>
<div id="div5">5</div>
<div id="div6">6</div>
<div id="div7">7</div>
</div>
<div id="log">We got to: <span></span>
</div>
<div>
<div id="div8">8</div>
<div id="div9">9</div>
<div id="div10">10</div>
<div id="div11">11</div>
<div id="div12">12</div>
<div id="div13">13</div>
<div id="div14">14</div>
</div>