我正在将服务器上的短文本文件读入PHP变量($data
),并首先访问数组中的前2项以显示它们。
然后,当用户单击其中一个项目(也发送表单数据)时,我想增加指定数组项($counter
)的PHP变量。
从文件中读取似乎最容易使用PHP,但使用Javascript时点击增加似乎更容易 - 我无法找到一个很好的方法来伪造这两个。解决这个问题的最佳方法是什么?我对这两种语言都很陌生。
用于从文件(工作)中读取的php / html代码:
<?php
function getData($subtest_nr) {
$data = file("subtests/$subtest_nr.txt");
return $data;
}
$subtest_nr = "7";
$counter = 0;
$data = getData($subtest_nr); ?>
<form id="myform" method="post">
<div class="four_images">
<div class="flex-item">
<input type="radio" name="image" value="7.11" id="alt1" class="hidden">
<label for="alt1"><img src="images/<?php echo $data[$counter]; ?>"></label>
</div>
<div class="flex-item">
<input type="radio" name="image" value="7.12" id="alt2" class="hidden">
<label for="alt2"><img src="images/<?php echo $data[$counter+1] ?>"></label>
</div>
</div>
</form>
快速尝试在jQuery中增加变量:
jQuery(function($) {
var counter = 0;
$("img").click(function(){
counter++;
$("p").text(counter);
});
});
所以我的问题是,我是否应该只针对两种功能的PHP或Javascript / jQuery,或者我是否有办法合并这两种功能?
答案 0 :(得分:1)
这是一个粗略的例子,没有错误检查。我不是jQuery,所以你需要将其转换为使用jQuery的ajax方法。无法通过点击每个图片来说明您尝试实现的目标,因此您可以对其进行编辑。
我的主要目的是展示前端可以维护状态信息的方法,并可以使用它来从(愚蠢的)后端请求所需的信息。
file1.txt
file2.swf
file1.pdf
file1.exe
file1.asm
<?php
$firstItem = $_GET['firstItem'];
$numItems = $_GET['numItems'];
// should do error checking here
$subtestNumber = 7;
$filename = sprintf("subtests/%d.txt", $subtestNumber);
// dummy, used for testing
$filename = 'sampleInput.txt';
$fileHandle = fopen($filename, "rt");
for ($numLinesToSkip=0; $numLinesToSkip<$firstItem; $numLinesToSkip++)
fgets($fileHandle);
$results = array();
for ($itemCount=0; $itemCount<$numItems; $itemCount++)
{
$curLine = fgets($fileHandle);
//
// you may wish to remove the trailing new-line character here
//
array_push($results, $curLine);
}
fclose($fileHandle);
echo json_encode($results);
?>
<!doctype html>
<html>
<head>
<script>
"use strict";
function newEl(tag){return document.createElement(tag)}
function byId(id){return document.getElementById(id)}
// useful for HtmlCollection, NodeList, String types
function forEach(array, callback, scope){for (var i=0,n=array.length; i<n; i++)callback.call(scope, array[i], i, array);} // passes back stuff we need
function ajaxGet(url, onLoad, onError)
{
var ajax = new XMLHttpRequest();
ajax.onreadystatechange = function(){if (this.readyState==4 && this.status==200) onLoad(this);}
ajax.onerror = function() {error.log("ajax request failed to: "+url);onError(this);}
ajax.open("GET", url, true);
ajax.send();
}
/////////////////////
window.addEventListener('load', onDocLoaded, false);
function onDocLoaded(evt)
{
byId('goBtn').addEventListener('click', onGoBtnClicked);
}
function onGoBtnClicked(evt)
{
var firstIndex = byId('firstRecordInput').value;
var numItems = byId('numRecordsInput').value;
var url = 'getItems.php?firstItem=' + firstIndex + '&numItems=' + numItems;
ajaxGet(url, onDataReceived, function(){alert('ajax failed! :(');} )
}
/*
<div class="four_images">
<div class="flex-item">
<input type="radio" name="image" value="7.11" id="alt1" class="hidden">
<label for="alt1"><img src="images/<?php echo $data[$counter]; ?>"></label>
</div>
<div class="flex-item">
<input type="radio" name="image" value="7.12" id="alt2" class="hidden">
<label for="alt2"><img src="images/<?php echo $data[$counter+1] ?>"></label>
</div>
</div>
*/
function onDataReceived(ajax)
{
var rawData = ajax.response;
var parsedData = JSON.parse(rawData);
var div = newEl('div');
div.className = 'four_images';
forEach(parsedData, makeItem);
byId('myForm').innerHTML = '';
byId('myForm').appendChild(div);
function makeItem(dataItem, index, arrayOfItems)
{
var itemDiv = newEl('div');
itemDiv.className = 'flex-item';
var input = newEl('input');
input.type = 'radio';
input.name = 'image';
input.value = 'putSomethingUsefulHere';
input.id = "alt" + (index+1);
input.className = 'hidden';
var label = newEl('label');
label.for = 'alt' + (index+1);
var img = newEl('img');
img.src = 'images/' + dataItem;
label.appendChild(img);
itemDiv.appendChild(input);
itemDiv.appendChild(label);
div.appendChild(itemDiv);
}
}
</script>
<style>
.panel
{
border: solid 1px black;
border-radius: 8px;
padding: 8px;
background-color: #eef;
display:inline-block;
}
</style>
</head>
<body>
<div class='panel'>
<label>Index of first record: <input type='number' id='firstRecordInput' value='0'/></label><br>
<label>Number of records: <input type='number' id='numRecordsInput' value='2'/></label>
<hr>
<div style='text-align: center'><button id='goBtn'>Submit</button></div>
<hr>
<form id='myForm'>
</form>
</div>
</body>
</html>
答案 1 :(得分:1)
除了评论之外,这里还有一种方法,它将font-end和后端组合成一个文件。
该文件使用$ _SERVER ['PHP_SELF']变量来查找正在执行的文件的名称。我们使用它来编写后端php文件的正确名称以请求进入javascript - 这有助于我们将单文件解决方案命名为我们想要的任何内容,而不用担心在源代码中的某处更新硬编码的URL 。 (头部疼痛了吗?:p)
<?php
if ( isset($_GET['firstItem']) && isset($_GET['numItems']) )
{
$firstItem = $_GET['firstItem'];
$numItems = $_GET['numItems'];
// should do error checking here
$subtestNumber = 7;
$filename = sprintf("subtests/%d.txt", $subtestNumber);
// dummy, used for testing
$filename = 'sampleInput.txt';
$fileHandle = fopen($filename, "rt");
for ($numLinesToSkip=0; $numLinesToSkip<$firstItem; $numLinesToSkip++)
fgets($fileHandle);
$results = array();
for ($itemCount=0; $itemCount<$numItems; $itemCount++)
{
$curLine = fgets($fileHandle);
//
// you may wish to remove the trailing new-line character here
//
array_push($results, $curLine);
}
fclose($fileHandle);
echo json_encode($results);
die; // stop execution now - dont output the html below
}
?><!doctype html>
<html>
<head>
<script>
"use strict";
function newEl(tag){return document.createElement(tag)}
function byId(id){return document.getElementById(id)}
// useful for HtmlCollection, NodeList, String types
function forEach(array, callback, scope){for (var i=0,n=array.length; i<n; i++)callback.call(scope, array[i], i, array);} // passes back stuff we need
function ajaxGet(url, onLoad, onError)
{
var ajax = new XMLHttpRequest();
ajax.onreadystatechange = function(){if (this.readyState==4 && this.status==200) onLoad(this);}
ajax.onerror = function() {error.log("ajax request failed to: "+url);onError(this);}
ajax.open("GET", url, true);
ajax.send();
}
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////
window.addEventListener('load', onDocLoaded, false);
function onDocLoaded(evt)
{
byId('goBtn').addEventListener('click', onGoBtnClicked);
}
function onGoBtnClicked(evt)
{
var firstIndex = byId('firstRecordInput').value;
var numItems = byId('numRecordsInput').value;
// we want to request data from this same file, so get php to print it into the javascript source
var filename = '<?php echo $_SERVER['PHP_SELF'];?>';
// construct the url from the filename and the (GET) parameters we'd like to pass to the php
var url = filename + '?firstItem=' + firstIndex + '&numItems=' + numItems;
// ask for it, fire the onDataReceived function with the XMLHttpRequest object as the only input
ajaxGet(url, onDataReceived, function(){alert('ajax failed! :(');} )
}
/*
------------------------------------------------------------
format of html the onDataReceived function needs to create
- .four_images div just once for the whole response
- .flex-item once for each item returned
------------------------------------------------------------
<div class="four_images">
<div class="flex-item">
<input type="radio" name="image" value="7.11" id="alt1" class="hidden">
<label for="alt1"><img src="images/<?php echo $data[$counter]; ?>"></label>
</div>
<div class="flex-item">
<input type="radio" name="image" value="7.12" id="alt2" class="hidden">
<label for="alt2"><img src="images/<?php echo $data[$counter+1] ?>"></label>
</div>
</div>
*/
function onDataReceived(ajax)
{
// get the raw data - it'll be a string something like `["file1.txt\n","file2.swf\n"]`
var rawData = ajax.response;
// parse it and turn it from a string into some javascript objects.
// this has same the effect as typing the following into your source-code
//
// var parsedData = [ "file1.txt\n", "file2.swf\n" ];
//
// except, you can do it with unknown data. BUT: we must know the *format*
// of the data so we know what to do with it. We happen to know that
// the data will be an array
var parsedData = JSON.parse(rawData);
// make the outer wrapper - refer above for the structure of the created HTML
// this wrapper needs to exist so the makeItem function can append content
// to it in the forEach call
var div = newEl('div');
div.className = 'four_images';
// for each of the items in the parsedData array, call the makeItem function - once this forEach call is done,
// we have the contents of the form all sitting in the [div] element - the makeItem function is inside this onDataReceived function
// so that it can 'see' the [div] variable in order to append each item to it.
forEach(parsedData, makeItem);
// show the results
byId('myForm').innerHTML = '';
byId('myForm').appendChild(div);
// this function has now finished executing. the makeItem function exists here (unfortunately) so that
// the [div] element remains in scope.
// called with the current element in the collection as dataItem, it's index in the collection as index and the collection itself as arrayOfItems
// we're making use of the item's index to correctly set the id of the radio-button and then to make the label refer to it (which it doesn't actually
// need to do in this case, since the label element contains the input)
// another use of index is to place a comma between items i.e "1,2,3,4,5,6" - there are two approaches. The naive one is to place a comma after each
// item except the last one. To do this - we need to know how many items there are in total - sometimes this is very expensive to compute.
// the other approach, is to put a comma _before_ all items except the first one.
function makeItem(dataItem, index, arrayOfItems)
{
var itemDiv = newEl('div');
itemDiv.className = 'flex-item';
var input = newEl('input');
input.type = 'radio';
input.name = 'image';
input.value = 'putSomethingUsefulHere'; // **** the example had 7.11 and 7.12 here - I've no idea how they were determined ***
input.id = "alt" + (index+1);
input.className = 'hidden';
var label = newEl('label');
label.for = 'alt' + (index+1);
var img = newEl('img');
img.src = 'images/' + dataItem;
label.appendChild(img);
itemDiv.appendChild(input);
itemDiv.appendChild(label);
div.appendChild(itemDiv);
}
}
</script>
<style>
.panel
{
border: solid 1px black;
border-radius: 8px;
padding: 8px;
background-color: #eef;
display:inline-block;
}
</style>
</head>
<body>
<div class='panel'>
<label>Index of first record: <input type='number' id='firstRecordInput' value='0'/></label><br>
<label>Number of records: <input type='number' id='numRecordsInput' value='2'/></label>
<hr>
<div style='text-align: center'><button id='goBtn'>Retrieve records</button></div>
<hr>
<form id='myForm'>
</form>
</div>
</body>
</html>
答案 2 :(得分:0)
我猜你得到的数据是ajax数据。所以需要是$(文件).on(...
var counter = 0;
$(document).on('click','img', function(){
counter++;
$("p").text(counter);
});