背景:完成的是一个类似百度知道的互动问答社区,本人负责个人空间页面(包括展示用户提问内容、回答内容、个人信息修改、密码修改),问题搜索结果展示页面,提问页面和回答页面。使用语言html+js+css+php+sql,使用前端框架layui
具体问题解决(代码为简化版,与问题无关基本删除)
-
iframe高度无法自适应:当展示内容较多时未出现滚动条,iframe高度与外div设置的最小高度等高。多方查找后解决方式如下。给iframe的加载设置了一个函数定义其高度。
html页面:
<iframe src="" id="ii" name="show_frame" class="user_iframe" scrolling="no" onload="setIframeHeight(this)" frameborder="0">
</iframe>
js:先获取iframe的高度,再将高度设定为所加载文档的实际高度。
function setIframeHeight(iframe) {
if (iframe) {
//contentWindow只读属性,返回指定的iframe的窗口对象,再通过这个对象,获取到里面的DOM元素
var iframeWin = iframe.contentWindow || iframe.contentDocument.parentWindow;
if (iframeWin.document.body) {
//scrollHeight为层实际高度
iframe.height = iframeWin.document.documentElement.scrollHeight || iframeWin.document.body.scrollHeight;
}
}
}
window.onload = function () {
setIframeHeight(document.getElementById('ii'));
};
(用iframe嵌套页面时,如果父页面要获取子页面里面的内容,可以使用contentWindow或者contentDocument。
contentDocument 属性能够以 HTML 对象来返回 iframe 中的文档。可以通过所有标准的 DOM 方法来处理被返回的对象。)
2.希望放置在右上角的面包屑导航居中显示:且页面出现横向滚动条。给body加了overflow-x:hidden属性
overflow-x属性指定如果它溢出了元素的内容区是否剪辑左/右边缘内容。
visible | 不裁剪内容,可能会显示在内容框之外。 |
hidden | 裁剪内容 - 不提供滚动机制。 |
scroll | 裁剪内容 - 提供滚动机制。 |
3.内联框架(iframe)的使用:页面结构为左侧导航栏链接到右侧的iframe。将左侧<a>的target属性设置为右侧iframe的name
<dl>
<dd>
<a href="user_settings.php" target="show_frame">个人设置</a>
</dd>
<dd>
<a href="change_password.php" target="show_frame">修改密码</a>
</dd>
</dl>
<iframe name="show_frame">
</iframe>
4.内联框架里页面的超链接希望跳转到新页面 :非跳转到框架内。给该a标签增加 target="_parent "属性。即
<a href=" " target="_parent ">
5.关于建表:需要建立N个表格用于存放问题和回答,具体属性包括 问题标题、问题内容、回答内容、回答者id。(一开始建表的时候没考虑点赞功能,于是也没考虑和点赞功能有关的表的内容。点赞功能详见后文)表格建立可选方式有两种,多表关联和一字段多值。最后选择了多表关联,后续的点赞功能和一问题多回答等都证明了选择是正确的,缺点是SQL语句写起来比较复杂。分析过程如下:
多表关联 | 便于查询问题列表。 回答表以 问题id+答者id 为主键,便于依照用户id输出其回答的问题。 便于删除某条回答 | 查询语句关联较复杂 |
一字段多值 | 查询语句简单,只有问题id即可。 便于对是否有回答对问题进行分类 | 空间换时间。筛选用户回答的时候会麻烦,需要拆分后输出 |
6.修改密码:注意代码格式
HTML:
<form class = "layui-form" action = "update_psw.php" method = "POST">
<!--填写新密码-->
<div class = "layui-form-item">
<label class = "layui-form-label">新密码</label>
<div class = "layui-input-block">
<input type = "password" name = "new_pass" lay-verify = "required|newpsw" autocomplete = "off" class = "layui-input">
</div>
</div>
<!--重复新密码-->
<div class = "layui-form-item">
<label class = "layui-form-label">确认新密码</label>
<div class = "layui-input-block">
<input type = "password" name = "sec_pass" lay-verify = "required|secpsw" autocomplete = "off" class = "layui-input">
</div>
</div>
<br><br><br>
<!--提交按钮-->
<div class = "layui-form-item">
<div class = "layui-input-block" style = "float: right;">
<button type = "submit" class = "layui-btn" lay-submit = "" lay-filter = "demo1"
style = "border-radius: 5px;">立即提交</button>
<button type = "reset" class = "layui-btn layui-btn-primary" style = "border-radius: 5px;">重置</button>
</div>
</div>
</form>
js:
<script type = "text/javascript" charset = "utf-8" src = "layui-v2.6.5/layui/layui.js"></script>
<script src="jquery.min.js"></script>
<script>
layui.use('form', function () {
var form = layui.form;
//自定义验证规则
form.verify({
oldpsw: function (value) {
}
//数组的两个值分别代表:[正则匹配、匹配不符时的提示文字]
// \S 匹配任何非空白字符
, newpsw: [
/^[\S]{6,12}$/
, '密码必须6到12位,且不能出现空格'
]
, secpsw: function (value) {
if ($('input[name=new_pass]').val() !== value)
return '两次密码输入不一致!';
}
});
});
</script>
7.个人设置页面不必修改全部信息:写这个页面之前看了看网上都是修改全部的信息,感觉用户实用性不是很高,于是决定使表单显示用户信息,用户在此基础上进行修改,即设置表单value默认值。根据传入的用户ID查询数据库对应用户信息,查询内容赋给数组。将数组值赋给对应的input。
前项为input的name。
一开始报错“Uncaught SyntaxError: missing } ”:要注意js拼合php变量时,注意检查变量类型,是否是字符串,需要加双引号。
项目中碰到的这种错误一般是代码书写不规范,变量类型错误,导致的缺失引号,或者是成对的符号缺失,不一定是像错误里说的少了}。
//设置表单value默认值
form.val('form_filter', {
"user_name":"<?php echo $u_name?>"
, "user_sex":"<?php echo $u_sex?>"
, "user_date":"<?php echo $u_date?>"
, "user_phone":"<?php echo $u_phone?>"
, "user_intro":"<?php echo $u_intro?>"
});
8.获取<textarea>内容失败:看了一两个小时帖子,一直尝试各种各样的方法都不成功,一检查代码才发现button未放在和文本框同一个form内部。
9.POST强行变GET并且提交页面后自动返回当前页:提问页面表单提交的问题跳转到后台页面处理时POST强行变GET并且提交页面后自动返回当前页,查看了JS函数、修改了<meta>强制http变https,也排查了method前面是不是多了空格,均为发现问题。后来检查代码,form标签的位置应该如下(非删除线位置):
<form>
问题标题
<form>
文本框,按钮
</form>
</form>
10.对数据库进行操作时,失败但不提示:可以加if-else判断,失败则echo error info。增强代码健壮性。
11.判断变量是否为空:var_dump(string);
返回值:无变量返回——NULL
有变量返回——返回空值 false
12.使用AJAX后台返回结果弹窗显示:Ajax后台页面无法显示弹窗,可以在定义事件处理程序中,将后台返回的不同值(xmlhttp.responseText)赋给新变量,对新变量设置条件进行判断,然后进行alert
13.点赞功能:一个用户针对同一回答仅能点赞一次。回答表每一个回答设置一列用于存放已经赞过的用户的id,记列名Who_like。逻辑如下
stripos()当未找到时,返回值为布尔类型false,在与false值比较判断时应用===。===比较类型和值,==只比较值。
14、实现varchar类型主键(形如B001)自增:
1、查询:问题id递增查询该类别问题id的最大值,“最大”用查询条件“ limit 1”控制
2、截取:使用substring()函数截取问题id的数字部分。因为问题id形如“B001”,则从第2位开始,共3位截取三位
3、自增:截取问题id的数字部分+1
4、填充:使用LPAD()函数填充id的数字部分,L从左填充,3表示填充后长度,0表示填充内容
5、拼接:使用concat()函数,将问题类别字母和填充后id拼接,得到用户提问问题的id
总结:
- 调试过程中,除了控制台报错,还可以经常使用判断语句打印错误信息,方便发现问题。var_dump感觉比echo好用,可以返回具体原因和行数。
- 无错误但功能无法实现时,看帖子排查并不是一个最佳决定,时间可能耗费很久但毫无进展。如果有数据库,可以同时查看表的结构、字段类型等等。开发过程中如果有表结构等的修改,一定要及时同步所有表。数据库有问题也会导致运行失败。
人愚笔拙,如有高见感谢指正。