我一直在编写一段代码,展示如何动态调整 div 的大小。然而,代码停留在 1 个元素上,我做了一些工作以转换为多个 div 调整器。
现在在调整大小时鼠标和 div 之间出现一个空格,我的目标是确保根据父位置使用精确的鼠标位置单独调整每个元素的大小。任何会改变我的观点的方法都是适用的。不绑定(bind)到调整大小的节点,而是直接持有 div 边框也是可能的。
到目前为止我取得的成就:
- 使多个 div 可通过鼠标位置调整大小。
-在函数中保存第一个位置信息。
-计算出 child 和 parent 之间的差异。
我想实现的目标:
- 确保在调整大小时鼠标和 div 之间没有任何空间时持有者保持在鼠标位置下方。
在多次尝试调整大小后,我发现父元素边距、填充等导致出现空格。 div 开始调整大小,div 和鼠标位置之间有一个空格。
我需要一个递归的计算解决方案来正确调整和重新定位 div。
可能是另一种方法可用于仅计算父级内部的 x、y、w、h,但我需要一些关于如何使用鼠标实现该目标的解释...
function resizeable() {
var resizers = document.querySelectorAll('.n, .s, .w, .e, .nw, .ne, .se, .sw');
const min = 40;
for (let i = 0; i < resizers.length; i++) {
const currentResizer = resizers[i];
const element = currentResizer.parentElement;
const parent = currentResizer.parentElement.parentElement;
let p;
let c;
let original_w = 0;
let original_h = 0;
let parent_x = 0;
let parent_y = 0;
let child_x = 0;
let child_y = 0;
let mouse_x = 0;
let mouse_y = 0;
let scale_x = 0;
let scale_y = 0;
// Mouse events
currentResizer.addEventListener('mousedown', function(e) {
first(e);
document.addEventListener('mousemove', resize);
document.addEventListener('mouseup', stopResize);
e.preventDefault();
});
// Log
function log(e){
var str = 'original_w['+original_w+'] original_h['+original_h+'] \n'+
'parent_x['+parent_x+'] parent_y['+parent_y+'] \n'+
'child_x['+child_x+'] child_y['+child_y+'] \n'+
'scale_x['+scale_x+'] scale_y['+scale_y+'] \n'+
'mouse_x['+mouse_x+'] mouse_y['+mouse_y+'] \n'+
'e.pageX['+e.pageX+'] e.pageY['+e.pageY+'] \n'+
'obj.left['+element.style.left+'] obj.top['+element.style.top+']';
console.log(str);
/**/
str = '<table>'+
'<tr>'+
'<th colspan="2">First Locations:</td>'+
'</tr>'+
'<tr>'+
'<td>original_w['+original_w+']</td>'+
'<td>original_h['+original_h+']</td>'+
'</tr>'+
'<tr>'+
'<td>parent_x['+parent_x+']</td>'+
'<td>parent_y['+parent_y+']</td>'+
'</tr>'+
'<tr>'+
'<td>child_x['+child_x+']</td>'+
'<td>child_y['+child_y+']</td>'+
'</tr>'+
'<tr>'+
'<td>scale_x['+scale_x+']</td>'+
'<td>scale_y['+scale_y+']</td>'+
'</tr>'+
'<tr>'+
'<td>mouse_x['+mouse_x+']</td>'+
'<td>mouse_y['+mouse_y+']</td>'+
'</tr>'+
'<tr>'+
'<td>e.pageX['+e.pageX+']</td>'+
'<td>e.pageY['+e.pageY+']</td>'+
'</tr>'+
'<tr>'+
'<td>obj.left['+element.style.left+']</td>'+
'<td>obj.top['+element.style.top+']</td>'+
'</tr>'
'</table>';
var m = document.getElementById("nfo"); // Debug element
m.innerHTML = str;
}
// First location & width
function first(e) {
c = element.getBoundingClientRect();
child_y = c.top;
child_x = c.left;
p = parent.getBoundingClientRect();
parent_y = p.top;
parent_x = p.left;
original_w = parseFloat(c.width).toFixed(2);
original_h = parseFloat(c.height).toFixed(2);
scale_y = parseFloat(c.height / element.offsetHeight).toFixed(2);
scale_x = parseFloat(c.width / element.offsetWidth).toFixed(2);
mouse_y = e.pageY;
mouse_x = e.pageX;
log(e);
}
// Resize process
function resize(e) {
element.style.position = "absolute";
if (currentResizer.classList.contains('se')) {
const width = e.pageX - child_x;
const height = e.pageY - child_y;
if (width > min) {
element.style.width = (width / scale_x) + 'px';
}
if (height > min) {
element.style.height = (height / scale_y) + 'px';
}
}
else if (currentResizer.classList.contains('sw')) {
const width = original_w - (e.pageX - child_x);
const height = e.pageY - child_y;
if (height > min) {
element.style.height = (height / scale_y) + 'px';
}
if (width > min) {
element.style.left = e.pageX - parent_x + 'px';
element.style.width = (width / scale_x) + 'px';
}
}
else if (currentResizer.classList.contains('ne')) {
const width = e.pageX - child_x;
const height = original_h - (e.pageY - mouse_y);
if (width > min) {
element.style.width = (width / scale_x) + 'px';
}
if (height > min) {
element.style.height = (height / scale_y) + 'px';
element.style.top = e.pageY - parent_y + 'px';
}
}
else if (currentResizer.classList.contains('nw')) {
const width = original_w - (e.pageX - child_x);
const height = original_h - (e.pageY - mouse_y);
if (width > min) {
element.style.left = e.pageX - parent_x + 'px';
element.style.width = (width / scale_x) + 'px';
}
if (height > min) {
element.style.height = (height / scale_y) + 'px';
element.style.top = e.pageY - parent_y + 'px';
}
}
else if (currentResizer.classList.contains('e')) {
const width = e.pageX - child_x;
if (width > min) {
element.style.width = (width / scale_x) + 'px';
}
}
else if (currentResizer.classList.contains('s')) {
const height = e.pageY - child_y;
if (height > min) {
element.style.height = (height / scale_y) + 'px';
}
}
else if (currentResizer.classList.contains('w')) {
const width = original_w - (e.pageX - child_x);
if (width > min) {
element.style.width = (width / scale_x) + 'px';
element.style.left = (e.pageX - parent_x) + 'px';
}
}
else if (currentResizer.classList.contains('n')) {
const height = original_h - (e.pageY - mouse_y);
if (height > min) {
element.style.height = (height / scale_y) + 'px';
element.style.top = e.pageY - parent_y + 'px';
}
}
log(e);
}
// When mouse released stop
function stopResize(e) {
first(e);
document.removeEventListener('mousemove', resize);
}
}
}
resizeable();.another_element_on_the_way {
position: relative;
width: 100px;
height: 100px;
float: left;
}
#nfo {
position: relative;
float: left;
}
div {
position: absolute;
background-color: grey;
}
.holder {
float: left;
clear: left;
position: relative;
margin: 20px;
width: 550px;
height: 600px;
}
.scaled:hover:before, .regular:hover:before {
content: '';
position: absolute;
top: -3px;
left: -3px;
width: calc(100% - 6px);
height: calc(100% - 6px);
border: 6px solid #ccc;
}
.regular:nth-child(1){
top: 5px;
left: 5px;
width: 120px;
height: 120px;
background-color: red;
}
.regular:nth-child(3){
top: 270px;
left: 60px;
width: 240px;
height: 180px;
background-color: blue;
}
.scaled {
top: 150px;
left: 25px;
width: 160px;
height: 160px;
transform: scale(0.6) translate(0, 0);
transform-origin: top left 0px;
background-color: green;
overflow: visible;
}
.previewHeader {
position: absolute;
top: 10px;
left: 10px;
background-color: #eee;
border: 1px solid #dedede;
}
.n, .s, .w, .e, .nw, .ne, .se, .sw {
position: absolute;
width: 18px;
height: 18px;
border: 1px solid grey;
border-radius: 20px;
background-color: #fff;
}
.n:hover, .s:hover, .w:hover, .e:hover,
.nw:hover, .ne:hover, .se:hover, .sw:hover {
background-color: red;
}
.nw {
top: -10px;
left: -10px;
cursor: nw-resize;
}
.ne {
top: -10px;
left: calc(100% - 10px);
cursor: ne-resize;
}
.sw {
top: calc(100% - 10px);
left: -10px;
cursor: sw-resize;
}
.se {
top: calc(100% - 10px);
left: calc(100% - 10px);
cursor: se-resize;
}
.n {
top: -10px;
left: calc(50% - 10px);
cursor: n-resize;
}
.w {
top: calc(50% - 10px);
left: -10px;
cursor: w-resize;
}
.e {
top: calc(50% - 10px);
left: calc(100% - 10px);
cursor: e-resize;
}
.s {
top: calc(100% - 10px);
left: calc(50% - 10px);
cursor: s-resize;
}<div class="another_element_on_the_way">
</div>
<div class="another_element_on_the_way">
</div>
<div class="another_element_on_the_way">
</div>
<div class="another_element_on_the_way">
</div>
<div class="another_element_on_the_way">
</div>
<div class="another_element_on_the_way">
</div>
<div class="holder">
<div class="regular">
<div class="previewHeader">Resizable</div>
<div class="nw"></div>
<div class="ne"></div>
<div class="sw"></div>
<div class="se"></div>
<div class="n"></div>
<div class="s"></div>
<div class="w"></div>
<div class="e"></div>
</div>
<div class="scaled">
<div class="previewHeader">Scaled</div>
<div class="nw"></div>
<div class="ne"></div>
<div class="sw"></div>
<div class="se"></div>
<div class="n"></div>
<div class="s"></div>
<div class="w"></div>
<div class="e"></div>
</div>
<div class="regular">
<div class="previewHeader">Resizable</div>
<div class="nw"></div>
<div class="ne"></div>
<div class="sw"></div>
<div class="se"></div>
<div class="n"></div>
<div class="s"></div>
<div class="w"></div>
<div class="e"></div>
</div>
</div>
<div id="nfo"> X & Y</div>
还有一个代码笔可以更清楚地显示它:https://codepen.io/BerkerYuceer/pen/gOYwqdb
最佳答案
您可以使用 getComputedStyle 通过正则表达式获取 transform 值并将 1/scale 值应用于所需的坐标。我只能为 East holder 解决问题(我对坐标几何太笨了:P):
let match = getComputedStyle(element)
.transform.match(/matrix\((-?\d*\.?\d+),\s*0,\s*0,\s*(-?\d*\.?\d+),\s*0,\s*0\)/);
let scale = 1; //for .regular folks
if (match && +match[1] != 0)
scale = 1 / +match[1]; //because we need to unapply the transformation
示例:
function resizeable() {
var resizers = document.querySelectorAll('.n, .s, .w, .e, .nw, .ne, .se, .sw');
const min = 40;
for (let i = 0; i < resizers.length; i++) {
const currentResizer = resizers[i];
const element = currentResizer.parentElement;
const parent = currentResizer.parentElement.parentElement;
let p;
let c;
let original_w = 0;
let original_h = 0;
let parent_x = 0;
let parent_y = 0;
let child_x = 0;
let child_y = 0;
let mouse_x = 0;
let mouse_y = 0;
let scale_x = 0;
let scale_y = 0;
let scroll_x = 0;
let scroll_y = 0;
// Mouse events
currentResizer.addEventListener('mousedown', function(e) {
first(e);
document.addEventListener('mousemove', resize);
document.addEventListener('mouseup', stopResize);
e.preventDefault();
});
// Log
function log(e){
var str = 'original_w['+original_w+'] original_h['+original_h+'] \n'+
'parent_x['+parent_x+'] parent_y['+parent_y+'] \n'+
'scroll_x['+scroll_x+'] scroll_y['+scroll_y+'] \n'+
'child_x['+child_x+'] child_y['+child_y+'] \n'+
'scale_x['+scale_x+'] scale_y['+scale_y+'] \n'+
'mouse_x['+mouse_x+'] mouse_y['+mouse_y+'] \n'+
'e.pageX['+e.pageX+'] e.pageY['+e.pageY+'] \n'+
'obj.left['+element.style.left+'] obj.top['+element.style.top+']';
console.log(str);
/**/
str = '<table>'+
'<tr>'+
'<th colspan="2">First Locations:</td>'+
'</tr>'+
'<tr>'+
'<td>original_w['+original_w+']</td>'+
'<td>original_h['+original_h+']</td>'+
'</tr>'+
'<tr>'+
'<td>parent_x['+parent_x+']</td>'+
'<td>parent_y['+parent_y+']</td>'+
'</tr>'+
'<tr>'+
'<td>scroll_x['+scroll_x+']</td>'+
'<td>scroll_y['+scroll_y+']</td>'+
'</tr>'+
'<tr>'+
'<td>child_x['+child_x+']</td>'+
'<td>child_y['+child_y+']</td>'+
'</tr>'+
'<tr>'+
'<td>scale_x['+scale_x+']</td>'+
'<td>scale_y['+scale_y+']</td>'+
'</tr>'+
'<tr>'+
'<td>mouse_x['+mouse_x+']</td>'+
'<td>mouse_y['+mouse_y+']</td>'+
'</tr>'+
'<tr>'+
'<td>e.pageX['+e.pageX+']</td>'+
'<td>e.pageY['+e.pageY+']</td>'+
'</tr>'+
'<tr>'+
'<td>obj.left['+element.style.left+']</td>'+
'<td>obj.top['+element.style.top+']</td>'+
'</tr>'
'</table>';
var m = document.getElementById("nfo"); // Debug element
m.innerHTML = str;
}
// First location & width
function first(e) {
c = element.getBoundingClientRect();
child_y = c.top;
child_x = c.left;
p = parent.getBoundingClientRect();
parent_y = p.top;
parent_x = p.left;
scroll_y = window.scrollY;
scroll_x = window.scrollX;
original_w = parseFloat(c.width).toFixed(2);
original_h = parseFloat(c.height).toFixed(2);
scale_y = parseFloat(c.height / element.offsetHeight).toFixed(2);
scale_x = parseFloat(c.width / element.offsetWidth).toFixed(2);
mouse_y = e.pageY - scroll_y;
mouse_x = e.pageX - scroll_x;
log(e);
}
// Resize process
function resize(e) {
element.style.position = "absolute";
if (currentResizer.classList.contains('se')) {
const width = e.pageX - scroll_x - child_x ;
const height = e.pageY - scroll_y - child_y ;
if (width > min) {
element.style.width = (width / scale_x) + 'px';
}
if (height > min) {
element.style.height = (height / scale_y) + 'px';
}
}
else if (currentResizer.classList.contains('sw')) {
const width = original_w - (e.pageX - scroll_x - child_x);
const height = e.pageY - scroll_y - child_y;
if (height > min) {
element.style.height = (height / scale_y) + 'px';
}
if (width > min) {
element.style.left = e.pageX - scroll_x - parent_x + 'px';
element.style.width = (width / scale_x) + 'px';
}
}
else if (currentResizer.classList.contains('ne')) {
const width = e.pageX - child_x - scroll_x;
const height = original_h - (e.pageY - mouse_y - scroll_y);
if (width > min) {
element.style.width = (width / scale_x) + 'px';
}
if (height > min) {
element.style.height = (height / scale_y) + 'px';
element.style.top = e.pageY - parent_y - scroll_y + 'px';
}
}
else if (currentResizer.classList.contains('nw')) {
const width = original_w - (e.pageX - scroll_x - child_x);
const height = original_h - (e.pageY - scroll_y - mouse_y);
if (width > min) {
element.style.left = e.pageX - parent_x - scroll_x + 'px';
element.style.width = (width / scale_x) + 'px';
}
if (height > min) {
element.style.height = (height / scale_y) + 'px';
element.style.top = e.pageY - parent_y - scroll_y + 'px';
}
}
else if (currentResizer.classList.contains('e')) {
const width = e.pageX - scroll_x - child_x;
if (width > min) {
element.style.width = (width / scale_x) + 'px';
}
}
else if (currentResizer.classList.contains('s')) {
const height = e.pageY - scroll_y - child_y;
if (height > min) {
element.style.height = (height / scale_y) + 'px';
}
}
else if (currentResizer.classList.contains('w')) {
const width = original_w - (e.pageX - scroll_x - child_x);
if (width > min) {
element.style.width = (width / scale_x) + 'px';
element.style.left = (e.pageX - scroll_x - parent_x) + 'px';
}
}
else if (currentResizer.classList.contains('n')) {
const height = original_h - (e.pageY - scroll_y - mouse_y);
if (height > min) {
element.style.height = (height / scale_y) + 'px';
element.style.top = e.pageY - scroll_y - parent_y + 'px';
}
}
log(e);
}
// When mouse released stop
function stopResize(e) {
first(e);
document.removeEventListener('mousemove', resize);
}
}
}
resizeable();body {
width: 1200px;
}
.another_element_on_the_top {
position: relative;
float: left;
margin: 10px;
width: 100px;
height: 100px;
}
.another_element_on_the_left {
position: relative;
float: left;
clear: left;
margin: 10px;
width: 100px;
height: 100px;
}
#nfo {
position: relative;
float: left;
}
div {
position: absolute;
background-color: grey;
}
.holder {
float: left;
position: relative;
margin: -470px 20px 20px 20px;
width: 550px;
height: 600px;
}
.scaled:hover:before, .regular:hover:before {
content: '';
position: absolute;
top: -3px;
left: -3px;
width: calc(100% - 6px);
height: calc(100% - 6px);
border: 6px solid #ccc;
}
.regular:nth-child(1){
top: 5px;
left: 5px;
width: 120px;
height: 120px;
background-color: red;
}
.regular:nth-child(3){
top: 270px;
left: 60px;
width: 240px;
height: 180px;
background-color: blue;
}
.scaled {
top: 150px;
left: 25px;
width: 160px;
height: 160px;
transform: scale(0.6) translate(0, 0);
transform-origin: top left 0px;
background-color: green;
overflow: visible;
}
.previewHeader {
position: absolute;
top: 10px;
left: 10px;
background-color: #eee;
border: 1px solid #dedede;
}
.n, .s, .w, .e, .nw, .ne, .se, .sw {
position: absolute;
width: 18px;
height: 18px;
border: 1px solid grey;
border-radius: 20px;
background-color: #fff;
}
.n:hover, .s:hover, .w:hover, .e:hover,
.nw:hover, .ne:hover, .se:hover, .sw:hover {
background-color: red;
}
.nw {
top: -10px;
left: -10px;
cursor: nw-resize;
}
.ne {
top: -10px;
left: calc(100% - 10px);
cursor: ne-resize;
}
.sw {
top: calc(100% - 10px);
left: -10px;
cursor: sw-resize;
}
.se {
top: calc(100% - 10px);
left: calc(100% - 10px);
cursor: se-resize;
}
.n {
top: -10px;
left: calc(50% - 10px);
cursor: n-resize;
}
.w {
top: calc(50% - 10px);
left: -10px;
cursor: w-resize;
}
.e {
top: calc(50% - 10px);
left: calc(100% - 10px);
cursor: e-resize;
}
.s {
top: calc(100% - 10px);
left: calc(50% - 10px);
cursor: s-resize;
}<div class="another_element_on_the_top">
</div>
<div class="another_element_on_the_top">
</div>
<div class="another_element_on_the_top">
</div>
<div class="another_element_on_the_top">
</div>
<div class="another_element_on_the_top">
</div>
<div class="another_element_on_the_top">
</div>
<div class="another_element_on_the_top">
</div>
<div class="another_element_on_the_top">
</div>
<div class="another_element_on_the_top">
</div>
<div class="another_element_on_the_top">
</div>
<div class="another_element_on_the_left">
</div>
<div class="another_element_on_the_left">
</div>
<div class="another_element_on_the_left">
</div>
<div class="another_element_on_the_left">
</div>
<div class="another_element_on_the_left">
</div>
<div class="holder">
<div class="regular">
<div class="previewHeader">Resizable</div>
<div class="nw"></div>
<div class="ne"></div>
<div class="sw"></div>
<div class="se"></div>
<div class="n"></div>
<div class="s"></div>
<div class="w"></div>
<div class="e"></div>
</div>
<div class="scaled">
<div class="previewHeader">Scaled</div>
<div class="nw"></div>
<div class="ne"></div>
<div class="sw"></div>
<div class="se"></div>
<div class="n"></div>
<div class="s"></div>
<div class="w"></div>
<div class="e"></div>
</div>
<div class="regular">
<div class="previewHeader">Resizable</div>
<div class="nw"></div>
<div class="ne"></div>
<div class="sw"></div>
<div class="se"></div>
<div class="n"></div>
<div class="s"></div>
<div class="w"></div>
<div class="e"></div>
</div>
</div>
<div id="nfo"> X & Y</div>
或使用 this另一个问题中的方法。
var element = document.querySelector('...');
var scaleX = element.getBoundingClientRect().width / element.offsetWidth;
"This works because getBoundingClientRect returns the actual dimension while offsetWidth/Height is the unscaled size."
编辑 window.scrollX/Y 添加。现在它可以在滚动页面中使用。
为了将来在页面的任何部分进行引用,它都可以正常工作。即使对象被缩放。
关于javascript - 如何根据js中的父位置动态调整div的大小,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57621679/
我正在学习如何使用Nokogiri,根据这段代码我遇到了一些问题:require'rubygems'require'mechanize'post_agent=WWW::Mechanize.newpost_page=post_agent.get('http://www.vbulletin.org/forum/showthread.php?t=230708')puts"\nabsolutepathwithtbodygivesnil"putspost_page.parser.xpath('/html/body/div/div/div/div/div/table/tbody/tr/td/div
总的来说,我对ruby还比较陌生,我正在为我正在创建的对象编写一些rspec测试用例。许多测试用例都非常基础,我只是想确保正确填充和返回值。我想知道是否有办法使用循环结构来执行此操作。不必为我要测试的每个方法都设置一个assertEquals。例如:describeitem,"TestingtheItem"doit"willhaveanullvaluetostart"doitem=Item.new#HereIcoulddotheitem.name.shouldbe_nil#thenIcoulddoitem.category.shouldbe_nilendend但我想要一些方法来使用
我试图在一个项目中使用rake,如果我把所有东西都放到Rakefile中,它会很大并且很难读取/找到东西,所以我试着将每个命名空间放在lib/rake中它自己的文件中,我添加了这个到我的rake文件的顶部:Dir['#{File.dirname(__FILE__)}/lib/rake/*.rake'].map{|f|requiref}它加载文件没问题,但没有任务。我现在只有一个.rake文件作为测试,名为“servers.rake”,它看起来像这样:namespace:serverdotask:testdoputs"test"endend所以当我运行rakeserver:testid时
我的目标是转换表单输入,例如“100兆字节”或“1GB”,并将其转换为我可以存储在数据库中的文件大小(以千字节为单位)。目前,我有这个:defquota_convert@regex=/([0-9]+)(.*)s/@sizes=%w{kilobytemegabytegigabyte}m=self.quota.match(@regex)if@sizes.include?m[2]eval("self.quota=#{m[1]}.#{m[2]}")endend这有效,但前提是输入是倍数(“gigabytes”,而不是“gigabyte”)并且由于使用了eval看起来疯狂不安全。所以,功能正常,
作为我的Rails应用程序的一部分,我编写了一个小导入程序,它从我们的LDAP系统中吸取数据并将其塞入一个用户表中。不幸的是,与LDAP相关的代码在遍历我们的32K用户时泄漏了大量内存,我一直无法弄清楚如何解决这个问题。这个问题似乎在某种程度上与LDAP库有关,因为当我删除对LDAP内容的调用时,内存使用情况会很好地稳定下来。此外,不断增加的对象是Net::BER::BerIdentifiedString和Net::BER::BerIdentifiedArray,它们都是LDAP库的一部分。当我运行导入时,内存使用量最终达到超过1GB的峰值。如果问题存在,我需要找到一些方法来更正我的代
关闭。这个问题是opinion-based.它目前不接受答案。想要改进这个问题?更新问题,以便editingthispost可以用事实和引用来回答它.关闭4年前。Improvethisquestion我想在固定时间创建一系列低音和高音调的哔哔声。例如:在150毫秒时发出高音调的蜂鸣声在151毫秒时发出低音调的蜂鸣声200毫秒时发出低音调的蜂鸣声250毫秒的高音调蜂鸣声有没有办法在Ruby或Python中做到这一点?我真的不在乎输出编码是什么(.wav、.mp3、.ogg等等),但我确实想创建一个输出文件。
Rails2.3可以选择随时使用RouteSet#add_configuration_file添加更多路由。是否可以在Rails3项目中做同样的事情? 最佳答案 在config/application.rb中:config.paths.config.routes在Rails3.2(也可能是Rails3.1)中,使用:config.paths["config/routes"] 关于ruby-on-rails-Rails3中的多个路由文件,我们在StackOverflow上找到一个类似的问题
给定这段代码defcreate@upgrades=User.update_all(["role=?","upgraded"],:id=>params[:upgrade])redirect_toadmin_upgrades_path,:notice=>"Successfullyupgradeduser."end我如何在该操作中实际验证它们是否已保存或未重定向到适当的页面和消息? 最佳答案 在Rails3中,update_all不返回任何有意义的信息,除了已更新的记录数(这可能取决于您的DBMS是否返回该信息)。http://ar.ru
我在我的项目目录中完成了compasscreate.和compassinitrails。几个问题:我已将我的.sass文件放在public/stylesheets中。这是放置它们的正确位置吗?当我运行compasswatch时,它不会自动编译这些.sass文件。我必须手动指定文件:compasswatchpublic/stylesheets/myfile.sass等。如何让它自动运行?文件ie.css、print.css和screen.css已放在stylesheets/compiled。如何在编译后不让它们重新出现的情况下删除它们?我自己编译的.sass文件编译成compiled/t
我正在寻找执行以下操作的正确语法(在Perl、Shell或Ruby中):#variabletoaccessthedatalinesappendedasafileEND_OF_SCRIPT_MARKERrawdatastartshereanditcontinues. 最佳答案 Perl用__DATA__做这个:#!/usr/bin/perlusestrict;usewarnings;while(){print;}__DATA__Texttoprintgoeshere 关于ruby-如何将脚