最小形式BACK按钮questionNumber interference

时间:2017-01-08 07:12:17

标签: javascript jquery css

我在Codrops form添加了一个后退按钮。

这是我网站上的webpage,其中包含已实施的表单。

问题在于,如果用户快速按下后退按钮(前一个问题),则questionNumber计数器会重叠,数字最终会混淆。

有人可以帮忙吗?

完整的JavaScriptCSS下面的代码段是主要关注点。

.simform .number {
	position: absolute;
	right: 0;
	overflow: hidden;
	margin: 0.4em 0;
	width: 3em;
	font-weight: 700;
	font-size: 0.4em;
}

.simform .number:after {
	position: absolute;
	left: 50%;
	content: '/';
	opacity: 0.4;
	-webkit-transform: translateX(-50%);
	transform: translateX(-50%);
}

.simform .number span {
	float: right;
	width: 40%;
	text-align: center;
}

.simform .number .number-current {
	float: left;
}

.simform .number-next {
	position: absolute;
	left: 0;
}

.simform.show-next .number-current {
	-webkit-transition: -webkit-transform 0.4s;
	transition: transform 0.4s;
	-webkit-transform: translateY(-100%);
	transform: translateY(-100%);
}

.simform.show-next .number-next {
	-webkit-animation: moveUpFromDown 0.4s both;
	animation: moveUpFromDown 0.4s both;
}

.simform.show-previous .number-current {
	-webkit-transition: -webkit-transform 0.4s;
	transition: transform 0.4s;
	-webkit-transform: translateY(100%);
	transform: translateY(100%);
}

.simform.show-previous .number-next {
	-webkit-animation: moveDownFromUp 0.4s both;
	animation: moveDownFromUp 0.4s both;
}

4 个答案:

答案 0 :(得分:1)

修复:

a)更改第275行附近的部分:

// changes the current question number
stepsForm.prototype._updateQuestionNumber = function() {

    if (this.nextQuestionNum) this.questionStatus.removeChild( this.nextQuestionNum ); // remove if it still exists (when user clicks forwards or back before animation ends)
    this.nextQuestionNum = document.createElement( 'span' );

    this.nextQuestionNum.className = 'number-next';
    this.nextQuestionNum.innerHTML = Number( this.current + 1 );
    // insert it in the DOM
    this.questionStatus.appendChild( this.nextQuestionNum );
};

b)更改第195行附近的部分:

    // after animation ends, remove class "show-next" from form element and change current question placeholder
    var self = this,
        onEndTransitionFn = function( ev ) {
            if( support.transitions ) {
                this.removeEventListener( transEndEventName, onEndTransitionFn );
            }
            if( self.isFilled ) {
                self._submit();
            }
            else {
                classie.removeClass( self.el, 'show-next' );
                self.currentNum.innerHTML = self.nextQuestionNum.innerHTML;
                self.questionStatus.removeChild( self.nextQuestionNum );
                self.nextQuestionNum = null; // set to null to indicate that it has been removed

                // force the focus on the next input
                nextQuestion.querySelector( 'input' ).focus();
            }
        };

b)更改第257行附近的部分:

    // after animation ends, remove class "show-previous" from form element and change current question placeholder
    var self = this,
        onEndTransitionFn = function( ev ) {
            if( support.transitions ) {
                this.removeEventListener( transEndEventName, onEndTransitionFn );
            }
            if( self.isFilled ) {
                self._submit();
            }
            else {
                classie.removeClass( self.el, 'show-previous' );
                self.currentNum.innerHTML = self.nextQuestionNum.innerHTML;
                self.questionStatus.removeChild( self.nextQuestionNum );
                self.nextQuestionNum = null; // set to null to indicate that it has been removed

                // force the focus on the next input
                previousQuestion.querySelector( 'input' ).focus();
            }
        };

说明:

问题在于这一部分:

// changes the current question number
    stepsForm.prototype._updateQuestionNumber = function() {
        // first, create next question number placeholder
        this.nextQuestionNum = document.createElement( 'span' );
        this.nextQuestionNum.className = 'number-next';
        this.nextQuestionNum.innerHTML = Number( this.current + 1 );
        // insert it in the DOM
        this.questionStatus.appendChild( this.nextQuestionNum );
    };

具体来说,就是this.nextQuestionNum = document.createElement( 'span' );行。

正在发生的事情是创建span并保留对它的引用(this.nextQuestionNum)。动画完成后,使用该引用销毁该元素。

当用户点击太快(即比动画运行得快)时,上面的代码会再次执行,因此会创建一个新的span并保留对它的引用。此时,如果原始span尚未删除,则代码已丢失其指向它并像恶臭一样挂起。

因此if语句检查它是否为空并将其删除。

答案 1 :(得分:1)

你可以在控制台中看到你有一个"未捕获的DOMException:无法执行' removeChild' on'节点':要删除的节点不是此节点的子节点。在HTMLDivElement.onEndTransitionFn(http://dundaah.com/days/js/contactForm.js:255:26)"。

我怀疑当你快速按下按钮时,你几乎同时发送了两个事件,它们试图删除相同的节点(并可能在某处重新添加)。执行self.questionStatus.removeChild( self.nextQuestionNum );

时,需要确保Dom节点存在

答案 2 :(得分:1)

正在发生的是这个功能:

// changes the current question number
stepsForm.prototype._updateQuestionNumber = function() {
    // first, create next question number placeholder
    this.nextQuestionNum = document.createElement( 'span' );
    this.nextQuestionNum.className = 'number-next';
    this.nextQuestionNum.innerHTML = Number( this.current + 1 );
    // insert it in the DOM
    this.questionStatus.appendChild( this.nextQuestionNum );
};
当按钮是上一个按钮或按下下一个按钮时,

正在创建一个新的span元素。 之后调用函数stepsForm.prototype._previousQuestion运行此代码块:

// after animation ends, remove class "show-previous" from form element and change current question placeholder
        var self = this,
            onEndTransitionFn = function( ev ) {
                if( support.transitions ) {
                    this.removeEventListener( transEndEventName, onEndTransitionFn );
                }
                if( self.isFilled ) {
                    self._submit();
                }
                else {
                    classie.removeClass( self.el, 'show-previous' );
                    self.currentNum.innerHTML = self.nextQuestionNum.innerHTML;
                    self.questionStatus.removeChild( self.nextQuestionNum );
                    // force the focus on the next input
                    previousQuestion.querySelector( 'input' ).focus();
                }
            };

问题是,当快速按下按钮时,第一个函数在第二个代码块能够删除第一个子节点之前运行两次,因此它只删除一个子节点,而另一个子节点保留在文档中。

您可以尝试移动此行

self.questionStatus.removeChild( self.nextQuestionNum );

进入stepsForm.prototype._updateQuestionNumber函数并进行一些简单的验证以避免可能的错误,如下所示:

// changes the current question number
stepsForm.prototype._updateQuestionNumber = function() {
    // if nextQuestionNum exists remove it
    if (this.nextQuestionNum.innerHTML){
        self.questionStatus.removeChild( self.nextQuestionNum );
    }
    // first, create next question number placeholder
    this.nextQuestionNum = document.createElement( 'span' );
    this.nextQuestionNum.className = 'number-next';
    this.nextQuestionNum.innerHTML = Number( this.current + 1 );
    // insert it in the DOM
    this.questionStatus.appendChild( this.nextQuestionNum );
};

答案 3 :(得分:1)

从每个人那里得到很好的澄清,当用户快速点击背面(或者下一个,脚本在下一次快速点击时断开)时,你会尝试删除那些不再存在的东西。快速修复可能是在onEndTransitionFn函数中查询要选择的节点(第一个拾取的节点始终是您想要的节点)。

self
    .nextQuestionNum
    .parentNode
    .removeChild(self.nextQuestionNum.parentNode.querySelector('.number-next'))