tiger tiger - 6 months ago 22
jQuery Question

removeAttr() and remove() doesn't work

I want to use

removeAttr()
and
remove()
to remove a
<div>
, but seems like it doesn't work. Since I have $('#div1').removeAttr('style').remove(); in the last line of the javascript, shouldn't that the
<div>
only appear just a moment? I am not sure if javascript is event-driven programming or top-down programming? Or depends on the code.

I want to do that because I want to delete and clear the
<div>
every time before I drag a new
<div>
, and I try to put that line of code everywhere, it doesn't work.

I am not a computer science major, please forgive my ignorance. But I don't understand why the last line doesn't execute?
If you can help, I am very appreciated. Thank you very much.

My code:



$(document).ready(function() {
var dragging = false;
var clickedX, clickedY;

// right click event
$("#displayWindow").mousedown(function(e) {
// when the mouse is pressed, the div is appended to the displayWindow
if (e.button == 2) {
// append the div start at the location that we click
$("#displayWindow").append("<div id='div1'></div>");
// get the coordinate where we clicked and set the div begin with that position
clickedX = e.pageX;
clickedY = e.pageY;
$('#div1').css({
top: clickedY,
left: clickedX
});
dragging = true;
return false;
}
});

// holding on the mouse button, change the size of the div
$("#displayWindow").on("mousemove", function(e) {
if (dragging) {
var mouseOnX = e.pageX;
var mouseOnY = e.pageY;
// allow user drag the selection box in 4 different direction
$('#div1').css({
top: Math.min(clickedY, mouseOnY),
left: Math.min(clickedX, mouseOnX),
height: Math.abs(mouseOnY - clickedY),
width: Math.abs(mouseOnX - clickedX)
});
}
}); // end on

$(document).on("mouseup", function(e) {
dragging = false;
});

// when clicked again, the menu fade out, and the div disappear
$(document).click(function(e) {
if (e.button == 0) {
// remove the selection box div
$('#div1').remove();
}
});

// prevent the default contextmenu on the display window
document.getElementById('displayWindow').oncontextmenu = function() {
return false;
};
}); // end ready

#displayWindow {
background-color: white;
border: 1px solid;
height: 600px;
width: 800px;
}
#div1 {
background-color: lightgreen;
position: absolute;
opacity: 0.3;
}

<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js"></script>
<div id="displayWindow">
<svg height="130" width="150" style="position:absolute; left:200; top:200;" class="ui-widget-content">
<text fill="black" x=75 y=75 style="text-anchor: middle">1</text>
<path d="M38 0 L113 0 L150 65 L113 130 L38 130 L0 65 Z" / fill="none" stroke="blue">
</svg>
</div>




Answer

The issue you have is not with the removal. The issues are:

  • You add an event handler to the mousemove event, every time you right click. This is not right. You need to bind the mousemove handler only once, so move that code outside of the mousemove event handler. As a consequence, also declare of clickedX and clickedY variables at the ready function level;
  • The mousemove event gives no information about buttons being pressed, so e.button will be 0 always. Instead you should keep track of whether the mouse button is pressed with a variable, and reset that variable when you detect a mouseup event on the document. This is not perfect, but probably good enough;

Some other notes:

  • The div you add has no style attribute, so it has no effect to do removeAttr('style'). However, the remove() works;
  • You can change several css styles in one css() call, by passing an object with key/value pairs.
  • There is no use in returning true from an event handler.
  • Although you mention in comments that the user can drag in all 4 directions, you have only allowed the box to move in one quadrant. You can support the 4 directions with a combination of Math.min and Math.abs calls.

Here is some adapted code:

$(document).ready(function() {
    var dragging = false;
    var clickedX, clickedY;
    // right click event
    $("#displayWindow").mousedown(function(e) {
        // when the mouse is pressed, the div is appended to the displayWindow
        if (e.button == 2) {
            $('#div1').remove(); // remove div that might still be there.
            // append the div start at the location that we click
            $("#displayWindow").append("<div id='div1'></div>");
            // get the coordinate where we clicked and set the div begin with that position
            clickedX = e.pageX;
            clickedY = e.pageY;
            $('#div1').css({top: clickedY, left: clickedX});
            dragging = true;
            return false;
        }
    });

    // holding on the mouse button, change the size of the div
    $("#displayWindow").on("mousemove", function(e) {
        if (dragging) {
            var mouseOnX = e.pageX;
            var mouseOnY = e.pageY;
            // allow user to drag the selection box in 4 different directions
            $('#div1').css({
                top: Math.min(clickedY, mouseOnY), 
                left: Math.min(clickedX, mouseOnX),
                height: Math.abs(mouseOnY - clickedY), 
                width: Math.abs(mouseOnX - clickedX)
            });
        }
    }); 

    $(document).on("mouseup", function(e) {
        dragging = false;
    });
    
    // when clicked the div disappears
    $(document).click(function(e) {
        if (e.button == 0) {
            // remove the selection box div
            $('#div1').remove();
        }
    });

    // prevent the default contextmenu on the display window
    document.getElementById('displayWindow').oncontextmenu = function() {
        return false;
    };

    $('#div1').remove();
}); // end ready
	#displayWindow {
	  background-color: white;
	  border: 1px solid;
	  height: 600px;
	  width: 800px;
	}
	#div1 {
	  background-color: lightgreen;
	  position: absolute;
	  opacity: 0.3;
	}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="displayWindow">
  <svg height="130" width="150" style="position:absolute; left:200; top:200;" class="ui-widget-content">
    <text fill="black" x=75 y=75 style="text-anchor: middle">1</text>
    <path d="M38 0 L113 0 L150 65 L113 130 L38 130 L0 65 Z" / fill="none" stroke="blue">
  </svg>
</div>