![](/img/trans.png)
[英]Javascript function works in chrome and safari but breaks in Firefox
[英]Function works in Chrome/Safari but not Firefox
因此,我有一个表,您可以在其中检查表行,它将获取该行中每个单元格的值,并显示另一个名为“ Quantity #
列。 Quantity #
列包含type="number"
输入。 输入数字后,用户将能够刷新页面,并且Quantity #
列和输入到输入中的值都将保持可见。 用户还可以点击“结帐”按钮,它将把该数据发布到电子邮件正文中。
一切在Safari和Google Chrome中都很好用。 但是,在Firefox中,如果在输入中输入一个值然后进行刷新,例如,该值将不再在输入中。 另外,如果您点击Checkout按钮并将其粘贴到电子邮件中,则不会像在Safari / Chrome中一样粘贴输入值。
为什么会这样,我该怎么做才能在Firefox中解决此问题?
JavaScript:
$(function($) {
var RowData = (function(storage, storageKey) {
var rowData = readFromSession();
var dataItems = ['loc', 'rp-code', 'sku', 'special-id', 'description', 'quantity', 'unit'];
var emailDelimiters = {
'row': '%0D%0A',
'dataItem': '\xa0\xa0'
};
function readFromSession() {
return JSON.parse(storage.getItem(storageKey) || '{}');
}
function writeToSession() {
storage.setItem(storageKey, JSON.stringify(rowData));
}
function writeRow(tr) {
var $tr = $(tr),
id = $tr.prop('id');
if($tr.find('.check').is(':checked')) {
rowData[id] = {};
for(var i=0; i<dataItems.length; i++) {
rowData[id][dataItems[i]] = $tr.find('.' + dataItems[i]).text();
}
rowData[id].quantity_num = $tr.find('.spinner').val();
} else {
delete rowData[id];
}
writeToSession();
}
function readRow(tr) {
// restore tr's checkbox and spinner value from stored data
var $tr = $(tr),
id = $tr.prop('id'),
row = rowData[id];
if(row) {
$tr.find('.check').prop('checked', true).end()
// .find('.spinner').spinner('value', row.quantity_num); // if using spinner widget
.find('.spinner').val(row.quantity_num); // if using HTML5 <input type="number">
}
}
function toEmailString() {
return $.map(rowData, function(row, id) {
return $.map(row, window.encodeURIComponent).join(emailDelimiters.dataItem);
}).join(emailDelimiters.row);
}
// selectively expose functions as methods of RowData
return {
'writeRow': writeRow,
'readRow': readRow,
'toEmailString': toEmailString
};
})(window.sessionStorage, 'checkedRowData');
$('#merchTable').on('change', '.check', function() { // on changing a table row ...
RowData.writeRow($(this).closest('tr').get(0)); // ... set the corresponding row object in RowData and sessionStorage
}).on('blur', '.spinner', function() { // on leaving a spinner widget
RowData.writeRow($(this).closest('tr').get(0));
});
$('#checkout').on('click', function() { // on clicking the [Checkout] button
var link = "mailto:me@example.com" + "?subject=" + encodeURIComponent("Order") + "&body=" + RowData.toEmailString();
console.log(link);
window.location.href = link;
});
// Call this function on completion of every pagination/search
function restoreVisibleRows() {
$('#merchTable tbody tr').get().forEach(RowData.readRow);
}
restoreVisibleRows();
});
使刷新时显示输入值和数量#列的JavaScript:
$(function(){
var showQuantityHeader = false;
$(':checkbox').each(function() {
// Iterate over the checkboxes and set their "check" values based on the session data
var $el = $(this);
//console.log('element id: ',$el.prop('id'),' sessionStorage[id]: ',sessionStorage[$el.prop('id')]);
$el.prop('checked', sessionStorage[$el.prop('id')] === 'true');
if ($el.prop('checked')) {
//show the quantity cell in the column under header with class num
$el.closest('tr').find('td.quantity_num').toggle(this.checked);
showQuantityHeader = true;
//setupSpinner(this);
var quantity = sessionStorage['value_'+$el.prop('id')];
}
});
if (showQuantityHeader) {
$('#merchTable').find('th.num').show();
//console.log('header with class num: ',$('#merchTable').find('th.num'));
}
$('input:checkbox').on('change', function() {
// save the individual checkbox in the session inside the `change` event,
// using the checkbox "id" attribute
var $el = $(this);
sessionStorage[$el.prop('id')] = $el.is(':checked');
console.log($el);
});
});
HTML:
<section id="checkout-btn">
<button id="checkout" name="order">Checkout</button>
</section>
<br>
<table id="merchTable" cellspacing="5" class="sortable">
<thead>
<tr class="ui-widget-header">
<th class="sorttable_nosort"></th>
<th class="sorttable_nosort">Loc</th>
<th class="merchRow">Report Code</th>
<th class="merchRow">SKU</th>
<th class="merchRow">Special ID</th>
<th class="merchRow">Description</th>
<th class="merchRow">Quantity</th>
<th class="sorttable_nosort">Unit</th>
<th style="display: none;" class="num">Quantity #</th>
</tr>
</thead>
<tbody>
<?php foreach ($dbh->query($query) as $row) {?>
<tr id="<?php echo intval ($row['ID'])?>">
<td class="ui-widget-content"><input type="checkbox" class="check" name="check" id="checkid-<?php echo intval ($row['ID'])?>"></td>
<td class="loc ui-widget-content" data-loc="<?php echo $row['Loc'] ?>"><input type="hidden"><?php echo $row['Loc'];?></td>
<td class="rp-code ui-widget-content" align="center" data-rp-code="<?php echo $row['Rp-Code'] ?>" id="rp-code-<?php echo intval ($row['Rp-Code'])?>"><?php echo $row['Rp-Code'];?></td>
<td class="sku ui-widget-content" data-sku="<?php echo $row['SKU'] ?>" id="sku-<?php echo intval ($row['SKU'])?>"><?php echo $row['SKU'];?></td>
<td class="special-id ui-widget-content" data-special-id="<?php echo $row['Special-ID'] ?>" align="center" id="special-id-<?php echo intval ($row['Special-ID'])?>"><?php echo $row['Special-ID'];?></td>
<td class="description ui-widget-content" data-description="<?php echo htmlspecialchars($row['Description']) ?>" id="description-<?php echo intval ($row['Description'])?>"><?php echo $row['Description'];?></td>
<td class="quantity ui-widget-content" data-quantity="<?php echo $row['Quantity'] ?>" align="center" id="quantity-<?php echo intval ($row['Quantity'])?>"><?php echo $row['Quantity'];?></td>
<td class="unit ui-widget-content" data-unit="<?php echo $row['Unit'] ?>" id="unit-<?php echo intval ($row['Unit'])?>"><?php echo $row['Unit'];?></td>
<td style="display: none;" class="quantity_num ui-widget-content"><input type="number" min="1" max="<?php echo $row['Quantity'];?>" step="1" style="width: 100px;" class="spinner" /></td>
</tr>
<?php } ?>
</tbody>
</table>
@ Rataiczak24,看来FF不会以与其他浏览器完全相同的方式触发blur
事件。
当前,存储行的状态是在response quantity_num
输入的blur
事件中完成的。 出于性能原因,我希望您不需要这样做,但是您需要响应“更改”事件而不是“模糊”事件。 输入的quantity_num
响应性可能会受到影响。
那应该解决两个报告的问题。
还有其他一些东西:
放置好我的RowData
对象后,您不应该直接与sessionStorage
交互(除非您将其用于其他目的)。 所有交互都应通过RowData API进行,并且RowData()
之外的所有代码均不应从sessionStorage
读取或写入。
如果在任何时候您都需要确信表行可能需要还原到存储在sessionStorage
的状态,请调用RowData.readRow(tr)
或调用restoreVisibleRows()
来还原所有可见行。
如果您遵循我的说明“在每次分页/搜索完成时调用此函数”,然后调用restoreVisibleRows();
在页面加载时,则无需在其他地方处理行还原。
$(function() { var showQuantityHeader = false; ...; ...; ...; });
几乎所有内容$(function() { var showQuantityHeader = false; ...; ...; ...; });
以上是不必要的。 RowData
唯一不满足的部分是$('#merchTable').find('th.num').show();
。 为此,您只需要添加几行到restoreVisibleRows()
,并且类似地响应复选框被选中/未选中。
因此,总的来说,我的代码建议的底部应该看起来像这样:
$('#merchTable').on('change', '.check', function() { // on cliking a checkbox
var $this = $(this),
$tr = $this.closest('tr');
$tr.find('td.quantity_num').toggle(this.checked);
$this.closest('table').find('th.num').toggle($('input:checkbox:checked', '#merchTable tbody').length > 0);
RowData.writeRow($tr.get(0)); // store row state
}).on('change', '.spinner', function() { // on changing the value of a "spinner" widget
RowData.writeRow($this.closest('tr').get(0)); // store row state
});
$('#checkout').on('click', function() { // on clicking the [Checkout] button
setTimeout(function() {
var link = "mailto:me@example.com" + "?subject=" + encodeURIComponent("Order") + "&body=" + RowData.toEmailString();
console.log(link);
window.location.href = link;
}, 0);
});
function restoreVisibleRows() {
$('#merchTable tbody tr').get().forEach(RowData.readRow);
if($('input:checkbox:checked', '#merchTable tbody').length > 0) {
$('#merchTable').find('th.num').show();
} else {
$('#merchTable').find('th.num').hide();
}
}
您自己的$(".check").change(function(){...})
(如果仍然存在)可以删除。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.