Slider control constructor
Really your question boils down to whether or not there is a better way to set a custom function. That's hard to say because your approach will work fine. Really any kind of answer your going to get is largely subjective.

For me I tend to avoid the prototype method for objects unless I'm overriding or extending some other function or object. You started on the right track with your declaration of the SliderControl object; you can incorporate your prototype into that method declaration as well to greatly simplify and encapsulate your code.

It could use some cleanup I'm sure but here's my quick take.

&lt;!DOCTYPE&gt;
&lt;html&gt;
&lt;head&gt;
  &lt;title&gt;Slider&lt;/title&gt;
  &lt;meta charset="utf-8" /&gt;
  &lt;style type="text/css" media="screen, print"&gt;
    #container {
      width: 400px;
      background: white;
      padding: 30px;
    }

    .area {
      width: 100%;
      height: 10px;
      padding-top: 10px;
      cursor: pointer;
    }

    .rail {
      width: 100%;
      height: 2px;
      background: lightgray;
    }

    .element {
      height: 2px;
      background: black;
      width: 40%;
    }

    .knob {
      width: 10px;
      height: 10px;
      background: black;
      float: right;
      border-radius: 50px;
      margin-top: -4px;
    }
  &lt;/style&gt;
  &lt;script&gt;
    var SliderControl = function (container, action, actionWhenActive, actionWhenSet) {
        var self = this;
        this.action = action;
        this.container = container;
          var area = document.createElement("div");
          this.container.appendChild(area);
          area.className = "area";
            var railDiv = document.createElement("div");
            area.appendChild(railDiv);
            railDiv.className = "rail";
              this.fill = document.createElement('div');
              railDiv.appendChild(this.fill);
              this.fill.className = "element";
              this.fill.innerHTML = "&lt;div class='knob'&gt;&lt;/div&gt;";
        this.element = area;
        this.value = 0;
        this.active = false;
        this.actionWhenActive = actionWhenActive;
        this.actionWhenSet = actionWhenSet;

        this.noEvent = false;
        this.clearNoEvent = function(){
          self.noEvent = false;
        }; 

        document.addEventListener("mousemove", function (event) {
            if(self.noEvent){
                return;
            }
            self.noEvent = true;
            setTimeout(self.clearNoEvent,10);  //debounce so the handler isn't called excessively
            self.move(event);
        },false);

        document.addEventListener("mouseup", function (event) {
            self.drop(event, self);
        },false);

        this.element.addEventListener("mousedown", function (event) {
            self.grab(event, self);
        },false);

        this.width = function(){
            var calcWidth = ((this.value * 100) + '%');
            this.fill.style.width = calcWidth;
        };

        this.update = function(event){
            if (this.actionWhenActive === true) {
                self.action(this.value);
            }
            var direction, percent, container, area;
            direction = event.pageX - this.element.offsetLeft;
            percent = Math.min(Math.max(direction / this.element.offsetWidth, 0), 1.0);
            this.value = percent;
            self.width();
        };

        this.move = function(event){
            if (this.active === true) {
                self.update(event);
            }
        };

        this.grab = function(event){
            event.preventDefault();
            this.active = true;
            self.update(event);
        };

        this.drop = function(event){
            if (this.active === true) {
                this.active = false;
                self.action(this.value);
            }
        };

        this.setValue = function(value){
            if (this.active !== false) {
                return;
            }
            this.value = value;
            self.width();
            if (this.actionWhenSet === true) {
                self.action(value);
            }
        };
    };

    window.onload = function(){
        var sContainer = document.getElementById('container');
        var sValue = document.getElementById('value');

        // create the slider control
        var mySlider = new SliderControl(sContainer, function setValue(value) {
            sValue.innerHTML = value;
          }, true);
    };
  &lt;/script&gt;
&lt;/head&gt;
&lt;body&gt;
  &lt;div id='container'&gt;&lt;/div&gt;
  &lt;div&gt;The value is &lt;span id='value'&gt;0.4&lt;/span&gt;&lt;/div&gt;
&lt;/body&gt;
&lt;/html&gt;


Now above and beyond your initial question...

To make your slider more portable (and practical) you should also create the dom structure in the object so that all you have to pass in during initialization is the element you'd like to put it in.

You'll also want to add the ability to set a default value, in case you're loading and editing preset data.

I would also suggest removing 'actionWhenActive' and 'actionWhenSet' and replacing them with your existing 'action' and a new 'actionSet' function. You can check if one or the other is null or undefined to give you the same effect as the booleans. This will also give your slider the ability to perform both operations (ie displaying a value, and then saving it when done).