ここでは、フォームとやりとりするスクリプトがあります。それはうまく動作しますが、私たちはそれを完全なものと呼べる前に、いくつかの相違があります。JavaScriptを使用したインタラクティブスクリプト
スクリプトは、ユーザーが選択した内容に応じて応答する複数の質問をします。
名、ベッドルーム、ストーリー、スタイルを次のように
質問の順序があります。
私には2つの問題があります。
1)名前を入力せずに最初の入力フィールドをスキップできます。私はユーザーが名前を入力することを確認する必要があります。
2)「ストーリー」>「スタイル」に移動したときに無効な応答が返されます。どうして?
もし私が偉大な助けを得ることができたら。
乾杯
window.addEventListener('load', function()
{
// Create our node store, allowing us easy access to the nodes in the future.
var nodes = {};
nodes.consultant = document.querySelector('#consultant');
nodes.scope = nodes.consultant.querySelector('.col');
nodes.response = nodes.scope.querySelector('.consultant-response');
nodes.question = nodes.scope.querySelector('.consultant-question');
nodes.input = nodes.scope.querySelector('.consultant-input-wrap');
nodes.image = nodes.consultant.querySelector('.consultant-image');
nodes.dots = nodes.scope.querySelector('.consultant-dots');
var clientName = '';
// This variable will store the current question.
var question;
// Create our question store, we will iterate through these by shifting the
// first item off and replacing the question variable with it. Once the
// client has responded to the question, it will be pushed in the responses
// store below.
var questions = [
{
name: 'name',
question: 'Let’s start now. You know my name. What’s yours?',
image: 'consultant-introduction.png',
input: (function()
{
var form = document.createElement('form');
var input = document.createElement('input');
input.placeholder = 'Enter your name';
input.className = 'consultant-input';
form.appendChild(input);
var submit = document.createElement('button');
submit.className = 'fa fa-chevron-right';
form.appendChild(submit);
return form;
})(),
response: function(name)
{
if (typeof name === 'undefined')
{
return;
}
question.image = 'consultant-bedroom-question.png';
clientName = name;
return "Hey " + name + ". Great to meet you. I’ve got a couple of questions about the new home you want to build.";
}
},
{
name: 'bedrooms',
question: "How many bedrooms would you like?",
input: document.querySelector('[name="_sfm_bedrooms[]"]').cloneNode(true),
original: document.querySelector('[name="_sfm_bedrooms[]"]'),
response: function(bedrooms)
{
if (typeof bedrooms === 'undefined')
{
return;
}
var response = '';
switch (+bedrooms)
{
case 5:
response = "Five! Sounds like you need plenty of room for the family and a guest or three.";
question.image = 'consultant-five-bedroom-answer.png';
break;
case 4:
response = "4 bedrooms, great! We’ve got plenty of ideas for you already.";
question.image = 'consultant-four-bedroom-answer.png';
break;
case 3:
response = "Brilliant, 3 bedrooms. We love smaller but perfectly formed homes too.";
question.image = 'consultant-three-bedroom-answer.png';
break;
default:
response = "Well that isn't a valid response...";
question.image = '';
}
return response;
}
},
{
name: 'levels',
question: function(bedrooms)
{
if (typeof bedrooms === 'undefined')
{
return;
}
var question = '';
switch (+bedrooms)
{
case 5:
question = "Does that mean you want two storeys as well or would you rather spread out over one?";
break;
case 4:
question = "How high would you like to go? One or two storeys?";
break;
case 3:
question = "Does that mean you’re after a single storey home or two levels maybe? ";
break;
default:
}
return question;
},
input: document.querySelector('[name="_sfm_levels[]"]').cloneNode(true),
original: document.querySelector('[name="_sfm_levels[]"]'),
response: function(levels)
{
var response = '';
switch (+levels)
{
case 2:
response = "Thanks " + clientName + ", two storeys will give you a lot of flexibility.";
question.image = 'consultant-two-storey-answer.png';
break;
case 1:
response = "Nice " + clientName + ", a single storey home is a great option.";
question.image = 'consultant-one-storey-answer.png';
break;
default:
response = "Well that isn't a valid response...";
question.image = '';
}
return response;
}
},
{
name: 'style',
question: "I’ve got one more question, do you like contemporary or traditional style homes?",
image: 'consultant-style-answer.png',
input: document.querySelector('[name="_sfm_style[]"]').cloneNode(true),
original: document.querySelector('[name="_sfm_style[]"]'),
response: function(style)
{
var response = '';
switch (style)
{
case 'Traditional':
response = "You can’t beat the classics eh! Brilliant, check out a few ideas we think you’ll like below.";
break;
case 'Modern':
response = "Great, you’re after something a little more modern. Check out a few ideas we think you’ll like below.";
break;
default:
response = "Well that isn't a valid response...";
question.image = '';
}
return response;
}
},
{
name: 'done',
question: "Remember, these plans are just a starting point. We can completely customise any of them to suit your needs perfectly.",
input: (function()
{
var wrap = document.createElement('div');
wrap.className = 'consultant-done-wrap';
var elmnt = document.createElement('a');
elmnt.className = 'consultant-done fa fa-angle-down';
elmnt.href = "#find-a-plan";
wrap.appendChild(elmnt);
return wrap;
})()
}
];
// Once a client responds to a question, that question object will be added
// to this array.
var responses = [];
// Create our function store, this helps organize our functions, but also
// prevents conflict with existing function names.
var funcs = {};
// Prompt the user with the new question.
funcs.prompt = function(e)
{
// Cancel the default event if an event object is supplied
if (typeof e !== 'undefined' && typeof e.preventDefault === 'function')
{
e.preventDefault();
}
// Store the previous response if it is available, so that we can pass
// it to the question function.
var previous = {};
if (typeof question !== 'undefined')
{
if (question.input instanceof HTMLElement)
{
// If the input field is a form element, we have to search for
// the input element.
if (/form/i.test(question.input.tagName))
{
previous.value = question.input.querySelector('input').value;
}
else
{
previous.value = question.input.value;
}
// If there was no selected value, or the value is empty, stop here
if (typeof previous === 'undefined' || previous.length === 0)
{
return;
}
}
// Check if the response field is supplied
if (typeof question.response !== 'undefined')
{
if (typeof question.response === 'function')
{
// If the response is a function, call it with the value of the input,
// and apply the output to the response node.
nodes.response.innerHTML = question.response(previous.value);
}
else
{
// If it isn't a function, apply the value to the response node.
nodes.response.innerHTML = question.response;
}
// Push the current question onto the response array.
responses.push(question);
// Remove the current input element.
nodes.input.removeChild(question.input);
}
// Just a check to make sure the dot element is actually an element,
// safety first!
if (question.dot instanceof HTMLElement)
{
// Set the dot for the current question as active.
question.dot.className += ' active';
}
previous.question = question;
}
// Assign the new question to the current question variable.
// This removes the first question from the question store.
question = questions.shift();
// If we are on the first question, load the image for this question.
if (typeof previous.question === 'undefined')
{
previous.question = question;
}
// If there is an image attached to the previous question, show it.
// This is usually set in the response field, so we can know what the response was.
if (typeof previous.question.image !== 'undefined')
{
if (nodes.image instanceof HTMLElement)
{
nodes.image.style.backgroundImage = 'url(' + previous.question.image + ')';
}
}
// Check to see if the question field is set.
if (typeof question.question !== 'undefined')
{
if (typeof question.question === 'function')
{
// If the question is a function, call it and apply the output
// to the question node.
nodes.question.innerHTML = question.question(previous.value);
}
else
{
// If it isn't a function, apply the value to the question node.
nodes.question.innerHTML = question.question;
}
}
// Check if the input field is an HTML element
if (question.input instanceof HTMLElement)
{
// If it is, insert it into the input container.
nodes.input.appendChild(question.input);
}
// Check to see if we are on the last question or not.
if (question.name !== 'done')
{
// If not, check if the input element is an HTML element
if (question.input instanceof HTMLElement)
{
// Make sure the input element isn't actually a form element.
if (!/form/i.test(question.input.tagName))
{
// Apply the styling to the input element.
question.input.className += ' consultant-input';
// Apply the event listener to the input element.
question.input.addEventListener('change', funcs.prompt, false);
}
else
{
// Apply the event listener to the input element.
question.input.addEventListener('submit', funcs.prompt, false);
}
}
}
else
{
// If we are on the last question, remove the dots and update the originals.
nodes.scope.removeChild(nodes.dots);
funcs.updateAllInputs();
}
};
// Update an individual input.
funcs.updateInput = function(response)
{
// If no original element was passed, exit the function
if (typeof response.original === 'undefined')
{
return;
}
// Check to see if the original field is actually an HTML element.
if (response.original instanceof HTMLElement)
{
// Set the value of the original input to that of the client input.
response.original.value = response.input.value;
// This is because IE is stupid. We have to check if "fireEvent" is a function.
if ("fireEvent" in document)
{
// If it is, the user is browsing with IE, use the "fireEvent" function
response.original.fireEvent('onchange');
}
else
{
// If it isn't, the user is browsing with a real browser.
// Create a "change" event.
var event = new UIEvent("change",
{
"view": window,
"bubbles": true,
"cancelable": true
});
// Dispatch the "change" event
response.original.dispatchEvent(event);
}
}
};
// Update all of the inputs.
funcs.updateAllInputs = function()
{
// Iterate through the responses array.
for (var i in responses)
{
// This excludes the "length" field, only relevant on mobile devices.
if (responses.hasOwnProperty(i))
{
// Update the original input.
funcs.updateInput(responses[i]);
}
}
};
// Make the dots to show the progress through the consultant
funcs.makeDots = function()
{
// Iterate through the questions array.
for (var i in questions)
{
// This excludes the "length" field, only relevant on mobile devices.
if (questions.hasOwnProperty(i))
{
// Skip the last question.
if (questions[i].name === 'done')
{
continue;
}
// Make the dot
questions[i].dot = document.createElement('li');
// Append the dot to the dots container
nodes.dots.appendChild(questions[i].dot);
}
}
};
// Make the dots.
funcs.makeDots();
// Prompt the first question.
funcs.prompt();
}, false);
HTML
<section class="beige section-padding strip-wrap" id="consultant">
<div class="container entry clr">
<div class="clr col span_1_of_3 col-1">
<h1 class="red">Can I help?</h1>
<div class="white consultant-response">
Hi, I'm Glenda. Our job is to make your build as easy and tailored as possible.
</div>
<div class="orange consultant-question"></div>
<div class="consultant-input-wrap"></div>
<ul class="consultant-dots"></ul>
</div>
<div class="clr col span_2_of_3"></div>
<a href="#find-a-plan">
<div class="strip">These homes are a perfect starting point
<div class="strip-arrow"><i class="fa fa-chevron-down"></i></div>
</div>
</a>
</div>
<!-- .entry-content -->
<div class="consultant-showcase">
<div class="consultant-image">
<div class="consultant-introduction"></div>
<div class="consultant-bedroom-question"></div>
<div class="consultant-three-bedroom-answer"></div>
<div class="consultant-four-bedroom-answer"></div>
<div class="consultant-five-bedroom-answer"></div>
<div class="consultant-one-storey-answer"></div>
<div class="consultant-two-storey-aswer"></div>
<div class="consultant-style-answer"></div>
</div>
</div>
</section>
_ "1)名前を入力せずに最初の入力フィールドをスキップすることができます。" _必須属性を使用します。 Questionに 'html'を含めることができますか? – guest271314
@ guest271314 - 必要な属性はどこに配置する必要がありますか? – tebrown
'var input = document.createElement(" input "); input.setAttribute( "required"、true) ' – guest271314